diff --git a/0015_three_sum/three_sum.c b/0015_three_sum/three_sum.c index 53cd947..5b096c1 100644 --- a/0015_three_sum/three_sum.c +++ b/0015_three_sum/three_sum.c @@ -43,7 +43,7 @@ int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes int i, j, capacity = 50000; int **results = malloc(capacity * sizeof(int *)); for (i = 0; i < numsSize - 2; i++) { - if (i == 0 || i > 0 && nums[i] != nums[i - 1]) { + if (i == 0 || (i > 0 && nums[i] != nums[i - 1])) { two_sum(nums, i + 1, numsSize - 1, -nums[i], results, returnSize); } } @@ -58,14 +58,18 @@ int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes int main(void) { - int i, count; + int i, j, count; //int nums[] = { -1, 0, 1, 2, -1, -4 }; //int nums[] = { 0, 0, 0 }; //int nums[] = { -1, 0, 1, 0 }; int nums[] = {-2,0,0,2,2}; - int **triplets = threeSum(nums, sizeof(nums) / sizeof(*nums), &count); + int *col_sizes; + int **triplets = threeSum(nums, sizeof(nums) / sizeof(*nums), &count, &col_sizes); for (i = 0; i < count; i++) { - printf("%d %d %d\n", triplets[i][0], triplets[i][1], triplets[i][2]); + for (j = 0; j < col_sizes[i]; j++) { + printf("%d \n", triplets[i][j]); + } + printf("\n"); } return 0; diff --git a/0018_four_sum/four_sum.c b/0018_four_sum/four_sum.c index 8b8a182..8b06eaf 100644 --- a/0018_four_sum/four_sum.c +++ b/0018_four_sum/four_sum.c @@ -68,13 +68,16 @@ int** fourSum(int* nums, int numsSize, int target, int* returnSize, int** return int main(void) { - int i, count, target = 11, *col_sizes; + int i, j, count, target = 11, *col_sizes; //int nums[] = { 1, 0, -1, 0, -2, 2 }; //int nums[] = { -3, -2, -1, 0, 0, 1, 2, 3 }; int nums[] = { 0, 1, 5, 0, 1, 5, 5, -4 }; int **quadruplets = fourSum(nums, sizeof(nums) / sizeof(*nums), target, &count, &col_sizes); for (i = 0; i < count; i++) { - printf("%d %d %d %d\n", quadruplets[i][0], quadruplets[i][1], quadruplets[i][2], quadruplets[i][3]); + for (j = 0; j < col_sizes[i]; j++) { + printf("%d ", quadruplets[i][j]); + } + printf("\n"); } return 0; diff --git a/0025_reverse_nodes_in_k_group/reverse_nodes.c b/0025_reverse_nodes_in_k_group/reverse_nodes.c index c28dab0..ecbe9a1 100644 --- a/0025_reverse_nodes_in_k_group/reverse_nodes.c +++ b/0025_reverse_nodes_in_k_group/reverse_nodes.c @@ -14,21 +14,21 @@ static struct ListNode* reverseKGroup(struct ListNode* head, int k) dummy.next = head; for (; head != NULL; head = head->next) { if (++len % k == 0) { - /* t always the original first one */ - struct ListNode *t = prev->next; + /* p always the original first one */ + struct ListNode *p = prev->next; /* loop condition implicits the final state */ while (prev->next != head) { /* the new segment head */ - struct ListNode *h = t->next; + struct ListNode *q = p->next; /* deletion */ - t->next = h->next; + p->next = q->next; /* insertion */ - h->next = prev->next; - prev->next = h; + q->next = prev->next; + prev->next = q; } /* For iteration */ - prev = t; - head = t; + prev = p; + head = p; } } return dummy.next; diff --git a/0026_remove_duplicates_from_sorted_array/rm_dup.c b/0026_remove_duplicates_from_sorted_array/rm_dup.c index 95b2e0b..1bc5764 100644 --- a/0026_remove_duplicates_from_sorted_array/rm_dup.c +++ b/0026_remove_duplicates_from_sorted_array/rm_dup.c @@ -1,20 +1,17 @@ #include #include + static int removeDuplicates(int* nums, int numsSize) { - if (numsSize <= 1) { - return numsSize; - } - - int i, count = 1; + int i, size = 0; for (i = 1; i < numsSize; i++) { - if (nums[i - 1] != nums[i]) { - nums[count++] = nums[i]; + if (nums[size] != nums[i]) { + nums[++size] = nums[i]; } } - return count; + return size + 1; } int main(int argc, char **argv) diff --git a/0026_remove_duplicates_from_sorted_array/rm_dup.cc b/0026_remove_duplicates_from_sorted_array/rm_dup.cc index 2ceef80..ebfc556 100644 --- a/0026_remove_duplicates_from_sorted_array/rm_dup.cc +++ b/0026_remove_duplicates_from_sorted_array/rm_dup.cc @@ -5,16 +5,13 @@ using namespace std; class Solution { public: int removeDuplicates(vector& nums) { - if (nums.size() == 0) { - return 0; - } - - int count = 1; + int size = 0; for (int i = 1; i < nums.size(); i++) { - if (nums[i - 1] != nums[i]) { - nums[count++] = nums[i]; + if (nums[size] != nums[i]) { + nums[++size] = nums[i]; } } - return count; + + return size + 1; } }; 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/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/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/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/0046_permutations/permutations.c b/0046_permutations/permutations.c index 9f9ca36..49b0b73 100644 --- a/0046_permutations/permutations.c +++ b/0046_permutations/permutations.c @@ -88,10 +88,10 @@ int main(int argc, char **argv) nums[i] = atoi(argv[i + 1]); } - int *size; - int **lists = permute(nums, argc - 1, &count, &size); + int *col_sizes; + int **lists = permute(nums, argc - 1, &count, &col_sizes); for (i = 0; i < count; i++) { - for (j = 0; j < argc - 1; j++) { + for (j = 0; j < col_sizes[i]; j++) { printf("%d", lists[i][j]); } putchar('\n'); diff --git a/0047_permutations_ii/permutations.c b/0047_permutations_ii/permutations.c index 96688cb..612867b 100644 --- a/0047_permutations_ii/permutations.c +++ b/0047_permutations_ii/permutations.c @@ -72,10 +72,10 @@ int main(int argc, char **argv) nums[i] = atoi(argv[i + 1]); } - int *size; - int **lists = permute(nums, argc - 1, &count, &size); + int *col_sizes; + int **lists = permute(nums, argc - 1, &count, &col_sizes); for (i = 0; i < count; i++) { - for (j = 0; j < argc - 1; j++) { + for (j = 0; j < col_sizes[i]; j++) { printf("%d", lists[i][j]); } putchar('\n'); 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/0070_climbing_stairs/climb_stairs.c b/0070_climbing_stairs/climb_stairs.c index e1e05ea..31b1904 100644 --- a/0070_climbing_stairs/climb_stairs.c +++ b/0070_climbing_stairs/climb_stairs.c @@ -2,18 +2,18 @@ #include #include -static int dfs(int n, int *count) +static int dfs(int n, int *steps) { if (n == 1) { return 1; } else if (n == 2) { return 2; - } else if (count[n] > 0) { - return count[n]; + } else if (steps[n] > 0) { + return steps[n]; } else { - count[n] += dfs(n - 1, count); - count[n] += dfs(n - 2, count); - return count[n]; + steps[n] += dfs(n - 1, steps); + steps[n] += dfs(n - 2, steps); + return steps[n]; } } @@ -21,9 +21,9 @@ static int climbStairs(int n) { #if 1 if (n < 1) return 0; - int *count = malloc((n + 1) * sizeof(int)); - memset(count, 0, (n + 1) * sizeof(int)); - return dfs(n, count); + int *steps = malloc((n + 1) * sizeof(int)); + memset(steps, 0, (n + 1) * sizeof(int)); + return dfs(n, steps); #else int i, a = 1, b = 2, c; for (i = 3; i <= n; i++) { diff --git a/0076_minimum_window_substring/window_substring.c b/0076_minimum_window_substring/window_substring.c index 792e898..cd7f525 100644 --- a/0076_minimum_window_substring/window_substring.c +++ b/0076_minimum_window_substring/window_substring.c @@ -22,7 +22,7 @@ static char *minWindow(char *s, char *t) int l = 0, r = 0; int min_len = slen + 1; int start = 0; - int chars_to_meet = 0; + int len = 0; for (i = 0; i < tlen; i++) { count[t[i]]++; @@ -31,10 +31,10 @@ static char *minWindow(char *s, char *t) while (r < slen) { if (--count[s[r++]] >= 0) { /* pattern found */ - chars_to_meet++; + len++; } - while (chars_to_meet == tlen) { + while (len >= tlen) { if (r - l < min_len) { min_len = r - l; start = l; @@ -42,7 +42,7 @@ static char *minWindow(char *s, char *t) /* Chars with negative count are not included in the pattern string */ if (++count[s[l++]] > 0) { - chars_to_meet--; + len--; } } } 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/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/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) diff --git a/0199_binary_tree_right_side_view/bst_right.c b/0199_binary_tree_right_side_view/bst_right.c index f8fdbf4..2be03cd 100644 --- a/0199_binary_tree_right_side_view/bst_right.c +++ b/0199_binary_tree_right_side_view/bst_right.c @@ -90,9 +90,7 @@ static void node_free(struct queue_node *qn, struct list_head *free_list) } /** - ** Return an array of arrays of size *returnSize. - ** The sizes of the arrays are returned as *returnColumnSizes array. - ** Note: Both returned array and *returnColumnSizes array must be malloced, assume caller calls free(). + ** The returned array must be malloced, assume caller calls free(). **/ static int* rightSideView(struct TreeNode* root, int* returnSize) { 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 bf9ea50..dd049b5 100644 --- a/0215_kth_largest_element_in_an_array/kth_elem.c +++ b/0215_kth_largest_element_in_an_array/kth_elem.c @@ -2,6 +2,15 @@ #include +static void show(int *nums, int lo, int hi) +{ + int i; + for (i = lo; i <= hi; i++) { + printf("%d ", nums[i]); + } + printf("\n"); +} + static inline void swap(int *a, int *b) { int t = *a; @@ -38,41 +47,48 @@ static void build_max_heap(int *nums, int size) } } -static int quick_select(int *nums, int lo, int hi, int k) +static void quick_select(int *nums, int lo, int hi, int k) { if (lo >= hi) { - return hi; + return; } int i = lo - 1; - int j = hi + 1; - int pivot = nums[lo]; + int j = hi; + int pivot = nums[hi]; + while (i < j) { /* For case of large amounts of consecutive duplicate elements, we * 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 (nums[++i] > pivot) {} - while (nums[--j] < pivot) {} + while (i < hi && nums[++i] > pivot) {} + while (j > lo && nums[--j] < pivot) {} if (i < j) { swap(&nums[i], &nums[j]); } } /* invariant: i == j + 1 or i == j */ - if (j >= k - 1) { - return quick_select(nums, lo, j, k); + swap(&nums[i], &nums[hi]); + /* compare index [i] with [k - 1] to locate the kth element */ + if (i > k - 1) { + quick_select(nums, lo, i - 1, k); } else { - return quick_select(nums, j + 1, hi, k); + quick_select(nums, i + 1, hi, k); } } int findKthLargest(int* nums, int numsSize, int k) { -#if 0 - int i = quick_select(nums, 0, numsSize - 1, k); - return nums[i]; +#if 1 + quick_select(nums, 0, numsSize - 1, k); + return nums[k - 1]; #else int i; diff --git a/0224_basic_calculator/calculator.c b/0224_basic_calculator/calculator.c index e4cfac5..5c39e16 100644 --- a/0224_basic_calculator/calculator.c +++ b/0224_basic_calculator/calculator.c @@ -1,60 +1,65 @@ +#include #include #include -static int calculator(char *s) + +static int dfs(char **input) { - int n; - int pos1 = 0; - int pos2 = 0; - int *nums = malloc(1000 * sizeof(int)); - char *signs = malloc(1000 * sizeof(char)); + int i, res = 0; + int num = 0; + int stk[700], pos = 0; + char sign = '+'; + char *s = *input; - nums[pos1++] = 0; while (*s != '\0') { - switch (*s) { - case '+': - case '-': - case '(': - signs[pos2++] = *s; - break; - case ')': - --pos2; - if (pos1 >= 2 && pos2 > 0 && signs[pos2 - 1] != '(') { - n = nums[--pos1]; - int a = nums[--pos1]; - if (signs[--pos2] == '+') { - n = a + n; - } else { - n = a - n; - } - } - nums[pos1++] = n; - break; - case ' ': - break; - default: - n = 0; - while(*s >= '0' && *s <= '9') { - n = n * 10 + (*s - '0'); - s++; - } - s--; + char c = *s++; + if (isdigit(c)) { + num = 10 * num + (c - '0'); + } + + if (c == '(') { + /* dfs("2*(1+3)") = 2 * dfs("1+3") */ + num = dfs(&s); + } - if (pos1 >= 2 && signs[pos2 - 1] != '(' && signs[pos2 - 1] != '(') { - int a = nums[--pos1]; - if (signs[--pos2] == '+') { - n = a + n; - } else { - n = a - n; - } + if (!isdigit(c) && c != ' ' || *s == '\0') { + switch (sign) { + case '+': + stk[pos++] = num; + break; + case '-': + stk[pos++] = -num; + break; + case '*': + stk[pos - 1] *= num; + break; + case '/': + stk[pos - 1] /= num; + break; } - nums[pos1++] = n; - break; + /* update the sign and reset the number */ + sign = c; + num = 0; } - s++; + + /* return from the dfs */ + if (c == ')') + break; + } + + /* update position */ + *input = s; + + while (pos > 0) { + res += stk[--pos]; } - return n; + return res; +} + +static int calculator(char *s) +{ + return dfs(&s); } int main(int argc, char **argv) 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]; + } +}; diff --git a/0560_subarray_sum_equals_k/subarray_sum.cc b/0560_subarray_sum_equals_k/subarray_sum.cc new file mode 100644 index 0000000..e7fcced --- /dev/null +++ b/0560_subarray_sum_equals_k/subarray_sum.cc @@ -0,0 +1,28 @@ +#include + +using namespace std; + +class Solution { +public: + int subarraySum(vector& nums, int k) { + int res = 0, sum = 0; + unordered_map pre_sum_cnt; + + // The prefix sum array records the sum of nums[0...i], so we have + // presum[j] - presum[j] = k when the sum of nums[i...j] equals k. + // The presum[0] should always be 0. And pre_sum_cnt[0] = 1. + pre_sum_cnt[0] = 1; + for (const auto n : nums) { + // Here the sum means sum of nums[0...j] and the sum0 means sum + // of nums[0...i] then there will be sum - sum0 = k. + sum += n; + int sum0 = sum - k; + if (ht.count(sum0)) { + res += pre_sum_cnt[sum0]; + } + pre_sum_cnt[sum]++; + } + + return res; + } +}; 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--; } } } diff --git a/0912_sort_an_array/Makefile b/0912_sort_an_array/Makefile new file mode 100644 index 0000000..b959cec --- /dev/null +++ b/0912_sort_an_array/Makefile @@ -0,0 +1,2 @@ +all: + gcc -o test sort.c diff --git a/0912_sort_an_array/sort.c b/0912_sort_an_array/sort.c new file mode 100644 index 0000000..304ffaf --- /dev/null +++ b/0912_sort_an_array/sort.c @@ -0,0 +1,125 @@ +#include +#include + + +static void show(int *nums, int lo, int hi) +{ + int i; + for (i = lo; i <= hi; i++) { + printf("%d ", nums[i]); + } + printf("\n"); +} + +static inline void swap(int *a, int *b) +{ + int t = *a; + *a = *b; + *b = t; +} + +static void quick_sort(int *nums, int lo, int hi) +{ + int i, j, mid, pivot; + + if (lo >= hi) { + return; + } + + /* shuffle the pivot as it is a must for performance */ + mid = lo + (hi - lo) / 2; + swap(&nums[mid], &nums[hi]); + + i = lo - 1; + j = hi; + pivot = nums[hi]; + while (i < j) { + /* For case of large amounts of consecutive duplicate elements, we + * 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 < j && nums[++i] < pivot) {} + while (i < j && nums[--j] > pivot) {} + if (i < j) { + swap(&nums[i], &nums[j]); + } + } + + /* Loop invariant: i == j + 1 or i == j */ + swap(&nums[i], &nums[hi]); + quick_sort(nums, lo, i - 1); + quick_sort(nums, i + 1, hi); +} + +static void merge(int *nums, int lo, int mid, int hi) +{ + int i, j, k, size = hi - mid; + int *tmp = malloc(size * sizeof(int)); + + for (j = 0; j < size; j++) { + tmp[j] = nums[mid + 1 + j]; + } + + i = mid; + j = size - 1; + k = hi; + while (i >= lo && j >= 0) { + if (tmp[j] >= nums[i]) { + nums[k--] = tmp[j--]; + } else { + nums[k--] = nums[i--]; + } + } + + while (j >= 0) { + nums[k--] = tmp[j--]; + } + + free(tmp); +} + +static void merge_sort(int *nums, int lo, int hi) +{ + int mid; + + if (lo >= hi) { + return; + } + + mid = lo + (hi - lo) / 2; + + merge_sort(nums, lo, mid); + merge_sort(nums, mid + 1, hi); + + merge(nums, lo, mid, hi); +} + +int *sortArray(int *nums, int numsSize, int *returnSize) +{ +#if 1 + quick_sort(nums, 0, numsSize - 1); +#else + merge_sort(nums, 0, numsSize - 1); +#endif + *returnSize = numsSize; + return nums; +} + +int main(int argc, char **argv) +{ + int i, count = argc - 1; + int ret_size = 0; + int *nums = malloc(count * sizeof(int)); + for (i = 0; i < count; i++) { + nums[i] = atoi(argv[i + 1]); + } + + show(sortArray(nums, count, &ret_size), 0, ret_size - 1); + + return 0; +}