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
613namespace listHelper {
14+
15+ // Linked list node definition
716struct 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
2132inline 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
3345inline 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
4555inline 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
5364inline 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
6274namespace treeHelper {
75+
76+ // Binary tree node definition
6377struct 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)
8198inline 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
109128inline 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
133153inline 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
149170namespace compareHelper {
171+
172+ // Compare two containers ignoring element order
173+ // Supports nested containers (e.g., vector<vector<int>>)
150174template <typename V>
151175bool 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