From 15d6c5fcbb0c25cf74b8868f078e4301a39e458f Mon Sep 17 00:00:00 2001 From: begeekmyfriend Date: Wed, 7 May 2025 07:30:58 +0800 Subject: [PATCH 1/5] Improvement Signed-off-by: begeekmyfriend --- 0039_combination_sum/combination_sum.cc | 2 +- 0045_jump_game_ii/jump_game.c | 8 ++++---- 0045_jump_game_ii/jump_game.cc | 14 +++++++------- 0069_sqrt/sqrt.c | 3 +++ 0069_sqrt/sqrt.cc | 3 +++ .../window_substring.cc | 15 ++++++++++----- 0137_single_number_ii/single_number.c | 1 + 0190_reverse_bits/reverse_bits.c | 19 +++++++++++-------- 8 files changed, 40 insertions(+), 25 deletions(-) diff --git a/0039_combination_sum/combination_sum.cc b/0039_combination_sum/combination_sum.cc index a45abf8..a95ab08 100644 --- a/0039_combination_sum/combination_sum.cc +++ b/0039_combination_sum/combination_sum.cc @@ -20,7 +20,7 @@ class Solution { } else { for (int i = start; i < candidates.size(); i++) { stack.push_back(candidates[i]); - /* The elements in solution can be duplicate for the purpose of the problem */ + /* The elements in solution can be taken as many times as you can for the purpose of the problem */ dfs(candidates, i, target - candidates[i], res); stack.pop_back(); } diff --git a/0045_jump_game_ii/jump_game.c b/0045_jump_game_ii/jump_game.c index 9de0eda..0d9ffb2 100644 --- a/0045_jump_game_ii/jump_game.c +++ b/0045_jump_game_ii/jump_game.c @@ -12,10 +12,10 @@ static int jump(int* nums, int numsSize) int i, right = 0; int steps = 0; int fartest = 0; - /* 1. Exhaust all the right boundries in the location range of [i...right] - * 2. When the search ends up with i==right, update the right boundry as - * the fartest position. - * 3. When the search ends up with i==right, it records as one jump step */ + /* 1. Exhaust all the right boundries in the location range of [i...farthest] + * 2. When i reaches the farthest boundary, update the farthest boundry + * and the step number. + * 3. Apply condition i < size - 1 and iterator i++ to avoid overflow. */ for (i = 0; i < numsSize; i++) { fartest = max(i + nums[i], fartest); if (i == right) { diff --git a/0045_jump_game_ii/jump_game.cc b/0045_jump_game_ii/jump_game.cc index e561405..cf61281 100644 --- a/0045_jump_game_ii/jump_game.cc +++ b/0045_jump_game_ii/jump_game.cc @@ -8,14 +8,14 @@ class Solution { int steps = 0; int right = 0; int farthest = 0; - // 1. Exhaust all the right boundries in the location range of [i...right] - // 2. When the search ends up with i==right, update the right boundry as - // the fartest position. - // 3. When the search ends up with i==right, it records as one jump step */ + // 1. Exhaust all the right boundries in the location range of [i...farthest] + // 2. When i reaches the farthest boundary, update the farthest boundry + // and the step number. + // 3. Apply condition i < size - 1 and iterator i++ to avoid overflow. for (int i = 0; i < nums.size() - 1; i++) { - fartest = max(i + nums[i], fartest); - for (i == right) { - right = fartest; + right = max(i + nums[i], right); + if (i == farthest) { + farthest = right; steps++; } } diff --git a/0069_sqrt/sqrt.c b/0069_sqrt/sqrt.c index e4fdcd0..70a8411 100644 --- a/0069_sqrt/sqrt.c +++ b/0069_sqrt/sqrt.c @@ -60,6 +60,9 @@ int mySqrt(int x) unsigned int lo = 1; unsigned int hi = (unsigned int) x; unsigned int mid = lo + (hi - lo) / 2; + // Firstly test mid > x / mid to decide whether hi = mid; + // else then test mid + 1 > x / (mid + 1) to decide whether the mid is located; + // Otherwise assign low = mid. for (; ;) { if (mid > x/mid) { hi = mid; diff --git a/0069_sqrt/sqrt.cc b/0069_sqrt/sqrt.cc index 8e47bf6..40445ce 100644 --- a/0069_sqrt/sqrt.cc +++ b/0069_sqrt/sqrt.cc @@ -11,6 +11,9 @@ class Solution { unsigned int lo = 1, hi = x; unsigned int mid = (lo + hi) / 2; + // Firstly test mid > x / mid to decide whether hi = mid; + // else then test mid + 1 > x / (mid + 1) to decide whether the mid is located; + // Otherwise assign low = mid. for (; ;) { if (mid > x / mid) { hi = mid; diff --git a/0076_minimum_window_substring/window_substring.cc b/0076_minimum_window_substring/window_substring.cc index d419221..8fd41bd 100644 --- a/0076_minimum_window_substring/window_substring.cc +++ b/0076_minimum_window_substring/window_substring.cc @@ -11,20 +11,25 @@ class Solution { } int l = 0, r = 0; - int need_to_meet = t.length(); - int start, min_len = INT_MAX; + int hit_num = 0; + int start = 0, min_len = INT_MAX; while (r < s.length()) { + // counting each letter in the string. The zero and positive + // countings indicate ones in pattern. And the negative ones + // indicate those out of the pattern. if (--count[s[r++]] >= 0) { - need_to_meet--; + hit_num++; } - while (need_to_meet == 0) { + while (hit_num == t.length()) { if (r - l < min_len) { start = l; min_len = r - l; } + // The countings of the letter larger than zero shall be + // the ones in the pattern. if (++count[s[l++]] > 0) { - need_to_meet++; + hit_num--; } } } diff --git a/0137_single_number_ii/single_number.c b/0137_single_number_ii/single_number.c index bf5beae..b02f66f 100644 --- a/0137_single_number_ii/single_number.c +++ b/0137_single_number_ii/single_number.c @@ -39,6 +39,7 @@ static int singleNumber(int *nums, int numsSize) count[i]++; } } + /* The specified bit counting should be multiple of 3 without the outlier */ mask |= (count[i] % 3) << i; } return mask; diff --git a/0190_reverse_bits/reverse_bits.c b/0190_reverse_bits/reverse_bits.c index 5fcf123..8ba7cff 100644 --- a/0190_reverse_bits/reverse_bits.c +++ b/0190_reverse_bits/reverse_bits.c @@ -4,14 +4,17 @@ static uint32_t reverseBits(uint32_t n) { - int i; - uint32_t res = 0; - for (i = 0; i < 32; i++) { - res <<= 1; - res |= n & 0x1; - n >>= 1; - } - return res; + const uint32_t MASK1 = 0x55555555; + const uint32_t MASK2 = 0x33333333; + const uint32_t MASK4 = 0x0f0f0f0f; + const uint32_t MASK8 = 0x00ff00ff; + + // Extract and swap the even and odd bit groups. + n = (n & MASK1) << 1 | ((n >> 1) & MASK1); + n = (n & MASK2) << 2 | ((n >> 2) & MASK2); + n = (n & MASK4) << 4 | ((n >> 4) & MASK4); + n = (n & MASK8) << 8 | ((n >> 8) & MASK8); + return n << 16 | n >> 16; } int main(int argc, char **argv) From 0e4fa45e8e34511d8a9b8c4dea503d2cbe6f4e88 Mon Sep 17 00:00:00 2001 From: begeekmyfriend Date: Tue, 13 May 2025 09:13:12 +0800 Subject: [PATCH 2/5] Improvement Signed-off-by: begeekmyfriend --- 0031_next_permutation/next_permutation.c | 8 ++++---- 0031_next_permutation/next_permutation.cc | 5 +++++ 0912_sort_an_array/sort.c | 12 ++++++++---- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/0031_next_permutation/next_permutation.c b/0031_next_permutation/next_permutation.c index 49ddbe5..8cd3024 100644 --- a/0031_next_permutation/next_permutation.c +++ b/0031_next_permutation/next_permutation.c @@ -21,15 +21,13 @@ static void reverse(int *a, int size) static void nextPermutation(int* nums, int numsSize) { - if (numsSize <= 1) { - return; - } - + // find the first smaller element in decreasing sequence from back to forth. int i = numsSize - 2; while (i >= 0 && nums[i] >= nums[i + 1]) { i--; } + // if found, find the first bigger element from back to forth and swap them. if (i >= 0) { int j = numsSize - 1; while (j >= 0 && nums[j] <= nums[i]) { @@ -37,6 +35,8 @@ static void nextPermutation(int* nums, int numsSize) } swap(nums + i, nums + j); } + + // reverse the subsequence into increasing one. reverse(nums + i + 1, numsSize - i - 1); } diff --git a/0031_next_permutation/next_permutation.cc b/0031_next_permutation/next_permutation.cc index 5b8256c..f12077d 100644 --- a/0031_next_permutation/next_permutation.cc +++ b/0031_next_permutation/next_permutation.cc @@ -5,11 +5,15 @@ using namespace std; class Solution { public: void nextPermutation(vector& nums) { + // find the first smaller element in decreasing sequence from back to + // forth. int i = nums.size() - 2; while (i >= 0 && nums[i] >= nums[i + 1]) { i--; } + // if found, find the first bigger element from back to forth and swap + // them. if (i >= 0) { int j = nums.size() - 1; while (j >= 0 && nums[i] >= nums[j]) { @@ -18,6 +22,7 @@ class Solution { swap(nums[i], nums[j]); } + // reverse the subsequence into increasing one. reverse(nums.begin() + i + 1, nums.end()); } }; diff --git a/0912_sort_an_array/sort.c b/0912_sort_an_array/sort.c index 107783a..304ffaf 100644 --- a/0912_sort_an_array/sort.c +++ b/0912_sort_an_array/sort.c @@ -26,7 +26,7 @@ static void quick_sort(int *nums, int lo, int hi) return; } - /* shuffle the pivot */ + /* shuffle the pivot as it is a must for performance */ mid = lo + (hi - lo) / 2; swap(&nums[mid], &nums[hi]); @@ -38,11 +38,15 @@ static void quick_sort(int *nums, int lo, int hi) * shall make the partition in the middle of the array as far as * possible. If the partition is located in the head or tail, the * performance might well be very bad for it. + * + * Note: Do NOT use nums[++i] <= pivot or nums[--j] >= pivot as the + * loop condition because it leads to redundant operations in each + * recusive iteration when there are many duplicate elements. */ - while (i < hi && nums[++i] < pivot) {} - while (j > lo && nums[--j] > pivot) {} + while (i < j && nums[++i] < pivot) {} + while (i < j && nums[--j] > pivot) {} if (i < j) { - swap(&nums[i], &nums[j]); + swap(&nums[i], &nums[j]); } } From 02b17696de11195db74e6c1fde809185b58e8240 Mon Sep 17 00:00:00 2001 From: begeekmyfriend Date: Tue, 13 May 2025 09:33:18 +0800 Subject: [PATCH 3/5] Improvement Signed-off-by: begeekmyfriend --- 0215_kth_largest_element_in_an_array/kth_elem.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/0215_kth_largest_element_in_an_array/kth_elem.c b/0215_kth_largest_element_in_an_array/kth_elem.c index b14d278..dd049b5 100644 --- a/0215_kth_largest_element_in_an_array/kth_elem.c +++ b/0215_kth_largest_element_in_an_array/kth_elem.c @@ -62,6 +62,10 @@ static void quick_select(int *nums, int lo, int hi, int k) * shall make the partition in the middle of the array as far as * possible. If the partition is located in the head or tail, the * performance might well be very bad for it. + * + * Note: Do NOT use nums[++i] <= pivot or nums[--j] >= pivot as the + * loop condition because it leads to redundant operations in each + * recusive iteration when there are many duplicate elements. */ while (i < hi && nums[++i] > pivot) {} while (j > lo && nums[--j] < pivot) {} @@ -72,7 +76,8 @@ static void quick_select(int *nums, int lo, int hi, int k) /* invariant: i == j + 1 or i == j */ swap(&nums[i], &nums[hi]); - if (i + 1 >= k) { + /* compare index [i] with [k - 1] to locate the kth element */ + if (i > k - 1) { quick_select(nums, lo, i - 1, k); } else { quick_select(nums, i + 1, hi, k); From 999ff027352c37a14de2c07c4158ccd6b31a926b Mon Sep 17 00:00:00 2001 From: begeekmyfriend Date: Tue, 10 Jun 2025 22:52:57 +0800 Subject: [PATCH 4/5] Add new case Signed-off-by: begeekmyfriend --- 0518_coin_change_ii/Makefile | 2 ++ 0518_coin_change_ii/coin_change.c | 44 ++++++++++++++++++++++++++++++ 0518_coin_change_ii/coin_change.cc | 24 ++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 0518_coin_change_ii/Makefile create mode 100644 0518_coin_change_ii/coin_change.c create mode 100644 0518_coin_change_ii/coin_change.cc diff --git a/0518_coin_change_ii/Makefile b/0518_coin_change_ii/Makefile new file mode 100644 index 0000000..a766ed4 --- /dev/null +++ b/0518_coin_change_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test coin_change.c diff --git a/0518_coin_change_ii/coin_change.c b/0518_coin_change_ii/coin_change.c new file mode 100644 index 0000000..d119fcb --- /dev/null +++ b/0518_coin_change_ii/coin_change.c @@ -0,0 +1,44 @@ +#include +#include + + +int change(int amount, int* coins, int coinsSize) +{ + int i, j; + unsigned int **dp = malloc((coinsSize + 1) * sizeof(unsigned int *)); + + for (i = 0; i <= coinsSize; i++) { + dp[i] = calloc(amount + 1, sizeof(unsigned int)); + dp[i][0] = 1; + } + + for (i = 1; i <= coinsSize; i++) { + for (j = 1; j <= amount; j++) { + if (j - coins[i - 1] >= 0) { + dp[i][j] = dp[i - 1][j] + dp[i][j - coins[i - 1]]; + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + + return dp[coinsSize][amount]; +} + +int main(int argc, char **argv) +{ + if (argc < 3) { + fprintf(stderr, "Usage: ./test 11 1 2 5"); + exit(-1); + } + + int amount = atoi(argv[1]); + int i, size = argc - 2; + int *coins = malloc(size * sizeof(int)); + for (i = 0; i < size; i++) { + coins[i] = atoi(argv[i + 2]); + } + printf("%d\n", change(amount, coins, size)); + + return 0; +} diff --git a/0518_coin_change_ii/coin_change.cc b/0518_coin_change_ii/coin_change.cc new file mode 100644 index 0000000..5282ef3 --- /dev/null +++ b/0518_coin_change_ii/coin_change.cc @@ -0,0 +1,24 @@ +#include + +using namespace std; + +class Solution { +public: + int change(int amount, vector& coins) { + vector> dp(coins.size() + 1, vector(amount + 1)); + for (int i = 0; i <= coins.size(); i++) { + dp[i][0] = 1; + } + + for (int i = 1; i <= coins.size(); i++) { + for (int j = 1; j <= amount; j++) { + if (j >= coins[i - 1]) { + dp[i][j] = dp[i - 1][j] + dp[i][j - coins[i - 1]]; + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + return dp[coins.size()][amount]; + } +}; From fe106a08189e425e13ba25496997f5153084b182 Mon Sep 17 00:00:00 2001 From: begeekmyfriend Date: Fri, 11 Jul 2025 10:41:34 +0800 Subject: [PATCH 5/5] Improvement Signed-off-by: begeekmyfriend --- 0043_multiply_strings/multiply_strings.cc | 22 ++++--- .../palindrome_partition.cc | 42 ++++++++++++ 0133_clone_graph/clone_graph.cc | 65 +++++++++++++++++++ .../permutation_in_string.cc | 10 +-- 4 files changed, 127 insertions(+), 12 deletions(-) create mode 100644 0131_palindrome_patitioning/palindrome_partition.cc create mode 100644 0133_clone_graph/clone_graph.cc diff --git a/0043_multiply_strings/multiply_strings.cc b/0043_multiply_strings/multiply_strings.cc index 77436e4..0ca6c59 100644 --- a/0043_multiply_strings/multiply_strings.cc +++ b/0043_multiply_strings/multiply_strings.cc @@ -5,23 +5,29 @@ using namespace std; class Solution { public: string multiply(string num1, string num2) { - string res(num1.length() + num2.length(), '0'); + vector v(num1.length() + num2.length()); for (int i = num2.length() - 1; i >= 0; i--) { - int j, carry = 0; - for (j = num1.length() - 1; j >= 0; j--) { - carry += (num1[j] - '0') * (num2[i] - '0') + (res[i + j + 1] - '0'); - res[i + j + 1] = carry % 10 + '0'; - carry /= 10; + for (int j = num1.length() - 1; j >= 0; j--) { + int a = num2[j] - '0'; + int b = num1[i] - '0'; + v[i + j + 1] = a * b; } - res[i + j + 1] = carry + '0'; } - int i; + int i, carry = 0; + string res(v.size(), '0'); + for (i = v.size() - 1; i >= 0; i--) { + carry += v[i]; + res[i] += carry % 10; + carry /= 10; + } + for (i = 0; i < res.length() - 1; i++) { if (res[i] != '0') { break; } } + return res.substr(i); } }; diff --git a/0131_palindrome_patitioning/palindrome_partition.cc b/0131_palindrome_patitioning/palindrome_partition.cc new file mode 100644 index 0000000..9897ddb --- /dev/null +++ b/0131_palindrome_patitioning/palindrome_partition.cc @@ -0,0 +1,42 @@ +#include + +using namespace std; + +class Solution { +public: + vector> partition(string s) { + vector> res; + vector> isPalindrome(s.size(), vector(s.size(), true)); + + // From bottom to up + for (int i = s.length() - 1; i >= 0; i--) { + // From left to right + for (int j = i + 1; j < s.length(); j++) { + // notebook for palindrome substring judgement + isPalindrome[i][j] = s[i] == s[j] && isPalindrome[i + 1][j - 1]; + } + } + + dfs(s, 0, isPalindrome, res); + return res; + } + +private: + vector ans; + void dfs(const string& s, int start, vector>& isPalindrome, vector>& res) { + // DFS for combination. When the start index reaches to the end, all + // the substrings are collected. + if (start == s.length()) { + res.push_back(ans); + return; + } + + for (int i = start; i < s.length(); i++) { + if (isPalindrome[start][i]) { + ans.push_back(s.substr(start, i - start + 1)); + dfs(s, i + 1, isPalindrome, res); + ans.pop_back(); + } + } + } +}; diff --git a/0133_clone_graph/clone_graph.cc b/0133_clone_graph/clone_graph.cc new file mode 100644 index 0000000..ca7d8e2 --- /dev/null +++ b/0133_clone_graph/clone_graph.cc @@ -0,0 +1,65 @@ +#include + +using namespace std; + +// Definition for a Node. +class Node { +public: + int val; + vector neighbors; + Node() { + val = 0; + neighbors = vector(); + } + Node(int _val) { + val = _val; + neighbors = vector(); + } + Node(int _val, vector _neighbors) { + val = _val; + neighbors = _neighbors; + } +}; + +class Solution { +public: + Node* cloneGraph(Node* node) { + if (node == nullptr) { + return node; + } +#if 1 // DFS + if (cloned.find(node) != cloned.end()) { + return cloned[node]; + } + + cloned[node] = new Node(node->val); + + for (auto& neighbor : node->neighbors) { + cloned[node]->neighbors.emplace_back(cloneGraph(neighbor)); + } +#else // BFS + queue q; + q.push(node); + cloned[node] = new Node(node->val); + + while (!q.empty()) { + int size = q.size(); + for (int i = 0; i < size; i++) { + auto n = q.front(); + q.pop(); + + for (auto& neighbor : n->neighbors) { + if (cloned.find(neighbor) == cloned.end()) { + cloned[neighbor] = new Node(neighbor->val); + q.push(neighbor); + } + cloned[n]->neighbors.emplace_back(cloned[neighbor]); + } + } + } +#endif + return cloned[node]; + } +private: + unordered_map cloned; +}; diff --git a/0567_permutation_in_string/permutation_in_string.cc b/0567_permutation_in_string/permutation_in_string.cc index 541b1cb..1061ae6 100644 --- a/0567_permutation_in_string/permutation_in_string.cc +++ b/0567_permutation_in_string/permutation_in_string.cc @@ -10,18 +10,20 @@ class Solution { count[c]++; } - int l = 0, r = 0, len = 0; + int l = 0, r = 0, hits = 0; while (r < s2.length()) { if (--count[s2[r++]] >= 0) { - len++; + hits++; } + // When the window length equals to the hit length, + // the permutation is contained. if (r - l >= s1.length()) { - if (len == s1.length()) { + if (hits == s1.length()) { return true; } if (++count[s2[l++]] > 0) { - len--; + hits--; } } }