Skip to content

Commit 8eb1baa

Browse files
author
kwu130
committed
refactor(common): restructure helper utilities
1 parent f208e1e commit 8eb1baa

1 file changed

Lines changed: 52 additions & 23 deletions

File tree

‎include/common.h‎

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,84 @@
11
#ifndef LEETCODE_COMMON_H
22
#define LEETCODE_COMMON_H
33

4+
#include <algorithm>
5+
#include <iostream>
6+
#include <queue>
47
#include <ranges>
8+
#include <vector>
9+
10+
// Helper utilities for LeetCode problem solving
11+
// Provides common data structures and operations for linked lists, trees, and comparisons
512

613
namespace listHelper {
14+
15+
// Linked list node definition
716
struct ListNode {
817
int val;
918
ListNode* next;
19+
1020
ListNode()
1121
: val(0),
1222
next(nullptr) {}
1323
explicit ListNode(int x)
1424
: val(x),
1525
next(nullptr) {}
16-
ListNode(const int x, ListNode* next)
26+
ListNode(int x, ListNode* next)
1727
: val(x),
1828
next(next) {}
1929
};
2030

31+
// Build a linked list from a vector
2132
inline ListNode* build(const std::vector<int>& vec) {
2233
if (vec.empty()) return nullptr;
34+
2335
auto* head = new ListNode(vec[0]);
2436
ListNode* cur = head;
25-
for (size_t i = 1; i < vec.size(); i++) {
37+
for (size_t i = 1; i < vec.size(); ++i) {
2638
cur->next = new ListNode(vec[i]);
2739
cur = cur->next;
2840
}
29-
3041
return head;
3142
}
3243

44+
// Compare two linked lists for equality
3345
inline bool equal(const ListNode* lhs, const ListNode* rhs) {
34-
while (lhs != nullptr && rhs != nullptr) {
35-
if (lhs->val != rhs->val) {
36-
return false;
37-
}
46+
while (lhs && rhs) {
47+
if (lhs->val != rhs->val) return false;
3848
lhs = lhs->next;
3949
rhs = rhs->next;
4050
}
41-
4251
return lhs == nullptr && rhs == nullptr;
4352
}
4453

54+
// Print linked list in format: val -> val -> nullptr
4555
inline void print(const ListNode* head) {
46-
while (head != nullptr) {
56+
while (head) {
4757
std::cout << head->val << " -> ";
4858
head = head->next;
4959
}
5060
std::cout << "nullptr" << std::endl;
5161
}
5262

63+
// Free all nodes in the linked list
5364
inline void free(ListNode* head) {
54-
while (head != nullptr) {
65+
while (head) {
5566
ListNode* tmp = head;
5667
head = head->next;
5768
delete tmp;
5869
}
5970
}
71+
6072
} // namespace listHelper
6173

6274
namespace treeHelper {
75+
76+
// Binary tree node definition
6377
struct TreeNode {
6478
int val;
6579
TreeNode* left;
6680
TreeNode* right;
81+
6782
TreeNode()
6883
: val(0),
6984
left(nullptr),
@@ -72,12 +87,14 @@ struct TreeNode {
7287
: val(x),
7388
left(nullptr),
7489
right(nullptr) {}
75-
TreeNode(const int x, TreeNode* left, TreeNode* right)
90+
TreeNode(int x, TreeNode* left, TreeNode* right)
7691
: val(x),
7792
left(left),
7893
right(right) {}
7994
};
8095

96+
// Build a binary tree from level-order traversal vector
97+
// nullptr_val represents null nodes (default: -1)
8198
inline TreeNode* build(const std::vector<int>& vec, int nullptr_val = -1) {
8299
if (vec.empty() || vec[0] == nullptr_val) return nullptr;
83100

@@ -90,24 +107,26 @@ inline TreeNode* build(const std::vector<int>& vec, int nullptr_val = -1) {
90107
TreeNode* cur = q.front();
91108
q.pop();
92109

110+
// Process left child
93111
if (i < vec.size() && vec[i] != nullptr_val) {
94112
cur->left = new TreeNode(vec[i]);
95113
q.push(cur->left);
96114
}
97-
i++;
115+
++i;
98116

117+
// Process right child
99118
if (i < vec.size() && vec[i] != nullptr_val) {
100119
cur->right = new TreeNode(vec[i]);
101120
q.push(cur->right);
102121
}
103-
i++;
122+
++i;
104123
}
105124
return root;
106125
}
107126

108-
// level order
127+
// Print tree in level-order traversal
109128
inline void print(const TreeNode* root) {
110-
if (root == nullptr) {
129+
if (!root) {
111130
std::cout << "null" << std::endl;
112131
return;
113132
}
@@ -119,7 +138,7 @@ inline void print(const TreeNode* root) {
119138
const TreeNode* cur = q.front();
120139
q.pop();
121140

122-
if (cur == nullptr) {
141+
if (!cur) {
123142
std::cout << "null ";
124143
} else {
125144
std::cout << cur->val << " ";
@@ -130,44 +149,54 @@ inline void print(const TreeNode* root) {
130149
std::cout << std::endl;
131150
}
132151

152+
// Recursively compare two trees for equality
133153
inline bool equal(const TreeNode* a, const TreeNode* b) {
134-
if (a == nullptr && b == nullptr) return true;
135-
if (a == nullptr || b == nullptr) return false;
154+
if (!a && !b) return true;
155+
if (!a || !b) return false;
136156
if (a->val != b->val) return false;
137-
138157
return equal(a->left, b->left) && equal(a->right, b->right);
139158
}
140159

141-
inline void free(const TreeNode* root) {
142-
if (root == nullptr) return;
160+
// Recursively free all nodes in the tree
161+
inline void free(TreeNode* root) {
162+
if (!root) return;
143163
free(root->left);
144164
free(root->right);
145165
delete root;
146166
}
167+
147168
} // namespace treeHelper
148169

149170
namespace compareHelper {
171+
172+
// Compare two containers ignoring element order
173+
// Supports nested containers (e.g., vector<vector<int>>)
150174
template <typename V>
151175
bool equalIgnoreOrder(const V& a, const V& b) {
152176
if (a.size() != b.size()) return false;
153177

178+
// Create copies to avoid modifying originals
154179
V aa = a;
155180
V bb = b;
156181

157182
using Elem = typename V::value_type;
158183

184+
// If elements are themselves sortable containers, sort them first
159185
if constexpr (requires(Elem e) {
160-
e.begin();
161-
e.end();
186+
{ e.begin() } -> std::input_or_output_iterator;
187+
{ e.end() } -> std::input_or_output_iterator;
162188
}) {
163189
for (auto& v : aa) std::ranges::sort(v);
164190
for (auto& v : bb) std::ranges::sort(v);
165191
}
166192

193+
// Sort outer containers
167194
std::ranges::sort(aa);
168195
std::ranges::sort(bb);
169196

170197
return aa == bb;
171198
}
199+
172200
} // namespace compareHelper
201+
173202
#endif // LEETCODE_COMMON_H

0 commit comments

Comments
 (0)