diff --git a/0001_two_sum/two_sum.c b/0001_two_sum/two_sum.c index e91c9ff..6a701ea 100644 --- a/0001_two_sum/two_sum.c +++ b/0001_two_sum/two_sum.c @@ -1,6 +1,7 @@ #include #include + struct object { int val; int index; @@ -11,7 +12,7 @@ static int compare(const void *a, const void *b) return ((struct object *) a)->val - ((struct object *) b)->val; } -static int * twosum(int *nums, int numsSize, int target, int *returnSize) +int * twosum(int *nums, int numsSize, int target, int *returnSize) { int i, j; struct object *objs = malloc(numsSize * sizeof(*objs)); diff --git a/0001_two_sum/two_sum.cc b/0001_two_sum/two_sum.cc index c06f0b4..7dca0f0 100644 --- a/0001_two_sum/two_sum.cc +++ b/0001_two_sum/two_sum.cc @@ -9,7 +9,7 @@ class Solution { unordered_map ht; for (int i = 0; i < nums.size(); i++) { int other = target - nums[i]; - if (ht.find(other) != ht.end()) { + if (ht.count(other)) { /* Only one solution for purpose of this problem */ res.append(ht[other]); res.append(i); diff --git a/0001_two_sum/two_sum.py b/0001_two_sum/two_sum.py deleted file mode 100644 index 2606238..0000000 --- a/0001_two_sum/two_sum.py +++ /dev/null @@ -1,11 +0,0 @@ -class Solution: - def twoSum(self, nums, target): - h = {} - for i, n in enumerate(nums): - other = target - n - if other not in h: - h[n] = i - else: - return [h[other], i] - -print(Solution().twoSum([-1, -2, -3, -4, -5], -8)) diff --git a/0002_add_two_numbers/add_two_numbers.c b/0002_add_two_numbers/add_two_numbers.c index acc3ebb..2dd91d5 100644 --- a/0002_add_two_numbers/add_two_numbers.c +++ b/0002_add_two_numbers/add_two_numbers.c @@ -2,13 +2,14 @@ #include #include + /* Definition for singly-linked list. */ struct ListNode { int val; struct ListNode *next; }; -static struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) +struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) { int carry = 0; struct ListNode dummy; diff --git a/0003_longest_substring_without_repeat/longest_substring_without_repeat.c b/0003_longest_substring_without_repeat/longest_substring_without_repeat.c index 701efa4..51c7c27 100644 --- a/0003_longest_substring_without_repeat/longest_substring_without_repeat.c +++ b/0003_longest_substring_without_repeat/longest_substring_without_repeat.c @@ -2,33 +2,22 @@ #include #include -static int lengthOfLongestSubstring(char *s) + +int lengthOfLongestSubstring(char *s) { - int offset[128]; - int max_len = 0; + int count[256] = {0}; int len = 0; - int index = 0; + int i, j; - memset(offset, 0xff, sizeof(offset)); - while (*s != '\0') { - if (offset[*s] == -1) { - len++; - } else { - if (index - offset[*s] > len) { - /* not included in sliding window, go on increasing */ - len++; - } else { - /* repetition in sliding window, count from scratch */ - len = index - offset[*s]; - } - } - if (len > max_len) { - max_len = len; + for (i = 0, j = 0; s[i] != '\0'; i++) { + count[s[i]]++; + while (count[s[i]] > 1) { + len = i - j > len ? i - j : len; + count[s[j++]] -= 1; } - offset[*s++] = index++; } - return max_len; + return i - j > len ? i - j : len; } int main(int argc, char **argv) diff --git a/0003_longest_substring_without_repeat/longest_substring_without_repeat.cc b/0003_longest_substring_without_repeat/longest_substring_without_repeat.cc index 08a12e2..af643ca 100644 --- a/0003_longest_substring_without_repeat/longest_substring_without_repeat.cc +++ b/0003_longest_substring_without_repeat/longest_substring_without_repeat.cc @@ -5,26 +5,18 @@ using namespace std; class Solution { public: int lengthOfLongestSubstring(string s) { - vector indexes(128, -1); - int max_len = 0; + vector count(256); int len = 0; + int i, j; - for (int i = 0; i < s.length(); i++) { - if (indexes[s[i]] == -1) { - len++; - } else { - if (i - indexes[s[i]] > len) { - /* not included in sliding window, go on increasing */ - len++; - } else { - /* repetition in sliding window, count from scratch */ - len = i - indexes[s[i]]; - } + for (i = 0, j = 0; i < s.length(); i++) { + count[s[i]]++; + while (count[s[i]] > 1) { + len = i - j > len ? i - j : len; + count[s[j++]] -= 1; } - max_len = max(max_len, len); - indexes[s[i]] = i; } - return max_len; + return i - j > len ? i - j : len; } }; diff --git a/0005_longest_palindromic_substring/longest_palindromic_substring.cc b/0005_longest_palindromic_substring/longest_palindromic_substring.cc new file mode 100644 index 0000000..3b95bb1 --- /dev/null +++ b/0005_longest_palindromic_substring/longest_palindromic_substring.cc @@ -0,0 +1,25 @@ +#include + +using namespace std; + +class Solution { +public: + string longestPalindrome(string s) { + bool dp[1005][1005]; + int n = s.size(); + int strlen = 0, start; + for(int i=n-1; i>=0; i--){ + for(int j=i; j #include + static int compare(const void *a, const void *b) { return *(int *) a - *(int *) b; @@ -30,7 +31,7 @@ static void two_sum(int *nums, int low, int high, int target, int **results, int ** Return an array of arrays of size *returnSize. ** Note: The returned array must be malloced, assume caller calls free(). **/ -static int** threeSum(int* nums, int numsSize, int* returnSize) +int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) { if (numsSize < 3) { return NULL; @@ -42,23 +43,33 @@ static int** threeSum(int* nums, int numsSize, int* returnSize) 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); } } + + *returnColumnSizes = malloc(*returnSize * sizeof(int *)); + for (i = 0; i < *returnSize; i++) { + (*returnColumnSizes)[i] = 3; + } + return results; } 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/0017_letter_combinations_of_a_phone_number/letter_combinations.cpp b/0017_letter_combinations_of_a_phone_number/letter_combinations.cpp new file mode 100644 index 0000000..2d375c4 --- /dev/null +++ b/0017_letter_combinations_of_a_phone_number/letter_combinations.cpp @@ -0,0 +1,43 @@ +#include +using namespace std; + +class Solution +{ +public: + vector m = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; + vector ans; + vector letterCombinations(string digits) + { + solve(0, "", digits); + return ans; + } + void solve(int i, string path, string digits) + { + if (i >= digits.size()) + { + if (path.size() > 0) + ans.push_back(path); + return; + } + for (auto c : m[digits[i] - '0']) + { + path += c; + solve(i + 1, path, digits); + path.pop_back(); + } + } +}; + +int main() +{ + cout << "Enter A string : "; + string s; + cin >> s; + Solution sol; + // vector ans = sol.letterCombinations(s) ; + for (auto str : sol.letterCombinations(s)) + { + cout << str << " "; + } + return 0; +} \ No newline at end of file diff --git a/0018_four_sum/four_sum.c b/0018_four_sum/four_sum.c index 87ce58b..8b06eaf 100644 --- a/0018_four_sum/four_sum.c +++ b/0018_four_sum/four_sum.c @@ -2,13 +2,14 @@ #include #include + static int compare(const void *a, const void *b) { return *(int *) a - *(int *) b; } -static void k_sum(int *nums, int low, int high, int target, int total, int k, - int *stack, int len, int **results, int *count, int *columnSizes) +static void k_sum(int *nums, int low, int high, long target, int total, int k, + int *stack, int len, int **results, int *count) { int i; if (k == 2) { @@ -23,7 +24,6 @@ static void k_sum(int *nums, int low, int high, int target, int total, int k, stack[len++] = nums[high]; results[*count] = malloc(total * sizeof(int)); memcpy(results[*count], stack, total * sizeof(int)); - columnSizes[*count] = total; (*count)++; len -= 2; while (++low < high && nums[low] == nums[low - 1]) {} @@ -34,9 +34,9 @@ static void k_sum(int *nums, int low, int high, int target, int total, int k, /* k > 2 */ for (i = low; i <= high - k + 1; i++) { if (i > low && nums[i] == nums[i - 1]) continue; - stack[len++] = nums[i]; - k_sum(nums, i + 1, high, target - nums[i], 4, k - 1, stack, len, results, count, columnSizes); - len--; + stack[len] = nums[i]; + k_sum(nums, i + 1, high, target - nums[i], 4, k - 1, stack, + len + 1, results, count); } } } @@ -44,31 +44,40 @@ static void k_sum(int *nums, int low, int high, int target, int total, int k, /** * Return an array of arrays of size *returnSize. * The sizes of the arrays are returned as *returnColumnSizes array. - * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). + * Note: Both returned array and *returnColumnSizes array must be malloced, assume caller calls free(). */ -int** fourSum(int* nums, int numsSize, int target, int* returnSize, int** returnColumnSizes) { +int** fourSum(int* nums, int numsSize, int target, int* returnSize, int** returnColumnSizes) +{ *returnSize = 0; - int i, j, capacity = 50000; + int i, capacity = 50000; int **results = malloc(capacity * sizeof(int *)); - *returnColumnSizes = malloc(capacity * sizeof(int)); if (numsSize >= 4) { qsort(nums, numsSize, sizeof(*nums), compare); int *stack = malloc(4 * sizeof(int)); - k_sum(nums, 0, numsSize - 1, target, 4, 4, stack, 0, results, returnSize, *returnColumnSizes); + k_sum(nums, 0, numsSize - 1, target, 4, 4, stack, 0, results, returnSize); + } + + *returnColumnSizes = malloc(capacity * sizeof(int)); + for (i = 0; i < *returnSize; i++) { + (*returnColumnSizes)[i] = 4; } + return results; } int main(void) { - int i, count; + 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), 11, &count); + 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/0021_merge_two_sorted_lists/merge_lists.c b/0021_merge_two_sorted_lists/merge_lists.c index 34ecdb0..021a584 100644 --- a/0021_merge_two_sorted_lists/merge_lists.c +++ b/0021_merge_two_sorted_lists/merge_lists.c @@ -9,25 +9,20 @@ struct ListNode { static struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) { struct ListNode dummy; - struct ListNode *prev = &dummy; - dummy.next = l1; + struct ListNode *tail = &dummy; while (l1 != NULL && l2 != NULL) { if (l1->val <= l2->val) { - prev = l1; + tail->next = l1; l1 = l1->next; } else { - struct ListNode *tmp = l2->next; - l2->next = l1; - prev->next = l2; - prev = l2; - l2 = tmp; + tail->next = l2; + l2 = l2->next; } + tail = tail->next; } - if (l2 != NULL) { - prev->next = l2; - } + tail->next = l1 != NULL ? l1 : l2; return dummy.next; } diff --git a/0021_merge_two_sorted_lists/merge_lists.cc b/0021_merge_two_sorted_lists/merge_lists.cc index a5d7a63..58a47f7 100644 --- a/0021_merge_two_sorted_lists/merge_lists.cc +++ b/0021_merge_two_sorted_lists/merge_lists.cc @@ -15,26 +15,21 @@ using namespace std; class Solution { public: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { - struct ListNode *prev, dummy; - - prev = &dummy; + struct ListNode *tail, dummy; + tail = &dummy; dummy.next = l1; + while (l1 != nullptr && l2 != nullptr) { if (l1->val <= l2->val) { - prev = l1; + tail->next = l1; l1 = l1->next; } else { - struct ListNode *tmp = l2; + tail->next = l2; l2 = l2->next; - tmp->next = l1; - prev->next = tmp; - prev = tmp; } } - if (l2 != nullptr) { - prev->next = l2; - } + tail->next = l1 != nullptr ? l1 : l2; return dummy.next; } diff --git a/0022_generate_parathesis/young_tableau.cc b/0022_generate_parathesis/young_tableau.cc new file mode 100644 index 0000000..04ffc7d --- /dev/null +++ b/0022_generate_parathesis/young_tableau.cc @@ -0,0 +1,60 @@ +#include +#include +#include + + +using namespace std; + +class Solution { +public: + vector> young_tableau(int n) { + vector> res; + dfs(n, 0, 0, res); + return res; + } + +private: + vector stack; + + void dfs(int n, int l, int r, vector>& res) { + if (stack.size() == 2 * n) { + vector sol(2 * n); + for (int i = 0, j = 0, k = n; i < 2 * n; i++) { + if (stack[i] == '(') { + sol[j++] = i + 1; + } else { + sol[k++] = i + 1; + } + } + res.push_back(sol); + } else { + if (l < n) { + stack.push_back('('); + dfs(n, l + 1, r, res); + stack.pop_back(); + } + + if (r < l) { + stack.push_back(')'); + dfs(n, l, r + 1, res); + stack.pop_back(); + } + } + } +}; + +int main(int argc, char **argv) +{ + int n = atoi(argv[1]); + Solution *solution = new Solution(); + vector> res = solution->young_tableau(n); + for (auto& v : res) { + for (int i = 0; i < 2 * n; i++) { + if (i == n) cout << endl; + cout << v[i] << ' '; + } + cout << endl; + } + + return 0; +} diff --git a/0023_merge_k_sorted_lists/merge_lists.c b/0023_merge_k_sorted_lists/merge_lists.c index 3b29dd6..5695b91 100644 --- a/0023_merge_k_sorted_lists/merge_lists.c +++ b/0023_merge_k_sorted_lists/merge_lists.c @@ -2,146 +2,137 @@ #include #include +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ struct ListNode { int val; struct ListNode *next; }; -struct PriorityQueue { - struct ListNode **nodes; - int size; -}; - static inline void swap(struct ListNode **a, struct ListNode **b) { - struct ListNode *tmp = *a; + struct ListNode *t = *a; *a = *b; - *b = tmp; + *b = t; } -static inline int left(int i) { return i * 2 + 1; } -static inline int right(int i) { return left(i) + 1; } -static inline int parent(int i) { return (i - 1) / 2; } - -static void queue_dump(struct PriorityQueue *queue) +static void min_heapify(struct ListNode **nodes, int size, int parent) { - int i; - for (i = 0; i < queue->size; i++) { - printf("%d ", queue->nodes[i]->val); - } - printf("\n"); -} + int i = parent; /* parent is the root */ + int l = parent * 2 + 1; + int r = parent * 2 + 2; -static void percolate_up(struct ListNode **nodes, int i) -{ - while (i >= 0 && nodes[parent(i)]->val > nodes[i]->val) { - swap(nodes + parent(i), nodes + i); - i = parent(i); + if (l < size && nodes[l]->val < nodes[i]->val) { + i = l; } -} -static void percolate_down1(struct ListNode **nodes, int size, int child) -{ - int i, min; - for (i = child; i >= 0; i = parent(i)) { - if (right(i) < size) { - min = nodes[left(i)]->val < nodes[right(i)]->val ? left(i) : right(i); - } else { - min = left(i); - } - if (nodes[min]->val < nodes[i]->val) { - swap(nodes + min, nodes + i); - } else { - break; - } + if (r < size && nodes[r]->val < nodes[i]->val) { + i = r; } -} -static void percolate_down2(struct ListNode **nodes, int size) -{ - int i, min; - for (i = 0; left(i) < size; i = min) { - if (right(i) < size) { - min = nodes[left(i)]->val < nodes[right(i)]->val ? left(i) : right(i); - } else { - min = left(i); - } - if (nodes[min]->val < nodes[i]->val) { - swap(nodes + min, nodes + i); - } else { - break; - } + /* percolate up */ + if (i != parent) { + swap(&nodes[i], &nodes[parent]); + min_heapify(nodes, size, i); } } -static void heap_build(struct PriorityQueue *queue) +static void build_min_heap(struct ListNode **nodes, int size) { int i; - for (i = queue->size / 2 - 1; i > 0; i--) { - percolate_down1(queue->nodes, queue->size, i); + + if (size <= 0) return; + + for (i = size / 2; i >= 0; i--) { + min_heapify(nodes, size, i); } } -static void put(struct PriorityQueue *queue, struct ListNode *node) +static struct ListNode *get(struct ListNode **nodes, int size) { - queue->nodes[queue->size++] = node; - percolate_up(queue->nodes, queue->size - 1); + struct ListNode *p = nodes[0]; + nodes[0] = nodes[--size]; + min_heapify(nodes, size, 0); + return p; } -static struct ListNode *get(struct PriorityQueue *queue) +static void put(struct ListNode **nodes, int size, struct ListNode *n) { - int i; - struct ListNode *p = queue->nodes[0]; - swap(queue->nodes, queue->nodes + queue->size - 1); - queue->size--; - percolate_down2(queue->nodes, queue->size); - return p; + nodes[size++] = n; + build_min_heap(nodes, size); } -static struct PriorityQueue *init(int size) +static struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) { - struct PriorityQueue *queue = malloc(sizeof(*queue)); - queue->nodes = malloc(size * sizeof(*queue->nodes)); - queue->size = 0; - return queue; + struct ListNode dummy; + struct ListNode *tail = &dummy; + + while (l1 != NULL && l2 != NULL) { + if (l1->val <= l2->val) { + tail->next = l1; + l1 = l1->next; + } else { + tail->next = l2; + l2 = l2->next; + } + tail = tail->next; + } + + tail->next = l1 != NULL ? l1 : l2; + + return dummy.next; } -static struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) +static struct ListNode* dfs(struct ListNode** lists, int lo, int hi) { - if (listsSize == 0) { - return NULL; - } + if (lo > hi) // listsSize might be zero + return NULL; - if (listsSize == 1) { - return lists[0]; - } + if (lo == hi) + return lists[lo]; - int i; - struct ListNode dummy; - struct ListNode *prev; - struct PriorityQueue *queue = init(listsSize); + int mid = lo + (hi - lo) / 2; + return mergeTwoLists(dfs(lists, lo, mid), dfs(lists, mid + 1, hi)); +} - dummy.next = NULL; - prev = &dummy; + +struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) +{ +#if 1 + return dfs(lists, 0, listsSize - 1); +#else + int i, size = 0; + struct ListNode dummy; + struct ListNode *p = &dummy; + struct ListNode **nodes = malloc(listsSize * sizeof(struct ListNode)); for (i = 0; i < listsSize; i++) { if (lists[i] != NULL) { - put(queue, lists[i]); + nodes[size++] = lists[i]; } } - heap_build(queue); - while (queue->size > 0) { - struct ListNode *n = get(queue); - prev->next = n; - prev = n; + build_min_heap(nodes, size); + + while (size > 0) { + struct ListNode *n = get(nodes, size); + size--; + p->next = n; + p = p->next; if (n->next != NULL) { - put(queue, n->next); + put(nodes, size, n->next); + size++; } n->next = NULL; } return dummy.next; +#endif } int main(void) 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/0027_remove_element/rm_elem.c b/0027_remove_element/rm_elem.c index 21109fb..6e56505 100644 --- a/0027_remove_element/rm_elem.c +++ b/0027_remove_element/rm_elem.c @@ -1,7 +1,8 @@ #include #include -static int removeElement(int *nums, int numsSize, int val) + +int removeElement(int *nums, int numsSize, int val) { int i, count = 0; for (i = 0; i < numsSize; i++) { diff --git a/0028_implement_strstr/strstr.c b/0028_implement_strstr/strstr.c index 24a8c32..f8204ba 100644 --- a/0028_implement_strstr/strstr.c +++ b/0028_implement_strstr/strstr.c @@ -78,6 +78,10 @@ static int strStr(char *haystack, char *needle) unsigned int hlen = strlen(haystack); unsigned int nlen = strlen(needle); + // when haystack is shorter than needle, should return -1 + if(hlen < nlen) + return -1; + /* Brute force */ /* Corner condition: imagine nlen = 1 and it equals i < hlen */ for (i = 0; i < hlen - nlen + 1; i++) { diff --git a/0028_implement_strstr/strstr.cc b/0028_implement_strstr/strstr.cc index 08808ff..1262839 100644 --- a/0028_implement_strstr/strstr.cc +++ b/0028_implement_strstr/strstr.cc @@ -4,7 +4,41 @@ using namespace std; class Solution { public: - int strStr(string haystack, string needle) { - return haystack.find(needle); - } + + // Rabin-Karp Algorithm for string matching + int strStr(string haystack, string needle) { + long long mod = 1e9 + 7, p = 53; + int h = haystack.size(), n = needle.size(); + if (h < n) return -1; + if (n == 0) return 0; + + // precalculating powers of p + vector p_pow(max(h, n)); + p_pow[0] = 1; + for (int i = 1; i < p_pow.size(); i++) { + p_pow[i] = (p_pow[i - 1] * p) % mod; + } + // calculating haystack_hash + vector haystack_hash(haystack.size() + 1, 0); + for (int i = 0; i < h; i++) { + haystack_hash[i + 1] = (haystack_hash[i] + (haystack[i] - 'a' + 1) * p_pow[i]) % mod; + } + + // calculating needle_hash + long long needle_hash = 0; + for (int i = 0; i < n; i++) { + needle_hash = (needle_hash + (needle[i] - 'a' + 1) * p_pow[i]) % mod; + } + + // checking for matching hashes + for (int i = 0; i <= h - n; i++) { + long long curr_hash = (haystack_hash[i + n] + mod - haystack_hash[i]) % mod; + if (curr_hash == (needle_hash * p_pow[i]) % mod) { + return i; + } + } + + // if no hash is find + return -1; + } }; diff --git a/0030_substring_with_concatenation_of_all_words/concatenation.c b/0030_substring_with_concatenation_of_all_words/concatenation.c index aefda09..475cc45 100644 --- a/0030_substring_with_concatenation_of_all_words/concatenation.c +++ b/0030_substring_with_concatenation_of_all_words/concatenation.c @@ -3,48 +3,67 @@ #include #include + #define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - (size_t)&(((type *)0)->member))) #define list_entry(ptr, type, member) \ container_of(ptr, type, member) -#define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos; pos = pos->next) - -struct hlist_node; +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, __typeof(*pos), member); \ + &(pos)->member != (head); \ + pos = list_entry((pos)->member.next, __typeof(*pos), member)) -struct hlist_head { - struct hlist_node *first; +struct list_head { + struct list_head *next, *prev; }; -struct hlist_node { - struct hlist_node *next, **pprev; +struct word_node { + char *word; + int index; + struct list_head link; }; -static inline void INIT_HLIST_HEAD(struct hlist_head *h) { - h->first = NULL; +static inline void INIT_LIST_HEAD(struct list_head *list) +{ + list->next = list->prev = list; } -static inline int hlist_empty(struct hlist_head *h) { - return !h->first; +static inline int list_empty(const struct list_head *head) +{ + return (head->next == head); } -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) +static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { - if (h->first != NULL) { - h->first->pprev = &n->next; - } - n->next = h->first; - n->pprev = &h->first; - h->first = n; + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; } -struct word_node { - struct hlist_node node; - char *word; - int index; -}; +static inline void list_add(struct list_head *_new, struct list_head *head) +{ + __list_add(_new, head, head->next); +} + +static inline void list_add_tail(struct list_head *_new, struct list_head *head) +{ + __list_add(_new, head->prev, head); +} + +static inline void __list_del(struct list_head *entry) +{ + entry->next->prev = entry->prev; + entry->prev->next = entry->next; +} + +static inline void list_del(struct list_head *entry) +{ + __list_del(entry); + entry->next = entry->prev = NULL; +} static inline int BKDRHash(char *s, size_t size) { @@ -56,12 +75,11 @@ static inline int BKDRHash(char *s, size_t size) return hash % size; } -static int find(char *word, struct hlist_head *heads, int size) +static int find(char *word, struct list_head *heads, int size) { + struct word_node *wn; int hash = BKDRHash(word, size); - struct hlist_node *pos; - hlist_for_each(pos, &heads[hash]) { - struct word_node *wn = list_entry(pos, struct word_node, node); + list_for_each_entry(wn, &heads[hash], link) { if (!strcmp(wn->word, word)) { return wn->index; } @@ -69,13 +87,11 @@ static int find(char *word, struct hlist_head *heads, int size) return -1; } -static void add(char **words, int index, struct hlist_head *heads, int size, int *freqs) +static void add(char **words, int index, struct list_head *heads, int size, int *freqs) { - int hash = BKDRHash(words[index], size); - struct hlist_node *pos; struct word_node *wn; - hlist_for_each(pos, &heads[hash]) { - wn = list_entry(pos, struct word_node, node); + int hash = BKDRHash(words[index], size); + list_for_each_entry(wn, &heads[hash], link) { if (!strcmp(wn->word, words[index])) { freqs[wn->index]++; return; @@ -84,7 +100,7 @@ static void add(char **words, int index, struct hlist_head *heads, int size, int wn = malloc(sizeof(*wn)); wn->word = words[index]; wn->index = index; - hlist_add_head(&wn->node, &heads[hash]); + list_add(&wn->link, &heads[hash]); freqs[wn->index]++; } @@ -101,9 +117,9 @@ static int *findSubstring(char *s, char **words, int wordsSize, int *returnSize) int i, j, cap = 10000, count = 0; int hash_size = wordsSize; - struct hlist_head *heads = malloc(hash_size * sizeof(*heads)); + struct list_head *heads = malloc(hash_size * sizeof(*heads)); for (i = 0; i < hash_size; i++) { - INIT_HLIST_HEAD(&heads[i]); + INIT_LIST_HEAD(&heads[i]); } int *freqs = malloc(wordsSize * sizeof(int)); 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 d1c7f72..f12077d 100644 --- a/0031_next_permutation/next_permutation.cc +++ b/0031_next_permutation/next_permutation.cc @@ -5,23 +5,24 @@ using namespace std; class Solution { public: void nextPermutation(vector& nums) { - if (nums.size() < 2) { - return; - } - + // 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[j] >= nums[i]) { + while (j >= 0 && nums[i] >= nums[j]) { j--; } - swap(nums.begin() + i, nums.begin() + j); + swap(nums[i], nums[j]); } + // reverse the subsequence into increasing one. reverse(nums.begin() + i + 1, nums.end()); } }; diff --git a/0033_search_in_rotated_sorted_array/rotated_array.c b/0033_search_in_rotated_sorted_array/rotated_array.c index 822c2ee..07d508c 100644 --- a/0033_search_in_rotated_sorted_array/rotated_array.c +++ b/0033_search_in_rotated_sorted_array/rotated_array.c @@ -12,6 +12,8 @@ static int search(int* nums, int numsSize, int target) return mid; } + /* lo might be mid */ + /* We only need to consider non-rotated sorted array search */ if (nums[lo] <= nums[mid]) { if (nums[lo] <= target && target < nums[mid]) { hi = mid - 1; diff --git a/0033_search_in_rotated_sorted_array/rotated_array.cc b/0033_search_in_rotated_sorted_array/rotated_array.cc index 6332d10..67d0ec8 100644 --- a/0033_search_in_rotated_sorted_array/rotated_array.cc +++ b/0033_search_in_rotated_sorted_array/rotated_array.cc @@ -7,11 +7,15 @@ class Solution { int search(vector& nums, int target) { int lo = 0; int hi = nums.size() - 1; + for (lo <= hi) { int mid = lo + (hi - lo) / 2; if (nums[mid] == target) { return mid; } + + // lo might be mid + // We only need to consider non-rotated sorted array search if (nums[lo] <= nums[mid]) { if (nums[lo] <= target && target < nums[mid]) { hi = mid - 1; @@ -26,6 +30,7 @@ class Solution { } } } + return -1; } }; diff --git a/0039_combination_sum/combination_sum.c b/0039_combination_sum/combination_sum.c index 9bda0fc..0fcb96b 100644 --- a/0039_combination_sum/combination_sum.c +++ b/0039_combination_sum/combination_sum.c @@ -28,10 +28,10 @@ static void dfs(int *nums, int size, int start, int target, int *stack, ** The sizes of the arrays are returned as *returnColumnSizes array. ** Note: Both returned array and *returnColumnSizes array must be malloced, assume caller calls free(). **/ -static int** combinationSum(int* candidates, int candidatesSize, int target, int* returnSize, int **returnColumnSizes) +int** combinationSum(int* candidates, int candidatesSize, int target, int* returnSize, int **returnColumnSizes) { int cap = 200; - int *stack = malloc(candidatesSize * sizeof(int)); + int *stack = malloc(cap * sizeof(int)); int **results = malloc(cap * sizeof(int *)); *returnColumnSizes = malloc(cap * sizeof(int)); *returnSize = 0; diff --git a/0039_combination_sum/combination_sum.cc b/0039_combination_sum/combination_sum.cc index 11afede..a95ab08 100644 --- a/0039_combination_sum/combination_sum.cc +++ b/0039_combination_sum/combination_sum.cc @@ -5,14 +5,14 @@ using namespace std; class Solution { public: vector> combinationSum(vector& candidates, int target) { - vector stack; vector> res; - dfs(candidates, 0, target, stack, res); + dfs(candidates, 0, target, res); return res; } private: - void dfs(vector& candidates, int start, int target, vector& stack, vector>& res) { + vector stack; + void dfs(vector& candidates, int start, int target, vector>& res) { if (target < 0) { return; } else if (target == 0) { @@ -20,8 +20,8 @@ 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 */ - dfs(candidates, i, target - candidates[i], stack, res); + /* 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/0040_combination_sum_ii/combination_sum.c b/0040_combination_sum_ii/combination_sum.c index b49ea54..4623149 100644 --- a/0040_combination_sum_ii/combination_sum.c +++ b/0040_combination_sum_ii/combination_sum.c @@ -11,7 +11,7 @@ static int compare(const void *a, const void *b) } static void dfs(int *nums, int size, int start, int target, int *solution, - int len, int **results, int *count, int *column_sizes) + int len, int **results, int *count, int *col_sizes) { int i; if (target < 0) { @@ -19,16 +19,16 @@ static void dfs(int *nums, int size, int start, int target, int *solution, } else if (target == 0) { results[*count] = malloc(len * sizeof(int)); memcpy(results[*count], solution, len * sizeof(int)); - column_sizes[*count] = len; + col_sizes[*count] = len; (*count)++; } else { int last = INT_MIN; for (i = start; i < size; i++) { if (last != nums[i]) { - /* No duplicate combinations in different order */ + /* No duplicate combinations in the same level position */ solution[len] = nums[i]; /* i + 1 limits the candidate range in next levels */ - dfs(nums, size, i + 1, target - nums[i], solution, len + 1, results, count, column_sizes); + dfs(nums, size, i + 1, target - nums[i], solution, len + 1, results, count, col_sizes); } last = nums[i]; } @@ -40,7 +40,7 @@ static void dfs(int *nums, int size, int start, int target, int *solution, ** The sizes of the arrays are returned as *returnColumnSizes array. ** Note: Both returned array and *returnColumnSizes array must be malloced, assume caller calls free(). **/ -static int** combinationSum(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes) +int** combinationSum(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes) { qsort(candidates, candidatesSize, sizeof(int), compare); diff --git a/0040_combination_sum_ii/combination_sum.cc b/0040_combination_sum_ii/combination_sum.cc index c74461f..277b432 100644 --- a/0040_combination_sum_ii/combination_sum.cc +++ b/0040_combination_sum_ii/combination_sum.cc @@ -5,15 +5,15 @@ using namespace std; class Solution { public: vector> combinationSum2(vector& candidates, int target) { - vector stack; vector> res; sort(candidates.begin(), candidates.end()); - dfs(candidates, 0, target, stack, res); + dfs(candidates, 0, target, res); return res; } private: - void dfs(vector& candidates, int start, int target, vector& stack, vector>& res) { + vector stack; + void dfs(vector& candidates, int start, int target, vector>& res) { if (target < 0) { return; } else if (target == 0) { @@ -22,10 +22,10 @@ class Solution { int last = INT_MIN; for (int i = start; i < candidates.size(); i++) { if (last != candidates[i]) { - /* No duplicate combinations in different order */ + /* No duplicate combinations in the same level position */ stack.push_back(candidates[i]); /* i + 1 limits the candidate range in next levels */ - dfs(candidates, i + 1, target - candidates[i], stack, res); + dfs(candidates, i + 1, target - candidates[i], res); stack.pop_back(); } last = candidates[i]; diff --git a/0042_trapping_rain_water/trap_water.c b/0042_trapping_rain_water/trap_water.c index 5f184e4..d0abc5b 100644 --- a/0042_trapping_rain_water/trap_water.c +++ b/0042_trapping_rain_water/trap_water.c @@ -1,6 +1,31 @@ #include #include +#if 0 +static int trap(int* height, int heightSize) +{ + int i, res = 0; + int *lmax = malloc(heightSize * sizeof(int)); + int *rmax = malloc(heightSize * sizeof(int)); + + lmax[0] = height[0]; + rmax[heightSize - 1] = height[heightSize - 1]; + + for (i = 1; i < heightSize; i++) { + lmax[i] = height[i] > lmax[i - 1] ? height[i] : lmax[i - 1] ; + } + + for (i = heightSize - 2; i >= 0; i--) { + rmax[i] = height[i] > rmax[i + 1] ? height[i] : rmax[i + 1] ; + } + + for (i = 1; i < heightSize - 1; i++) { + res += (lmax[i] < rmax[i] ? lmax[i] : rmax[i] ) - height[i]; + } + + return res; +} +#endif static int trap(int* height, int heightSize) { @@ -10,20 +35,18 @@ static int trap(int* height, int heightSize) int res = 0; int l = 0, lmax = 0; int r = heightSize - 1, rmax = 0; + while (l < r) { - if (height[l] < height[r]) { - if (height[l] > lmax) { - lmax = height[l]; - } else { - res += lmax - height[l]; - } + /* lmax is the highest in height[0...l] and + * rmax is the highest in height[r...size - 1] + */ + lmax = height[l] > lmax ? height[l] : lmax; + rmax = height[r] > rmax ? height[r] : rmax; + if (lmax < rmax) { + res += lmax - height[l]; l++; } else { - if (height[r] > rmax) { - rmax = height[r]; - } else { - res += rmax - height[r]; - } + res += rmax - height[r]; r--; } } diff --git a/0042_trapping_rain_water/trap_water.cc b/0042_trapping_rain_water/trap_water.cc index 42be139..5649a61 100644 --- a/0042_trapping_rain_water/trap_water.cc +++ b/0042_trapping_rain_water/trap_water.cc @@ -9,23 +9,20 @@ class Solution { * water level of the position would be determined by the opposite side. */ int res = 0; - int left = 0, left_max = 0; - int right = height.size() - 1, right_max = 0; - while (left < right) { - if (height[left] < height[right]) { - if (height[left] > left_max) { - left_max = height[left]; - } else { - res += left_max - height[left]; - } - left++; + int l = 0, l_max = 0; + int r = height.size() - 1, r_max = 0; + + while (l < r) { + // lmax is the highest in height[0...l] and + // rmax is the highest in height[r...size - 1] + l_max = max(height[l], l_max); + r_max = max(height[r], r_max); + if (l_max < r_max) { + res += l_max - height[l]; + l++; } else { - if (height[right] > right_max) { - right_max = height[right]; - } else { - res += right_max - height[right]; - } - right--; + res += r_max - height[r]; + r--; } } diff --git a/0045_jump_game_ii/jump_game.c b/0045_jump_game_ii/jump_game.c index d315766..0d9ffb2 100644 --- a/0045_jump_game_ii/jump_game.c +++ b/0045_jump_game_ii/jump_game.c @@ -1,6 +1,7 @@ #include #include + static inline int max(int a, int b) { return a > b ? a : b; @@ -8,19 +9,21 @@ static inline int max(int a, int b) static int jump(int* nums, int numsSize) { - int i, lo = 0, hi = 0; + int i, right = 0; int steps = 0; - while (hi < numsSize - 1) { - int right = 0; - for (i = lo; i <= hi; i++) { - /* Assume right > hi for the purpose of the problem */ - right = max(i + nums[i], right); + int fartest = 0; + /* 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) { + right = fartest; + steps++; } - /* [lo, hi] is the next location range */ - lo = hi + 1; - hi = right; - steps++; } + return steps; } diff --git a/0045_jump_game_ii/jump_game.cc b/0045_jump_game_ii/jump_game.cc index 77e6f2f..cf61281 100644 --- a/0045_jump_game_ii/jump_game.cc +++ b/0045_jump_game_ii/jump_game.cc @@ -6,17 +6,18 @@ class Solution { public: int jump(vector& nums) { int steps = 0; - int lo = 0, hi = 0; - while (hi < nums.size() - 1) { - int right = 0; - for (int i = lo; i <= hi; i++) { - // right > hi for nums[i] > 0 - right = max(i + nums[i], right); + int right = 0; + int farthest = 0; + // 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++) { + right = max(i + nums[i], right); + if (i == farthest) { + farthest = right; + steps++; } - // [lo, hi] is the next location range - lo = hi + 1; - hi = right; - steps++; } return steps; diff --git a/0046_permutations/permutations.c b/0046_permutations/permutations.c index 38968d4..49b0b73 100644 --- a/0046_permutations/permutations.c +++ b/0046_permutations/permutations.c @@ -41,16 +41,18 @@ static void dfs(int *nums, int size, bool *used, int *stack, memcpy(results[*count], stack, size * sizeof(int)); col_size[*count] = size; (*count)++; - } else { - /* Reverse order is allowed in different levels, always starts from [0] */ - for (i = 0; i < size; i++) { - if (!used[i]) { - /* Used marks only allows remaining elements in DFS levels */ - used[i] = true; - stack[len] = nums[i]; - dfs(nums, size, used, stack, len + 1, results, count, col_size); - used[i] = false; - } + return; + } + + /* Reverse order is allowed in different levels, always starts from [0] */ + for (i = 0; i < size; i++) { + if (!used[i]) { + /* Used marks all the allowable remaining elements in the next DFS + * levels */ + stack[len] = nums[i]; + used[i] = true; + dfs(nums, size, used, stack, len + 1, results, count, col_size); + used[i] = false; } } } @@ -58,9 +60,9 @@ static void dfs(int *nums, int size, bool *used, int *stack, /** * Return an array of arrays of size *returnSize. * The sizes of the arrays are returned as *returnColumnSizes array. - * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). + * Note: Both returned array and *returnColumnSizes array must be malloced, assume caller calls free(). */ -static int** permute(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) +int** permute(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) { int count = 0, cap = 5000; int **results = malloc(cap * sizeof(int *)); @@ -86,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/0046_permutations/permutations.cc b/0046_permutations/permutations.cc index 2f33cab..35b4efe 100644 --- a/0046_permutations/permutations.cc +++ b/0046_permutations/permutations.cc @@ -6,27 +6,29 @@ class Solution { public: vector> permute(vector& nums) { vector> res; - vector stack; vector used(nums.size()); - dfs(nums, used, stack, res); + dfs(nums, used, res); return res; } private: - void dfs(vector& nums, vector& used, vector& stack, vector>& res) { + vector stack; + void dfs(vector& nums, vector& used, vector>& res) { if (stack.size() == nums.size()) { res.push_back(stack); - } else { - // Reverse order is allowed in different levels, always starts from [0] - for (int i = 0; i < nums.size(); i++) { - if (!used[i]) { - // Used marks only allows remaining elements in DFS levels - used[i] = true; - stack.push_back(nums[i]); - dfs(nums, used, stack, res); - stack.pop_back(); - used[i] = false; - } + return; + } + + // Reverse order is allowed in different levels, always starts from [0] + for (int i = 0; i < nums.size(); i++) { + if (!used[i]) { + // Used marks all the allowable remaining elements in the next + // DFS levels + used[i] = true; + stack.push_back(nums[i]); + dfs(nums, used, res); + stack.pop_back(); + used[i] = false; } } } diff --git a/0047_permutations_ii/permutations.c b/0047_permutations_ii/permutations.c index a666bdc..612867b 100644 --- a/0047_permutations_ii/permutations.c +++ b/0047_permutations_ii/permutations.c @@ -12,25 +12,29 @@ static void dfs(int *nums, int size, bool *used, int *stack, int len, int **results, int *count, int *col_size) { int i; + if (len == size) { results[*count] = malloc(len * sizeof(int)); memcpy(results[*count], stack, len * sizeof(int)); col_size[*count] = size; (*count)++; - } else { - /* Reverse order is allowed in different levels, always starts from [0] */ - for (i = 0; i < size; i++) { - /* Used marks only allows remaining elements in DFS levels */ - if (!used[i]) { - if (i > 0 && !used[i - 1] && nums[i - 1] == nums[i]) { - /* In case that duplicate permutation with same elemements but in different postions */ - continue; - } - used[i] = true; - stack[len] = nums[i]; - dfs(nums, size, used, stack, len + 1, results, count, col_size); - used[i] = false; + return; + } + + /* Reverse order is allowed in different levels, always starts from [0] */ + for (i = 0; i < size; i++) { + /* used marks remaining allowable elements in the next DFS level */ + if (!used[i]) { + if (i > 0 && !used[i - 1] && nums[i - 1] == nums[i]) { + /* !used[i - 1] means the upper DFS level does not contain + * nums[i - 1] such that we need to exclude the duplicate + * enumeration that has been recorded with used[i - 1]==true. */ + continue; } + stack[len] = nums[i]; + used[i] = true; + dfs(nums, size, used, stack, len + 1, results, count, col_size); + used[i] = false; } } } @@ -68,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/0047_permutations_ii/permutations.cc b/0047_permutations_ii/permutations.cc index 389df2b..de8bdff 100644 --- a/0047_permutations_ii/permutations.cc +++ b/0047_permutations_ii/permutations.cc @@ -6,28 +6,30 @@ class Solution { public: vector> permuteUnique(vector& nums) { vector> res; - vector stack; vector used(nums.size()); sort(nums.begin(), nums.end()); - dfs(nums, used, stack, res); + dfs(nums, used, res); return res; } private: - void dfs(vector& nums, vector& used, vector& stack, vector>& res) { + vector stack; + void dfs(vector& nums, vector& used, vector>& res) { if (stack.size() == nums.size()) { res.push_back(stack); } else { for (int i = 0; i < nums.size(); i++) { - // Used marks only allows remaining elements in DFS levels + // used marks remaining allowable elements in the next DFS level if (!used[i]) { if (i > 0 && !used[i - 1] && nums[i - 1] == nums[i]) { - // In case that duplicate permutation with same elemements but in different postions + // !used[i - 1] means the upper DFS level does not contain + // nums[i - 1] such that we need to exclude the duplicate + // enumeration that has been recorded with used[i-1]==true. continue; } - used[i] = true; stack.push_back(nums[i]); - dfs(nums, used, stack, res); + used[i] = true; + dfs(nums, used, res); stack.pop_back(); used[i] = false; } diff --git a/0048_rotate_image/rotate.cc b/0048_rotate_image/rotate.cc index e1e9950..806e151 100644 --- a/0048_rotate_image/rotate.cc +++ b/0048_rotate_image/rotate.cc @@ -15,6 +15,6 @@ class Solution { matrix[size - 1 - i][size - 1 - j] = matrix[j][size - 1 - i]; matrix[j][size - 1 - i] = tmp; } - } + } } }; diff --git a/0049_group_anagrams/anagrams.c b/0049_group_anagrams/anagrams.c index 52d5bb0..fb9765f 100644 --- a/0049_group_anagrams/anagrams.c +++ b/0049_group_anagrams/anagrams.c @@ -29,7 +29,7 @@ static inline int BKDRHash(char *s, size_t size) ** The sizes of the arrays are returned as *returnColumnSizes array. ** Note: Both returned array and *returnColumnSizes array must be malloced, assume caller calls free(). **/ -static char*** groupAnagrams(char** strs, int strsSize, int* returnSize, int** returnColumnSizes) +char*** groupAnagrams(char** strs, int strsSize, int* returnSize, int** returnColumnSizes) { int i, j, count = 0; int hash_size = strsSize; @@ -72,10 +72,10 @@ static char*** groupAnagrams(char** strs, int strsSize, int* returnSize, int** r int main(int argc, char **argv) { - int *column_sizes, count = 0, i, j; - char ***lists = groupAnagrams(argv + 1, argc - 1, &count, &column_sizes); + int *col_sizes, count = 0, i, j; + char ***lists = groupAnagrams(argv + 1, argc - 1, &count, &col_sizes); for (i = 0; i < count; i++) { - for (j = 0; j < column_sizes[i]; j++) { + for (j = 0; j < col_sizes[i]; j++) { printf("%s ", lists[i][j]); } printf("\n"); diff --git a/0049_group_anagrams/anagrams.cc b/0049_group_anagrams/anagrams.cc index c90a7f6..0090531 100644 --- a/0049_group_anagrams/anagrams.cc +++ b/0049_group_anagrams/anagrams.cc @@ -9,14 +9,14 @@ class Solution { unordered_map> ht; for (const auto& str : strs) { int counts[26] = { 0 }; - for (const auto& s : str) { - counts[s - 'a']++; + for (char c : str) { + counts[c - 'a']++; } string key; - for (const auto& c : counts) { + for (int i : counts) { key.push_back('#'); - key.push_back(c + '0'); + key.push_back(i + '0'); } ht[key].push_back(str); diff --git a/0050_pow/pow.c b/0050_pow/pow.c index ce98a46..065e92f 100644 --- a/0050_pow/pow.c +++ b/0050_pow/pow.c @@ -2,7 +2,8 @@ #include #include -static double fast_pow(double x, int n) + +double fast_pow(double x, int n) { if (n == 0) { return 1.0; } if (n == 1) { return x; } @@ -10,7 +11,7 @@ static double fast_pow(double x, int n) return n & 1 ? t * t * x : t * t; } -static double my_pow(double x, int n) +double my_pow(double x, int n) { if (n == INT_MIN) { double t = 1 / fast_pow(x, -(n / 2)); diff --git a/0051_n_queens/n_queens.c b/0051_n_queens/n_queens.c index e2ba9a3..5892c12 100644 --- a/0051_n_queens/n_queens.c +++ b/0051_n_queens/n_queens.c @@ -73,7 +73,7 @@ static void dfs(int n, int row, int *stack, char ***solutions, int *count, int * /** * Return an array of arrays of size *returnSize. * The sizes of the arrays are returned as *returnColumnSizes array. - * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). + * Note: Both returned array and *returnColumnSizes array must be malloced, assume caller calls free(). */ char *** solveNQueens(int n, int* returnSize, int** returnColumnSizes) { diff --git a/0054_spiral_matrix/spiral_matrix.c b/0054_spiral_matrix/spiral_matrix.c index be53988..5ae413f 100644 --- a/0054_spiral_matrix/spiral_matrix.c +++ b/0054_spiral_matrix/spiral_matrix.c @@ -1,10 +1,11 @@ #include #include + /** ** Note: The returned array must be malloced, assume caller calls free(). **/ -static int* spiralOrder(int** matrix, int matrixSize, int *matrixColSize, int *returnSize) +int* spiralOrder(int** matrix, int matrixSize, int *matrixColSize, int *returnSize) { if (matrixSize == 0) { *returnSize = 0; diff --git a/0054_spiral_matrix/spiral_matrix.cc b/0054_spiral_matrix/spiral_matrix.cc index f155dc3..b411d33 100644 --- a/0054_spiral_matrix/spiral_matrix.cc +++ b/0054_spiral_matrix/spiral_matrix.cc @@ -5,17 +5,12 @@ using namespace std; class Solution { public: vector spiralOrder(vector>& matrix) { - if (matrix.empty()) { - return vector(); - } - + vector res; int hor_top = 0; - int hor_bottom = matrix.size(); + int hor_bottom = matrix.size() - 1; int ver_left = 0; - int ver_right = matrix[0].size(); + int ver_right = matrix[0].size() - 1; int direction = 0; - vector res; - while (hor_top <= hor_bottom && ver_left <= ver_right) { switch (direction) { case 0: diff --git a/0056_merge_intervals/merge_intervals.c b/0056_merge_intervals/merge_intervals.c index e9570d5..133a778 100644 --- a/0056_merge_intervals/merge_intervals.c +++ b/0056_merge_intervals/merge_intervals.c @@ -11,7 +11,7 @@ static int compare(const void *a, const void *b) /** * Return an array of arrays of size *returnSize. * The sizes of the arrays are returned as *returnColumnSizes array. - * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). + * Note: Both returned array and *returnColumnSizes array must be malloced, assume caller calls free(). */ int** merge(int** intervals, int intervalsSize, int* intervalsColSize, int* returnSize, int** returnColumnSizes) { diff --git a/0057_insert_interval/insert_interval.c b/0057_insert_interval/insert_interval.c index c0f7c9d..b97da9a 100644 --- a/0057_insert_interval/insert_interval.c +++ b/0057_insert_interval/insert_interval.c @@ -10,9 +10,10 @@ static int compare(const void *a, const void *b) /** * Return an array of arrays of size *returnSize. * The sizes of the arrays are returned as *returnColumnSizes array. - * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). + * Note: Both returned array and *returnColumnSizes array must be malloced, assume caller calls free(). */ -int** insert(int** intervals, int intervalsSize, int* intervalsColSize, int* newInterval, int newIntervalSize, int* returnSize, int** returnColumnSizes) +int** insert(int** intervals, int intervalsSize, int* intervalsColSize, int* newInterval, + int newIntervalSize, int* returnSize, int** returnColumnSizes) { int i, len = 0; int *tmp = malloc((intervalsSize + 1) * 2 * sizeof(int)); diff --git a/0058_length_of_last_word/word_length.c b/0058_length_of_last_word/word_length.c index b18cec9..bad2085 100644 --- a/0058_length_of_last_word/word_length.c +++ b/0058_length_of_last_word/word_length.c @@ -1,18 +1,20 @@ #include #include +#include int lengthOfLastWord(char *s) { - int len = 0; - while (*s != '\0') { - if (s[-1] == ' ' && s[0] != ' ') { - len = 1; - } else if (*s != ' ') { - len++; - } - s++; + int word_len = 0; + int len = strlen(s); + + while (len > 0 && s[--len] == ' ') {} + + while (len >= 0 && s[len] != ' ') { + word_len++; + len--; } - return len; + + return word_len; } int main(int argc, char **argv) diff --git a/0059_spiral_matrix_ii/spiral_matrix.c b/0059_spiral_matrix_ii/spiral_matrix.c index 18da9e0..d4c5339 100644 --- a/0059_spiral_matrix_ii/spiral_matrix.c +++ b/0059_spiral_matrix_ii/spiral_matrix.c @@ -5,9 +5,9 @@ /** * Return an array of arrays of size *returnSize. * The sizes of the arrays are returned as *returnColumnSizes array. - * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). + * Note: Both returned array and *returnColumnSizes array must be malloced, assume caller calls free(). */ -static int** generateMatrix(int n, int* returnSize, int** returnColumnSizes) +int** generateMatrix(int n, int* returnSize, int** returnColumnSizes) { int i; int **matrix = malloc(n * sizeof(int *)); diff --git a/0059_spiral_matrix_ii/spiral_matrix.cc b/0059_spiral_matrix_ii/spiral_matrix.cc new file mode 100644 index 0000000..47d658a --- /dev/null +++ b/0059_spiral_matrix_ii/spiral_matrix.cc @@ -0,0 +1,47 @@ +#include + +using namespace std; + +class Solution { +public: + vector> generateMatrix(int n) { + vector> matrix(n, vector(n)); + int direction = 0; + int hor_top = 0; + int hor_bottom = n - 1; + int ver_left = 0; + int ver_right = n - 1; + int num = 0; + while (num < n * n) { + switch (direction) { + case 0: + for (int i = ver_left; i <= ver_right; i++) { + matrix[hor_top][i] = ++num; + } + hor_top++; + break; + case 1: + for (int i = hor_top; i <= hor_bottom; i++) { + matrix[i][ver_right] = ++num; + } + ver_right--; + break; + case 2: + for (int i = ver_right; i >= ver_left; i--) { + matrix[hor_bottom][i] = ++num; + } + hor_bottom--; + break; + case 3: + for (int i = hor_bottom; i >= hor_top; i--) { + matrix[i][ver_left] = ++num; + } + ver_left++; + break; + } + direction++; + direction %= 4; + } + return matrix; + } +}; diff --git a/0061_rotate_list/rotate_list.c b/0061_rotate_list/rotate_list.c index 9f8eb56..ae77398 100644 --- a/0061_rotate_list/rotate_list.c +++ b/0061_rotate_list/rotate_list.c @@ -1,31 +1,29 @@ #include #include + struct ListNode { int val; struct ListNode *next; }; -static struct ListNode* rotateRight(struct ListNode* head, int k) +struct ListNode* rotateRight(struct ListNode* head, int k) { - if (head == NULL || k <= 0) { + if (head == NULL) { return head; } + int len = 0; struct ListNode dummy; dummy.next = head; - struct ListNode *prev = &dummy; - struct ListNode *p = head; - int len = 0; - while (p != NULL) { - prev = p; - p = p->next; + struct ListNode *tail = &dummy; + while (tail->next != NULL) { + tail = tail->next; len++; } - struct ListNode *last = prev; - prev = &dummy; - p = head; + struct ListNode *prev = &dummy; + struct ListNode *p = head; len = len - (k % len); while (len-- > 0) { prev = p; @@ -36,23 +34,22 @@ static struct ListNode* rotateRight(struct ListNode* head, int k) /* deletion */ prev->next = NULL; /* insertion */ - last->next = dummy.next; - dummy.next = p; + tail->next = head; + head = p; } - return dummy.next; + return head; } int main(int argc, char **argv) { - int i; - struct ListNode *p, *prev, dummy, *list; - if (argc < 2) { fprintf(stderr, "Usage: ./test k n1 n2...\n"); exit(-1); } + int i; + struct ListNode *p, *prev, dummy, *list; dummy.next = NULL; prev = &dummy; for (i = 2; i < argc; i++) { diff --git a/0061_rotate_list/rotate_list.cc b/0061_rotate_list/rotate_list.cc new file mode 100644 index 0000000..e533c21 --- /dev/null +++ b/0061_rotate_list/rotate_list.cc @@ -0,0 +1,48 @@ +#include + +using namespace std; + +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode() : val(0), next(nullptr) {} + * ListNode(int x) : val(x), next(nullptr) {} + * ListNode(int x, ListNode *next) : val(x), next(next) {} + * }; + */ +class Solution { +public: + ListNode* rotateRight(ListNode* head, int k) { + if (head == nullptr) { + return head; + } + + int len = 0; + ListNode dummy; + dummy.next = head; + ListNode *tail = &dummy; + while (tail->next != nullptr) { + len++; + tail = tail->next; + } + + ListNode *prev = &dummy; + ListNode *p = head; + k = k % len; + for (int i = 0; i < len - k; i++) { + prev = p; + p = p->next; + } + + if (p != nullptr) { + /* deletion */ + prev->next = tail->next; + /* insertion */ + tail->next = head; + head = p; + } + return head; + } +}; diff --git a/0066_plus_one/plus_one.c b/0066_plus_one/plus_one.c index 4f6005c..a613f37 100644 --- a/0066_plus_one/plus_one.c +++ b/0066_plus_one/plus_one.c @@ -11,9 +11,15 @@ static int* plusOne(int* digits, int digitsSize, int* returnSize) int i, j, len = 0, carry = 1; int *result = malloc((digitsSize + 1) * sizeof(int)); for (i = digitsSize - 1; i >= 0 || carry; i--) { - int n = digits[i] + carry; - result[len++] = n % 10; - carry = n / 10; + if(i >= 0){ + int n = digits[i] + carry; + result[len++] = n % 10; + carry = n / 10; + } else { + // add case like [9] + result[len++] = 1; + carry = 0; + } } for (i = 0, j = len - 1; i < j; i++, j--) { diff --git a/0069_sqrt/sqrt.c b/0069_sqrt/sqrt.c index 08cc5bd..70a8411 100644 --- a/0069_sqrt/sqrt.c +++ b/0069_sqrt/sqrt.c @@ -51,26 +51,29 @@ static double mySqrt(double n) } #endif -static int mySqrt(int x) +int mySqrt(int x) { if (x == 0) { return 0; } - unsigned int left = 1; - unsigned int right = (unsigned int) x; - unsigned int mid = left + (right - left) / 2; + 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) { - right = mid; + hi = mid; } else { if (mid + 1 > x/(mid + 1)) { break; } else { - left = mid; + lo = mid; } } - mid = left + (right - left) / 2; + mid = lo + (hi - lo) / 2; } return mid; diff --git a/0069_sqrt/sqrt.cc b/0069_sqrt/sqrt.cc new file mode 100644 index 0000000..40445ce --- /dev/null +++ b/0069_sqrt/sqrt.cc @@ -0,0 +1,32 @@ +#include + +using namespace std; + +class Solution { +public: + int mySqrt(int x) { + if (x == 0) { + return 0; + } + + 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; + } else { + if (mid + 1 > x / (mid + 1)) { + break; + } else { + lo = mid; + } + } + mid = (lo + hi) / 2; + } + + return mid; + } +}; diff --git a/0070_climbing_stairs/climb_stairs.c b/0070_climbing_stairs/climb_stairs.c index 3ecc50c..31b1904 100644 --- a/0070_climbing_stairs/climb_stairs.c +++ b/0070_climbing_stairs/climb_stairs.c @@ -2,31 +2,28 @@ #include #include -static int dfs(int n, int *count) +static int dfs(int n, int *steps) { - if (n == 0) { - return 0; - } else if (count[n] > 0) { - return count[n]; + if (n == 1) { + return 1; + } else if (n == 2) { + return 2; + } else if (steps[n] > 0) { + return steps[n]; } else { - if (n >= 1) { - count[n] += dfs(n - 1, count); - } - if (n >= 2) { - count[n] += dfs(n - 2, count); - } - return count[n]; + steps[n] += dfs(n - 1, steps); + steps[n] += dfs(n - 2, steps); + return steps[n]; } } static int climbStairs(int n) { -#if 0 - int *count = malloc((n + 1) * sizeof(int)); - memset(count, 0, (n + 1) * sizeof(int)); - count[1] = 1; - count[2] = 2; - return dfs(n, count); +#if 1 + if (n < 1) return 0; + 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/0072_edit_distance/edit_distance.c b/0072_edit_distance/edit_distance.c index b035609..92f96a8 100644 --- a/0072_edit_distance/edit_distance.c +++ b/0072_edit_distance/edit_distance.c @@ -31,23 +31,25 @@ static inline int min(int a, int b) static int minDistance(char* word1, char* word2) { int i, j; - int len1 = strlen(word1); - int len2 = strlen(word2); - int *table = malloc((len1 + 1) * (len2 + 1) * sizeof(int)); - int **dp = malloc((len1 + 1) * sizeof(int *)); - for (i = 0; i < len1 + 1; i++) { - dp[i] = table + i * (len2 + 1); + int l1 = strlen(word1); + int l2 = strlen(word2); + int *table = malloc((l1 + 1) * (l2 + 1) * sizeof(int)); + int **dp = malloc((l1 + 1) * sizeof(int *)); + + for (i = 0; i < l1 + 1; i++) { + dp[i] = table + i * (l2 + 1); } - for (i = 0; i < len2 + 1; i++) { + dp[0][0] = 0; + for (i = 1; i <= l2; i++) { dp[0][i] = i; } - for (i = 0; i < len1 + 1; i++) { + for (i = 1; i <= l1; i++) { dp[i][0] = i; } - for (i = 1; i < len1 + 1; i++) { - for (j = 1; j < len2 + 1; j++) { + for (i = 1; i <= l1; i++) { + for (j = 1; j <= l2; j++) { if (word1[i - 1] == word2[j - 1]) { dp[i][j] = dp[i - 1][j - 1]; } else { @@ -55,7 +57,8 @@ static int minDistance(char* word1, char* word2) } } } - return dp[len1][len2]; + + return dp[l1][l2]; } int main(int argc, char **argv) diff --git a/0072_edit_distance/edit_distance.cc b/0072_edit_distance/edit_distance.cc index deb09f8..be8543a 100644 --- a/0072_edit_distance/edit_distance.cc +++ b/0072_edit_distance/edit_distance.cc @@ -5,25 +5,28 @@ using namespace std; class Solution { public: int minDistance(string word1, string word2) { - vector> dp; - for (int i = 0; i <= word1.length(); i++) { - dp.push_back(vector(word2.length() + 1)); - dp[i][0] = i; - } - for (int i = 0; i <= word2.length(); i++) { - dp[0][i] = i; + int l1 = word1.length(); + int l2 = word2.length(); + vector dp(l2 + 1); + for (int i = 0; i <= l2; i++) { + dp[i] = i; } - for (int i = 1; i <= word1.length(); i++) { - for (int j = 1; j <= word2.length(); j++) { + int up = 0; + for (int i = 1; i <= l1; i++) { + int left_up = dp[0]; + dp[0] = i; + for (int j = 1; j <= l2; j++) { + up = dp[j]; if (word1[i - 1] == word2[j - 1]) { - dp[i][j] = dp[i - 1][j - 1]; + dp[j] = left_up; } else { - dp[i][j] = 1 + min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1])); + dp[j] = 1 + min(left_up, min(up, dp[j - 1])); } + left_up = up; } } - return dp[word1.length()][word2.length()]; + return dp[l2]; } }; diff --git a/0073_set_matrix_zeroes/set_zero.c b/0073_set_matrix_zeroes/set_zero.c index 7be6a54..b56fd87 100644 --- a/0073_set_matrix_zeroes/set_zero.c +++ b/0073_set_matrix_zeroes/set_zero.c @@ -1,21 +1,23 @@ #include #include -static void setZeroes(int** matrix, int matrixRowSize, int matrixColSize) + +void setZeroes(int** matrix, int matrixSize, int* matrixColSize) { - int row, col, bRow = 0, bCol = 0; - for (row = 0; row < matrixRowSize; row++) { - for (col = 0; col < matrixColSize; col++) { + int row, col; + bool bRow = false, bCol = false; + for (row = 0; row < matrixSize; row++) { + for (col = 0; col < matrixColSize[row]; col++) { if (matrix[row][col] == 0) { - if (row == 0) bCol = 1; - if (col == 0) bRow = 1; + if (row == 0) bRow = true; + if (col == 0) bCol = true; matrix[0][col] = matrix[row][0] = 0; } } } - for (row = 1; row < matrixRowSize; row++) { - for(col = 1; col < matrixColSize; col++){ + for (row = 1; row < matrixSize; row++) { + for(col = 1; col < matrixColSize[row]; col++){ if (matrix[0][col] == 0 || matrix[row][0] == 0) { matrix[row][col] = 0; } @@ -23,14 +25,12 @@ static void setZeroes(int** matrix, int matrixRowSize, int matrixColSize) } if (bRow) { - for(row = 0; row < matrixRowSize; row++) { - matrix[row][0] = 0; - } + memset(matrix[0], 0, matrixColSize[0] * sizeof(int)); } if (bCol) { - for (col = 0; col + +using namespace std; + +public: + void setZeroes(vector>& matrix) { + bool bRow = false, bCol = false; + for (int row = 0; row < matrix.size(); row++) { + for (int col = 0; col < matrix[row].size(); col++) { + if (matrix[row][col] == 0) { + if (row == 0) { bRow = true; } + if (col == 0) { bCol = true; } + matrix[0][col] = matrix[row][0] = 0; + } + } + } + + for (int row = 1; row < matrix.size(); row++) { + for (int col = 1; col < matrix[row].size(); col++) { + if (matrix[0][col] == 0 || matrix[row][0] == 0) { + matrix[row][col] = 0; + } + } + } + + if (bRow) { + for (auto& m : matrix[0]) { + m = 0; + } + } + + if (bCol) { + for (int row = 0; row < matrix.size(); row++) { + matrix[row][0] = 0; + } + } + } +}; diff --git a/0075_sort_colors/sort_colors.c b/0075_sort_colors/sort_colors.c index 0791746..290c02d 100644 --- a/0075_sort_colors/sort_colors.c +++ b/0075_sort_colors/sort_colors.c @@ -2,6 +2,7 @@ #include #include + static inline void swap(int *a, int *b) { int tmp = *a; @@ -9,7 +10,7 @@ static inline void swap(int *a, int *b) *b = tmp; } -static void sortColors(int* nums, int numsSize) +void sortColors(int* nums, int numsSize) { int i, j = 0; for (i = 0; i < numsSize; i++) { diff --git a/0075_sort_colors/sort_colors.cc b/0075_sort_colors/sort_colors.cc new file mode 100644 index 0000000..0d8ab5b --- /dev/null +++ b/0075_sort_colors/sort_colors.cc @@ -0,0 +1,34 @@ +#include + +using namespace std; + +class Solution { +public: + void sortColors(vector& nums) { + int i = 0, j = nums.size() - 1; + while (i < j) { + if (nums[i] == 0) { + i++; + continue; + } + if (nums[j] != 0) { + j--; + continue; + } + swap(nums[i], nums[j]); + } + + j = nums.size() - 1; + while (i < j) { + if (nums[i] == 1) { + i++; + continue; + } + if (nums[j] != 1) { + j--; + continue; + } + swap(nums[i], nums[j]); + } + } +}; diff --git a/0076_minimum_window_substring/window_substring.c b/0076_minimum_window_substring/window_substring.c index a9e87ab..cd7f525 100644 --- a/0076_minimum_window_substring/window_substring.c +++ b/0076_minimum_window_substring/window_substring.c @@ -2,36 +2,47 @@ #include #include + +/* sliding window pattern + * while (r < size) { + * // check target condition + * while (target_condition) { + * // calculate minimum length + * // iterate left indicator + * } + * // iterate right indicator + * } + */ static char *minWindow(char *s, char *t) { int i, j, count[256] = { 0 }; int slen = strlen(s); int tlen = strlen(t); + /* edges of sliding window */ + int l = 0, r = 0; + int min_len = slen + 1; + int start = 0; + int len = 0; + for (i = 0; i < tlen; i++) { count[t[i]]++; } - /* edges of sliding window */ - int lo = 0, hi = 0; - int min_len = slen + 1; - int start = 0; - int chars_to_meet = tlen; - while (hi < slen) { - if (--count[s[hi++]] >= 0) { + while (r < slen) { + if (--count[s[r++]] >= 0) { /* pattern found */ - chars_to_meet--; + len++; } - while (chars_to_meet == 0) { - if (hi - lo < min_len) { - min_len = hi - lo; - start = lo; + while (len >= tlen) { + if (r - l < min_len) { + min_len = r - l; + start = l; } /* Chars with negative count are not included in the pattern string */ - if (++count[s[lo++]] > 0) { - /* chars_to_meet == 1 */ - chars_to_meet++; + if (++count[s[l++]] > 0) { + len--; } } } @@ -42,8 +53,7 @@ static char *minWindow(char *s, char *t) memcpy(result, s + start, min_len); result[min_len] = '\0'; } else { - result = malloc(1); - result[0] = '\0'; + result = ""; } return result; 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/0077_combinations/combinations.c b/0077_combinations/combinations.c index d184521..2ef84f7 100644 --- a/0077_combinations/combinations.c +++ b/0077_combinations/combinations.c @@ -3,6 +3,7 @@ #include #include + static void dfs(int n, int k, int start, int *stack, int len, int **results, int *count, int *col_sizes) { @@ -23,16 +24,14 @@ static void dfs(int n, int k, int start, int *stack, int len, /** * Return an array of arrays of size *returnSize. * The sizes of the arrays are returned as *returnColumnSizes array. - * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). + * Note: Both returned array and *returnColumnSizes array must be malloced, assume caller calls free(). */ int** combine(int n, int k, int* returnSize, int** returnColumnSizes) { int capacity = 10000; - int count = 0; int **results = malloc(capacity * sizeof(int *)); int *stack = malloc(k * sizeof(int)); *returnColumnSizes = malloc(capacity * sizeof(int)); - dfs(n, k, 1, stack, 0, results, &count, *returnColumnSizes); - *returnSize = count; + dfs(n, k, 1, stack, 0, results, returnSize, *returnColumnSizes); return results; } @@ -43,8 +42,15 @@ int main(int argc, char **argv) exit(-1); } + int n = atoi(argv[1]); + int k = atoi(argv[2]); + if (k > n) { + fprintf(stderr, "n(=%d) must larger than k(=%d)\n", n, k); + exit(-1); + } + int i, j, *col_sizes, count = 0; - int **lists = combine(atoi(argv[1]), atoi(argv[2]), &count, &col_sizes); + int **lists = combine(n, k, &count, &col_sizes); for (i = 0; i < count; i++) { for (j = 0; j < col_sizes[i]; j++) { printf("%d ", lists[i][j]); diff --git a/0077_combinations/combinations.cc b/0077_combinations/combinations.cc index 7687061..1aabf42 100644 --- a/0077_combinations/combinations.cc +++ b/0077_combinations/combinations.cc @@ -6,19 +6,19 @@ class Solution { public: vector> combine(int n, int k) { vector> res; - vector stack; - dfs(n, k, 1, stack, res); + dfs(n, k, 1, res); return res; } private: - void dfs(int n, int k, int start, vector& stack, vector>& res) { + vector stack; + void dfs(int n, int k, int start, vector>& res) { if (stack.size() == k) { res.push_back(stack); } else { for (int i = start; i <= n; i++) { stack.push_back(i); - dfs(n, k, i + 1, stack, res); + dfs(n, k, i + 1, res); stack.pop_back(); } } diff --git a/0078_subsets/subsets.c b/0078_subsets/subsets.c index a98cfcf..aeb75b1 100644 --- a/0078_subsets/subsets.c +++ b/0078_subsets/subsets.c @@ -2,33 +2,34 @@ #include #include -static void dfs(int *nums, int size, int start, int *buf, + +static void dfs(int *nums, int size, int start, int *stack, int len, int **sets, int *count, int *sizes) { int i; sets[*count] = malloc(len * sizeof(int)); - memcpy(sets[*count], buf, len * sizeof(int)); + memcpy(sets[*count], stack, len * sizeof(int)); sizes[*count] = len; (*count)++; for (i = start; i < size; i++) { - buf[len] = nums[i]; - dfs(nums, size, i + 1, buf, len + 1, sets, count, sizes); + stack[len] = nums[i]; + dfs(nums, size, i + 1, stack, len + 1, sets, count, sizes); } } /** ** Return an array of arrays of size *returnSize. ** The sizes of the arrays are returned as *returnColumnSizes array. - ** Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). + ** Note: Both returned array and *returnColumnSizes array must be malloced, assume caller calls free(). **/ int** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) { int capacity = 5000; int **sets = malloc(capacity * sizeof(int *)); - int *buf = malloc(numsSize * sizeof(int)); + int *stack = malloc(numsSize * sizeof(int)); *returnColumnSizes = malloc(capacity * sizeof(int)); *returnSize = 0; - dfs(nums, numsSize, 0, buf, 0, sets, returnSize, *returnColumnSizes); + dfs(nums, numsSize, 0, stack, 0, sets, returnSize, *returnColumnSizes); return sets; } diff --git a/0078_subsets/subsets.cc b/0078_subsets/subsets.cc index 5d10d7e..c6593d2 100644 --- a/0078_subsets/subsets.cc +++ b/0078_subsets/subsets.cc @@ -6,17 +6,17 @@ class Solution { public: vector> subsets(vector& nums) { vector> res; - vector stack; - dfs(nums, 0, stack, res); + dfs(nums, 0, res); return res; } private: - void dfs(vector& nums, int start, vector& stack, vector>& res) { + vector stack; + void dfs(vector& nums, int start, vector>& res) { res.push_back(stack); for (int i = start; i < nums.size(); i++) { stack.push_back(nums[i]); - dfs(nums, i + 1, stack, res); + dfs(nums, i + 1, res); stack.pop_back(); } } diff --git a/0083_remove_duplicates_from_sorted_list/rm_dup.c b/0083_remove_duplicates_from_sorted_list/rm_dup.c index f5b7c7f..e8d7d4a 100644 --- a/0083_remove_duplicates_from_sorted_list/rm_dup.c +++ b/0083_remove_duplicates_from_sorted_list/rm_dup.c @@ -1,3 +1,4 @@ +#include #include #include @@ -9,16 +10,19 @@ struct ListNode { struct ListNode* deleteDuplicates(struct ListNode* head) { - struct ListNode *p, *q; - p = q = head; - while (p != NULL) { - while (q != NULL && q->val == p->val) { - q = q->next; + struct ListNode dummy; + struct ListNode *prev = &dummy; + dummy.val = INT_MIN; + + while (head != NULL) { + if (prev->val != head->val) { + prev->next = head; + prev = head; } - p->next = q; - p = q; + head = head->next; } - return head; + prev->next = head; + return dummy.next; } int main(int argc, char **argv) diff --git a/0084_largest_rectangle_in_histogram/rect_in_histogram.c b/0084_largest_rectangle_in_histogram/rect_in_histogram.c index 49116ff..4e302ad 100644 --- a/0084_largest_rectangle_in_histogram/rect_in_histogram.c +++ b/0084_largest_rectangle_in_histogram/rect_in_histogram.c @@ -3,33 +3,33 @@ static int largestRectangleArea(int* heights, int heightsSize) { - int *indexes = malloc(heightsSize * sizeof(int)); - int *left = malloc(heightsSize * sizeof(int)); - int *right = malloc(heightsSize * sizeof(int)); + int *idx_stk = malloc(heightsSize * sizeof(int)); + int *lmax = malloc(heightsSize * sizeof(int)); + int *rmax = malloc(heightsSize * sizeof(int)); int i, pos = 0; for (i = 0; i < heightsSize; i++) { - /* monotonous increasing stack */ - while (pos > 0 && heights[indexes[pos - 1]] >= heights[i]) { + /* keep monotonous increasing stack */ + while (pos > 0 && heights[i] < heights[idx_stk[pos - 1]]) { pos--; } - left[i] = pos == 0 ? -1 : indexes[pos - 1]; - indexes[pos++] = i; + lmax[i] = pos == 0 ? -1 : idx_stk[pos - 1]; + idx_stk[pos++] = i; } pos = 0; for (i = heightsSize - 1; i >= 0; i--) { - /* monotonous increasing stack */ - while (pos > 0 && heights[indexes[pos - 1]] >= heights[i]) { + /* keep monotonous increasing stack */ + while (pos > 0 && heights[i] < heights[idx_stk[pos - 1]]) { pos--; } - right[i] = pos == 0 ? heightsSize : indexes[pos - 1]; - indexes[pos++] = i; + rmax[i] = pos == 0 ? heightsSize : idx_stk[pos - 1]; + idx_stk[pos++] = i; } int max_area = 0; for (i = 0; i < heightsSize; i++) { - int area = heights[i] * (right[i] - left[i] - 1); + int area = heights[i] * (rmax[i] - lmax[i] - 1); max_area = area > max_area ? area : max_area; } diff --git a/0085_maximal_rectangle/maximal_rectangle.c b/0085_maximal_rectangle/maximal_rectangle.c index c33ad1c..3f620c3 100644 --- a/0085_maximal_rectangle/maximal_rectangle.c +++ b/0085_maximal_rectangle/maximal_rectangle.c @@ -10,49 +10,49 @@ static inline int max(int a, int b) static int area_calc(int *heights, int size) { - int *indexes = malloc(size * sizeof(int)); - int *lhist = malloc(size * sizeof(int)); - int *rhist = malloc(size * sizeof(int)); + int *idx_stk = malloc(size * sizeof(int)); + int *lmax = malloc(size * sizeof(int)); + int *rmax = malloc(size * sizeof(int)); int i, pos = 0; for (i = 0; i < size; i++) { - /* squeeze to keep monotonous increasing histograms */ - while (pos > 0 && heights[indexes[pos - 1]] >= heights[i]) { + /* keep monotonous increasing maxograms */ + while (pos > 0 && heights[i] < heights[idx_stk[pos - 1]]) { pos--; } - lhist[i] = pos == 0 ? -1 : indexes[pos - 1]; - indexes[pos++] = i; + lmax[i] = pos == 0 ? -1 : idx_stk[pos - 1]; + idx_stk[pos++] = i; } pos = 0; for (i = size - 1; i >= 0; i--) { - /* squeeze to keep monotonous increasing histograms */ - while (pos > 0 && heights[indexes[pos - 1]] >= heights[i]) { + /* keep monotonous increasing maxograms */ + while (pos > 0 && heights[i] < heights[idx_stk[pos - 1]]) { pos--; } - rhist[i] = pos == 0 ? size : indexes[pos - 1]; - indexes[pos++] = i; + rmax[i] = pos == 0 ? size : idx_stk[pos - 1]; + idx_stk[pos++] = i; } int max_area = 0; for (i = 0; i < size; i++) { - int area = heights[i] * (rhist[i] - lhist[i] - 1); + int area = heights[i] * (rmax[i] - lmax[i] - 1); max_area = max(area, max_area); } return max_area; } -static int maximalRectangle(char** matrix, int matrixRowSize, int matrixColSize) +static int maximalRectangle(char** matrix, int matrixSize, int* matrixColSize) { int i, j, max_area = 0; - int *heights = malloc(matrixColSize * sizeof(int)); - memset(heights, 0, matrixColSize * sizeof(int)); - for (i = 0; i < matrixRowSize; i++) { - for (j = 0; j < matrixColSize; j++) { + int *heights = malloc(matrixColSize[0] * sizeof(int)); + memset(heights, 0, matrixColSize[0] * sizeof(int)); + for (i = 0; i < matrixSize; i++) { + for (j = 0; j < matrixColSize[i]; j++) { heights[j] = matrix[i][j] == '1' ? heights[j] + 1 : 0; } - max_area = max(max_area, area_calc(heights, matrixColSize)); + max_area = max(max_area, area_calc(heights, matrixColSize[i])); } return max_area; } @@ -68,9 +68,11 @@ int main(int argc, char **argv) int i, j; int row_size = argc - 1; int col_size = strlen(argv[1]); + int *cols = malloc(row_size * sizeof(int)); for (i = 0; i < row_size; i++) { + cols[i] = strlen(argv[1]); printf("%s\n", argv[i + 1]); } - printf("%d\n", maximalRectangle(argv + 1, argc - 1, strlen(argv[1]))); + printf("%d\n", maximalRectangle(argv + 1, argc - 1, cols)); return 0; } diff --git a/0090_subsets_ii/subsets.cc b/0090_subsets_ii/subsets.cc index f5ae3e9..d6ee1da 100644 --- a/0090_subsets_ii/subsets.cc +++ b/0090_subsets_ii/subsets.cc @@ -6,21 +6,21 @@ class Solution { public: vector> subsetsWithDup(vector& nums) { vector> res; - vector stack; sort(nums.begin(), nums.end()); - dfs(nums, 0, stack, res); + dfs(nums, 0, res); return res; } private: - void dfs(vector& nums, int start, vector& stack, vector>& res) { + vector stack; + void dfs(vector& nums, int start, vector>& res) { res.push_back(stack); int last = INT_MIN; for (int i = start; i < nums.size(); i++) { if (last != nums[i]) { - /* No duplicate candidate elements at same level position */ + /* No duplicate candidate elements in the same level position */ stack.push_back(nums[i]); - dfs(nums, i + 1, stack, res); + dfs(nums, i + 1, res); stack.pop_back(); } last = nums[i]; diff --git a/0105_construct_binary_tree_from_preorder_and_inorder_traversal/binary_tree_build.c b/0105_construct_binary_tree_from_preorder_and_inorder_traversal/binary_tree_build.c index 6162f06..53d4916 100644 --- a/0105_construct_binary_tree_from_preorder_and_inorder_traversal/binary_tree_build.c +++ b/0105_construct_binary_tree_from_preorder_and_inorder_traversal/binary_tree_build.c @@ -1,71 +1,67 @@ #include #include + #define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - (size_t)&(((type *)0)->member))) #define list_entry(ptr, type, member) \ container_of(ptr, type, member) -#define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos; pos = pos->next) +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, __typeof(*pos), member); \ + &(pos)->member != (head); \ + pos = list_entry((pos)->member.next, __typeof(*pos), member)) -struct hlist_node; +struct list_head { + struct list_head *next, *prev; +}; -struct hlist_head { - struct hlist_node *first; +struct TreeNode { + int val; + struct TreeNode *left; + struct TreeNode *right; }; -struct hlist_node { - struct hlist_node *next, **pprev; +struct order_node { + struct list_head link; + int val; + int index; }; -static inline void INIT_HLIST_HEAD(struct hlist_head *h) { - h->first = NULL; +static inline void INIT_LIST_HEAD(struct list_head *list) +{ + list->next = list->prev = list; } -static inline int hlist_empty(struct hlist_head *h) { - return !h->first; +static inline int list_empty(const struct list_head *head) +{ + return (head->next == head); } -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) +static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { - if (h->first != NULL) { - h->first->pprev = &n->next; - } - n->next = h->first; - n->pprev = &h->first; - h->first = n; + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; } -static inline void hlist_del(struct hlist_node *n) +static inline void list_add(struct list_head *_new, struct list_head *head) { - struct hlist_node *next = n->next; - struct hlist_node **pprev = n->pprev; - *pprev = next; - if (next != NULL) { - next->pprev = pprev; - } + __list_add(_new, head, head->next); } -struct TreeNode { - int val; - struct TreeNode *left; - struct TreeNode *right; -}; - -struct order_node { - struct hlist_node node; - int val; - int index; -}; +static inline void list_add_tail(struct list_head *_new, struct list_head *head) +{ + __list_add(_new, head->prev, head); +} -static int find(int num, int size, struct hlist_head *heads) +static int find(int num, int size, struct list_head *heads) { - struct hlist_node *p; + struct order_node *on; int hash = (num < 0 ? -num : num) % size; - hlist_for_each(p, &heads[hash]) { - struct order_node *on = list_entry(p, struct order_node, node); + list_for_each_entry(on, &heads[hash], link) { if (num == on->val) { return on->index; } @@ -74,7 +70,7 @@ static int find(int num, int size, struct hlist_head *heads) } static struct TreeNode *dfs(int *preorder, int pre_low, int pre_high, int *inorder, - int in_low, int in_high, struct hlist_head *in_heads, int size) + int in_low, int in_high, struct list_head *in_heads, int size) { if (in_low > in_high || pre_low > pre_high) { return NULL; @@ -87,21 +83,21 @@ static struct TreeNode *dfs(int *preorder, int pre_low, int pre_high, int *inord return tn; } -static void node_add(int val, int index, int size, struct hlist_head *heads) +static void node_add(int val, int index, int size, struct list_head *heads) { struct order_node *on = malloc(sizeof(*on)); on->val = val; on->index = index; int hash = (val < 0 ? -val : val) % size; - hlist_add_head(&on->node, &heads[hash]); + list_add(&on->link, &heads[hash]); } -static struct TreeNode *buildTree(int *preorder, int preorderSize, int *inorder, int inorderSize) +struct TreeNode *buildTree(int *preorder, int preorderSize, int *inorder, int inorderSize) { int i; - struct hlist_head *in_heads = malloc(inorderSize * sizeof(*in_heads)); + struct list_head *in_heads = malloc(inorderSize * sizeof(*in_heads)); for (i = 0; i < inorderSize; i++) { - INIT_HLIST_HEAD(&in_heads[i]); + INIT_LIST_HEAD(&in_heads[i]); } for (i = 0; i < inorderSize; i++) { node_add(inorder[i], i, inorderSize, in_heads); diff --git a/0106_construct_binary_tree_from_inorder_and_postorder_traversal/binary_tree_build.c b/0106_construct_binary_tree_from_inorder_and_postorder_traversal/binary_tree_build.c index 2edb121..5adb6ab 100644 --- a/0106_construct_binary_tree_from_inorder_and_postorder_traversal/binary_tree_build.c +++ b/0106_construct_binary_tree_from_inorder_and_postorder_traversal/binary_tree_build.c @@ -1,71 +1,67 @@ #include #include + #define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - (size_t)&(((type *)0)->member))) #define list_entry(ptr, type, member) \ container_of(ptr, type, member) -#define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos; pos = pos->next) +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, __typeof(*pos), member); \ + &(pos)->member != (head); \ + pos = list_entry((pos)->member.next, __typeof(*pos), member)) -struct hlist_node; +struct list_head { + struct list_head *next, *prev; +}; -struct hlist_head { - struct hlist_node *first; +struct TreeNode { + int val; + struct TreeNode *left; + struct TreeNode *right; }; -struct hlist_node { - struct hlist_node *next, **prev; +struct order_node { + struct list_head link; + int val; + int index; }; -static inline void INIT_HLIST_HEAD(struct hlist_head *h) { - h->first = NULL; +static inline void INIT_LIST_HEAD(struct list_head *list) +{ + list->next = list->prev = list; } -static inline int hlist_empty(struct hlist_head *h) { - return !h->first; +static inline int list_empty(const struct list_head *head) +{ + return (head->next == head); } -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) +static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { - if (h->first != NULL) { - h->first->prev = &n->next; - } - n->next = h->first; - n->prev = &h->first; - h->first = n; + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; } -static inline void hlist_del(struct hlist_node *n) +static inline void list_add(struct list_head *_new, struct list_head *head) { - struct hlist_node *next = n->next; - struct hlist_node **prev = n->prev; - *prev = next; - if (next != NULL) { - next->prev = prev; - } + __list_add(_new, head, head->next); } -struct TreeNode { - int val; - struct TreeNode *left; - struct TreeNode *right; -}; - -struct order_node { - struct hlist_node node; - int val; - int index; -}; +static inline void list_add_tail(struct list_head *_new, struct list_head *head) +{ + __list_add(_new, head->prev, head); +} -static int find(int num, int size, struct hlist_head *heads) +static int find(int num, int size, struct list_head *heads) { - struct hlist_node *p; + struct order_node *on; int hash = (num < 0 ? -num : num) % size; - hlist_for_each(p, &heads[hash]) { - struct order_node *on = list_entry(p, struct order_node, node); + list_for_each_entry(on, &heads[hash], link) { if (num == on->val) { return on->index; } @@ -73,17 +69,17 @@ static int find(int num, int size, struct hlist_head *heads) return -1; } -static void node_add(int val, int index, int size, struct hlist_head *heads) +static void node_add(int val, int index, int size, struct list_head *heads) { struct order_node *on = malloc(sizeof(*on)); on->val = val; on->index = index; int hash = (val < 0 ? -val : val) % size; - hlist_add_head(&on->node, &heads[hash]); + list_add(&on->link, &heads[hash]); } static struct TreeNode *dfs(int *inorder, int in_lo, int in_hi, int *postorder, - int post_lo, int post_hi, struct hlist_head *in_heads, int size) + int post_lo, int post_hi, struct list_head *in_heads, int size) { if (in_lo > in_hi || post_lo > post_hi) { return NULL; @@ -96,12 +92,12 @@ static struct TreeNode *dfs(int *inorder, int in_lo, int in_hi, int *postorder, return tn; } -static struct TreeNode *buildTree(int *inorder, int inorderSize, int *postorder, int postorderSize) +struct TreeNode *buildTree(int *inorder, int inorderSize, int *postorder, int postorderSize) { int i; - struct hlist_head *in_heads = malloc(inorderSize * sizeof(*in_heads)); + struct list_head *in_heads = malloc(inorderSize * sizeof(*in_heads)); for (i = 0; i < inorderSize; i++) { - INIT_HLIST_HEAD(&in_heads[i]); + INIT_LIST_HEAD(&in_heads[i]); } for (i = 0; i < inorderSize; i++) { node_add(inorder[i], i, inorderSize, in_heads); diff --git a/0107_binary_tree_level_order_traversal_ii/bst_bfs.c b/0107_binary_tree_level_order_traversal_ii/bst_bfs.c index 564ae71..2464fbf 100644 --- a/0107_binary_tree_level_order_traversal_ii/bst_bfs.c +++ b/0107_binary_tree_level_order_traversal_ii/bst_bfs.c @@ -2,7 +2,6 @@ #include #include -#define BST_MAX_LEVEL 800 struct TreeNode { int val; @@ -29,9 +28,9 @@ static void bfs(struct TreeNode *root, int **results, int *count, int *col_sizes /** ** Return an array of arrays of size *returnSize. ** The sizes of the arrays are returned as *returnColumnSizes array. - ** Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). + ** Note: Both returned array and *returnColumnSizes array must be malloced, assume caller calls free(). **/ -static int** levelOrderBottom(struct TreeNode* root, int* returnSize, int** returnColumnSizes) +int** levelOrderBottom(struct TreeNode* root, int* returnSize, int** returnColumnSizes) { if (root == NULL) { *returnSize = 0; @@ -40,9 +39,9 @@ static int** levelOrderBottom(struct TreeNode* root, int* returnSize, int** retu int size = 1; *returnSize = 0; - int **results = malloc(BST_MAX_LEVEL * sizeof(int *)); - *returnColumnSizes = malloc(BST_MAX_LEVEL * sizeof(int)); - memset(*returnColumnSizes, 0, BST_MAX_LEVEL * sizeof(int)); + int **results = malloc(800 * sizeof(int *)); + *returnColumnSizes = malloc(800 * sizeof(int)); + memset(*returnColumnSizes, 0, 800 * sizeof(int)); bfs(root, results, returnSize, *returnColumnSizes, &size, 0); int i, j; diff --git a/0109_convert_sorted_list_to_binary_search_tree/bst_convert.c b/0109_convert_sorted_list_to_binary_search_tree/bst_convert.c index c79f239..88434f0 100644 --- a/0109_convert_sorted_list_to_binary_search_tree/bst_convert.c +++ b/0109_convert_sorted_list_to_binary_search_tree/bst_convert.c @@ -1,6 +1,7 @@ #include #include + struct ListNode { int val; struct ListNode *next; @@ -12,26 +13,29 @@ struct TreeNode { struct TreeNode *right; }; -static struct TreeNode *traverse(int *nums, int lo, int hi) +static struct TreeNode *dfs(struct ListNode **head, int lo, int hi) { + if (lo > hi) { + return NULL; + } + int mid = lo + (hi - lo) / 2; struct TreeNode *node = malloc(sizeof(*node)); - node->val = nums[mid]; - node->left = mid > lo ? traverse(nums, lo, mid - 1) : NULL; - node->right = mid < hi ? traverse(nums, mid + 1, hi) : NULL; + node->left = dfs(head, lo, mid - 1); + node->val = (*head)->val; + (*head) = (*head)->next; + node->right = dfs(head, mid + 1, hi); return node; } -static struct TreeNode *sortedListToBST(struct ListNode *head) +static struct TreeNode* sortedListToBST(struct ListNode* head) { - int i, nums[10000]; - for (i = 0; head != NULL; head = head->next, i++) { - nums[i] = head->val; - } - if (i == 0) { - return NULL; + struct ListNode *p; + int len = 0; + for (p = head; p != NULL; p = p->next) { + len++; } - return traverse(nums, 0, i - 1); + return dfs(&head, 0, len - 1); } int main(int argc, char **argv) diff --git a/0109_convert_sorted_list_to_binary_search_tree/bst_convert.cc b/0109_convert_sorted_list_to_binary_search_tree/bst_convert.cc new file mode 100644 index 0000000..8f840af --- /dev/null +++ b/0109_convert_sorted_list_to_binary_search_tree/bst_convert.cc @@ -0,0 +1,49 @@ +#include + +using namespace std; + +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode() : val(0), next(nullptr) {} + * ListNode(int x) : val(x), next(nullptr) {} + * ListNode(int x, ListNode *next) : val(x), next(next) {} + * }; + */ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode() : val(0), left(nullptr), right(nullptr) {} + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} + * }; + */ +class Solution { +public: + TreeNode *sortedListToBST(ListNode* head) { + if (head == nullptr) { + return NULL; + } else if (head->next == nullptr) { + return new TreeNode(head->val); + } else { + ListNode *fast = head; + ListNode *slow = head; + ListNode *last = slow; + while (fast != nullptr && fast->next != nullptr) { + last = slow; + slow = slow->next; + fast = fast->next->next; + } + last->next = nullptr; + TreeNode *node = new TreeNode(slow->val); + node->left = sortedListToBST(head); + node->right = sortedListToBST(slow->next); + return node; + } + } +}; diff --git a/0113_path_sum_ii/path_sum.c b/0113_path_sum_ii/path_sum.c index 43071cc..cb52c2f 100644 --- a/0113_path_sum_ii/path_sum.c +++ b/0113_path_sum_ii/path_sum.c @@ -2,6 +2,7 @@ #include #include + struct TreeNode { int val; struct TreeNode *left; @@ -25,7 +26,12 @@ static void dfs(struct TreeNode *node, int sum, int *stack, int len, int **resul } } -static int **pathSum(struct TreeNode *root, int sum, int **columnSizes, int *returnSize) +/** + * 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(). + */ +int **pathSum(struct TreeNode *root, int sum, int *returnSize, int **returnColumnSizes) { if (root == NULL) { *returnSize = 0; @@ -35,8 +41,8 @@ static int **pathSum(struct TreeNode *root, int sum, int **columnSizes, int *ret int level = 5000, cap = 1000; int *stack = malloc(level * sizeof(int)); int **results = malloc(cap * sizeof(int *)); - *columnSizes = malloc(cap * sizeof(int)); - dfs(root, sum, stack, 0, results, *columnSizes, returnSize); + *returnColumnSizes = malloc(cap * sizeof(int)); + dfs(root, sum, stack, 0, results, *returnColumnSizes, returnSize); return results; } @@ -76,13 +82,14 @@ int main(int argc, char **argv) n3[7].right = NULL; int i, j, count = 0; - int *sizes; - int **list = pathSum(&root, 22, &sizes, &count); + int *col_sizes, sum = 22; + int **list = pathSum(&root, sum, &count, &col_sizes); for (i = 0; i < count; i++) { - for (j = 0; j < sizes[i]; j++) { + for (j = 0; j < col_sizes[i]; j++) { printf("%d ", list[i][j]); } printf("\n"); } + return 0; } diff --git a/0113_path_sum_ii/path_sum.cc b/0113_path_sum_ii/path_sum.cc new file mode 100644 index 0000000..64b24a1 --- /dev/null +++ b/0113_path_sum_ii/path_sum.cc @@ -0,0 +1,39 @@ +#include + +using namespace std; + +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode() : val(0), left(nullptr), right(nullptr) {} + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} + * }; + */ +class Solution { +public: + vector> pathSum(TreeNode* root, int targetSum) { + vector> res; + dfs(root, targetSum, res); + return res; + } +private: + vector stack; + void dfs(TreeNode* root, int sum, vector>& res) { + if (root == nullptr) { + return; + } else if (root->left == nullptr && root->right == nullptr && sum == root->val) { + stack.push_back(root->val); + res.push_back(stack); + stack.pop_back(); + } else { + stack.push_back(root->val); + dfs(root->left, sum - root->val, res); + dfs(root->right, sum - root->val, res); + stack.pop_back(); + } + } +}; diff --git a/0116_populating_next_right_pointers_in_each_node/connect.c b/0116_populating_next_right_pointers_in_each_node/connect.c index 728a0be..16fbfe3 100644 --- a/0116_populating_next_right_pointers_in_each_node/connect.c +++ b/0116_populating_next_right_pointers_in_each_node/connect.c @@ -1,33 +1,35 @@ #include #include -struct TreeLinkNode { + +struct Node { int val; - struct TreeLinkNode *left; - struct TreeLinkNode *right; - struct TreeLinkNode *next; + struct Node *left; + struct Node *right; + struct Node *next; }; -static void connect(struct TreeLinkNode *root) +struct Node* connect(struct Node *root) { if (root == NULL) { - return; + return root; } - struct TreeLinkNode *head = root; + struct Node *head = root; while (head->left != NULL) { - struct TreeLinkNode *p; + struct Node *p; for (p = head; p != NULL; p = p->next) { p->left->next = p->right; p->right->next = p->next == NULL ? NULL : p->next->left; } head = head->left; } + return root; } int main(int argc, char **argv) { - struct TreeLinkNode root, n1[2], n2[4], n3[8]; + struct Node root, n1[2], n2[4], n3[8]; root.val = 5; n1[0].val = 4; n1[1].val = 8; diff --git a/0116_populating_next_right_pointers_in_each_node/connect.cc b/0116_populating_next_right_pointers_in_each_node/connect.cc new file mode 100644 index 0000000..1222b9d --- /dev/null +++ b/0116_populating_next_right_pointers_in_each_node/connect.cc @@ -0,0 +1,41 @@ +#include + +using namespace std; + +/* +// Definition for a Node. +class Node { +public: + int val; + Node* left; + Node* right; + Node* next; + + Node() : val(0), left(NULL), right(NULL), next(NULL) {} + + Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {} + + Node(int _val, Node* _left, Node* _right, Node* _next) + : val(_val), left(_left), right(_right), next(_next) {} +}; +*/ + +class Solution { +public: + Node* connect(Node* root) { + if (root == nullptr) { + return root; + } + + if (root->left != nullptr) { + root->left->next = root->right; + } + Node *next = root->next; + if (root->right != nullptr && next != nullptr) { + root->right->next = next->left; + } + connect(root->left); + connect(root->right); + return root; + } +}; diff --git a/0118_pascal_triangle/pascal_triangle.c b/0118_pascal_triangle/pascal_triangle.c index 99de1c1..7dee4c4 100644 --- a/0118_pascal_triangle/pascal_triangle.c +++ b/0118_pascal_triangle/pascal_triangle.c @@ -1,19 +1,20 @@ #include #include + /** - ** Return an arrahi of arrahis. - ** The sizes of the arrahis are returned as *columnSizes arrahi. - ** Note: Both returned arrahi and *columnSizes arrahi must be malloced, assume caller calls free(). - **/ -static int** generate(int numRows, int** columnSizes) + * 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(). + */ +int** generate(int numRows, int *returnSize, int** returnColumnSizes) { int i, j; int **triangle = malloc(numRows * sizeof(int *)); - *columnSizes = malloc(numRows * sizeof(int *)); + *returnColumnSizes = malloc(numRows * sizeof(int *)); for (i = 0; i < numRows; i++) { int num = i + 1; - (*columnSizes)[i] = num; + (*returnColumnSizes)[i] = num; triangle[i] = malloc(num * sizeof(int)); triangle[i][0] = 1; triangle[i][num - 1] = 1; @@ -21,6 +22,7 @@ static int** generate(int numRows, int** columnSizes) triangle[i][j] = triangle[i - 1][j - 1] + triangle[i - 1][j]; } } + *returnSize = numRows; return triangle; } @@ -30,10 +32,12 @@ int main(int argc, char **argv) fprintf(stderr, "Usage: ./test n\n"); exit(-1); } - int i, j, *sizes, row = atoi(argv[1]); - int **triangle = generate(row, &sizes); + + int i, j, count, *col_sizes; + int row = atoi(argv[1]); + int **triangle = generate(row, &count, &col_sizes); for (i = 0; i < row; i++) { - for (j = 0; j < sizes[i]; j++) { + for (j = 0; j < col_sizes[i]; j++) { printf("%d ", triangle[i][j]); } printf("\n"); diff --git a/0120_triangle/triangle.c b/0120_triangle/triangle.c index 7df14cc..bcf9875 100644 --- a/0120_triangle/triangle.c +++ b/0120_triangle/triangle.c @@ -5,33 +5,33 @@ static int dfs(int** triangle, int row_size, int *col_sizes, - int row, int col, int **sums, bool **passes) + int row, int col, int **sums, bool **passed) { if (row == row_size - 1) { return triangle[row][col]; - } else if (passes[row][col]) { + } else if (passed[row][col]) { return sums[row][col]; } else { - int s1 = dfs(triangle, row_size, col_sizes, row + 1, col, sums, passes); - int s2 = dfs(triangle, row_size, col_sizes, row + 1, col + 1, sums, passes); + int s1 = dfs(triangle, row_size, col_sizes, row + 1, col, sums, passed); + int s2 = dfs(triangle, row_size, col_sizes, row + 1, col + 1, sums, passed); sums[row][col] = triangle[row][col] + (s1 < s2 ? s1 : s2); /* Set pass marks in backtracing as the paths are overlapped */ - passes[row][col] = true; + passed[row][col] = true; return sums[row][col]; } } -static int minimumTotal(int** triangle, int triangleSize, int *triangleColSizes) +int minimumTotal(int** triangle, int triangleSize, int *triangleColSizes) { int i; int **sums = malloc(triangleSize * sizeof(int *)); - bool **passes = malloc(triangleSize * sizeof(bool *)); + bool **passed = malloc(triangleSize * sizeof(bool *)); for (i = 0; i < triangleSize; i++) { - passes[i] = malloc(triangleColSizes[i]); - memset(passes[i], false, triangleColSizes[i]); + passed[i] = malloc(triangleColSizes[i]); + memset(passed[i], false, triangleColSizes[i]); sums[i] = malloc(triangleColSizes[i] * sizeof(int)); } - return dfs(triangle, triangleSize, triangleColSizes, 0, 0, sums, passes); + return dfs(triangle, triangleSize, triangleColSizes, 0, 0, sums, passed); } int main(void) diff --git a/0120_triangle/triangle.cc b/0120_triangle/triangle.cc new file mode 100644 index 0000000..9ecd64b --- /dev/null +++ b/0120_triangle/triangle.cc @@ -0,0 +1,30 @@ +#include + +using namespace std; + +class Solution { +public: + int minimumTotal(vector>& triangle) { + for (auto & t : triangle) { + passed.push_back(vector(t.size(), false)); + sums.push_back(vector(t.size())); + } + return dfs(triangle, 0, 0); + } +private: + vector> passed; + vector> sums; + int dfs(vector>& triangle, int row, int col) { + if (row == triangle.size() - 1) { + return triangle[row][col]; + } else if (passed[row][col]) { + return sums[row][col]; + } else { + int s1 = dfs(triangle, row + 1, col); + int s2 = dfs(triangle, row + 1, col + 1); + sums[row][col] = triangle[row][col] + (s1 < s2 ? s1 : s2); + passed[row][col] = true; + return sums[row][col]; + } + } +}; diff --git a/0123_best_time_to_buy_and_sell_stock_iii/stock.c b/0123_best_time_to_buy_and_sell_stock_iii/stock.c index c0e38ef..55172db 100644 --- a/0123_best_time_to_buy_and_sell_stock_iii/stock.c +++ b/0123_best_time_to_buy_and_sell_stock_iii/stock.c @@ -53,7 +53,7 @@ static int maxProfit(int* prices, int pricesSize) int total = left_profit[pricesSize - 1]; for (i = pricesSize - 2; i >= 0; i--) { if (prices[i] > max) { - max = prices[i]; + max = prices[i]; } else { tmp = max - prices[i]; right_profit = tmp > right_profit ? tmp : right_profit; diff --git a/0123_best_time_to_buy_and_sell_stock_iii/stock.cc b/0123_best_time_to_buy_and_sell_stock_iii/stock.cc new file mode 100644 index 0000000..3be2669 --- /dev/null +++ b/0123_best_time_to_buy_and_sell_stock_iii/stock.cc @@ -0,0 +1,42 @@ +#include + +using namespace std; + +class Solution { +public: + int maxProfit(vector& prices) { + if (prices.size() == 0) { + return 0; + } + + int max_diff = 0; + int min_price = prices[0]; + vector left_profits(prices.size()); + for (int i = 1; i < prices.size(); i++) { + if (prices[i] < min_price) { + min_price = prices[i]; + } else { + int diff = prices[i] - min_price; + max_diff = max(diff, max_diff); + } + left_profits[i] = max_diff; + } + + int total = 0; + max_diff = 0; + int right_profit = 0; + int max_price = prices[prices.size() - 1]; + for (int i = prices.size() - 2; i >= 0; i--) { + if (prices[i] > max_price) { + max_price = prices[i]; + } else { + int diff = max_price - prices[i]; + right_profit = max(diff, right_profit); + } + int profit = left_profits[i] + right_profit; + total = max(profit, total); + } + + return total; + } +}; diff --git a/0126_word_ladder_ii/word_ladder.c b/0126_word_ladder_ii/word_ladder.c index d0980e0..9efc70f 100644 --- a/0126_word_ladder_ii/word_ladder.c +++ b/0126_word_ladder_ii/word_ladder.c @@ -1,7 +1,9 @@ +#include #include #include #include + #define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - (size_t)&(((type *)0)->member))) @@ -9,18 +11,26 @@ container_of(ptr, type, member) #define list_first_entry(ptr, type, field) list_entry((ptr)->next, type, field) -#define list_last_entry(ptr, type, field) list_entry((ptr)->prev, type, field) - -#define list_for_each(p, head) \ - for (p = (head)->next; p != (head); p = p->next) -#define list_for_each_safe(p, n, head) \ - for (p = (head)->next, n = p->next; p != (head); p = n, n = p->next) +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, __typeof(*pos), member); \ + &(pos)->member != (head); \ + pos = list_entry((pos)->member.next, __typeof(*pos), member)) struct list_head { struct list_head *next, *prev; }; +struct word_node { + char *word; + struct list_head node; + struct list_head sibling; + struct list_head link; + int par_num; + int step; + struct word_node *parents[]; +}; + static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list->prev = list; @@ -61,22 +71,6 @@ static inline void list_del(struct list_head *entry) entry->next = entry->prev = NULL; } -struct word_node { - int step; - char *word; - struct list_head node; -}; - -struct word_tree { - char *word; - struct list_head sibling; - struct list_head link; - struct word_tree **parents; - int par_num; - int par_cap; - int step; -}; - static int BKDRHash(char* str, int size) { int seed = 131; // 31 131 1313 13131 131313 etc.. @@ -87,12 +81,11 @@ static int BKDRHash(char* str, int size) return hash % size; } -static struct word_node *find(char *word, struct list_head *hheads, int size, int step) +static struct word_node *find(char *word, struct list_head *dict, int size, int step) { - struct list_head *p; + struct word_node *node; int hash = BKDRHash(word, size); - list_for_each(p, &hheads[hash]) { - struct word_node *node = list_entry(p, struct word_node, node); + list_for_each_entry(node, &dict[hash], node) { if (!strcmp(node->word, word)) { if (node->step == 0 || node->step == step) { return node; @@ -102,101 +95,95 @@ static struct word_node *find(char *word, struct list_head *hheads, int size, in return NULL; } -static void parent_add(struct word_tree *parent, struct word_tree *child) -{ - if (child->par_num + 1 > child->par_cap) { - child->par_cap *= 2; - struct word_tree **parents = malloc(child->par_cap * sizeof(void *)); - memcpy(parents, child->parents, child->par_num * sizeof(void *)); - free(child->parents); - child->parents = parents; - } - child->parents[child->par_num++] = parent; -} - /** ** 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(). **/ -static char*** findLadders(char* beginWord, char* endWord, char** wordList, int wordListSize, int* returnSize, int** returnColumnSizes) +char*** findLadders(char* beginWord, char* endWord, char** wordList, int wordListSize, int* returnSize, int** returnColumnSizes) { - int i, j, k; - int len = strlen(beginWord); + int i, word_len = strlen(beginWord); int hashsize = wordListSize * 2; - char *word = malloc(len + 1); + char *word = malloc(word_len + 1); - struct list_head *hheads = malloc(hashsize * sizeof(*hheads)); + struct list_head *dict = malloc(hashsize * sizeof(*dict)); for (i = 0; i < hashsize; i++) { - INIT_LIST_HEAD(hheads + i); + INIT_LIST_HEAD(dict + i); } - struct list_head *level_heads = malloc(wordListSize * sizeof(*level_heads)); + struct list_head *level_caches = malloc(wordListSize * sizeof(*level_caches)); for (i = 0; i < wordListSize; i++) { - INIT_LIST_HEAD(&level_heads[i]); + INIT_LIST_HEAD(&level_caches[i]); } - /* Add into hash list */ - struct word_node *node; + /* Word dictionary */ + *returnSize = 0; + bool found = false; + struct word_node *node, *wn; for (i = 0; i < wordListSize; i++) { node = malloc(sizeof(*node)); node->word = wordList[i]; node->step = 0; int hash = BKDRHash(wordList[i], hashsize); - list_add(&node->node, &hheads[hash]); + list_add(&node->node, &dict[hash]); + if (!strcmp(endWord, wordList[i])) { + found = true; + } + } + if (!found) { + return NULL; } /* FIFO */ - struct list_head *p, queue; + struct list_head queue; INIT_LIST_HEAD(&queue); /* Build tree structure for BFS */ - struct word_tree *root = malloc(sizeof(*root)); + struct word_node *root = malloc(sizeof(*root) + sizeof(void *)); root->word = beginWord; root->step = 1; - root->par_cap = 1; root->par_num = 1; - root->parents = malloc(sizeof(void *)); root->parents[0] = NULL; - list_add_tail(&root->sibling, &level_heads[0]); - node = find(beginWord, hheads, hashsize, 1); + list_add_tail(&root->sibling, &level_caches[0]); + node = find(beginWord, dict, hashsize, 1); if (node != NULL) { node->step = 1; } - /* BFS with FIFO for shortest path */ - struct word_tree *first = root; + /* BFS with FIFO queue for shortest path */ + struct word_node *first = root; while (strcmp(first->word, endWord)) { strcpy(word, first->word); - for (i = 0; i < len; i++) { + for (i = 0; i < word_len; i++) { char c; char o = word[i]; for (c = 'a'; c <= 'z'; c++) { + if (c == o) continue; word[i] = c; - node = find(word, hheads, hashsize, first->step + 1); + node = find(word, dict, hashsize, first->step + 1); if (node != NULL) { int enqueue = 1; - list_for_each(p, &level_heads[first->step]) { - struct word_tree *w = list_entry(p, struct word_tree, sibling); - if (!strcmp(w->word, node->word)) { + /* Search in level cache in case of duplication */ + list_for_each_entry(wn, &level_caches[first->step], sibling) { + /* Here we could just check if they are the same reference */ + if (wn->word == node->word) { enqueue = 0; /* record the parant relation */ - parent_add(first, w); + wn->parents[wn->par_num++] = first; break; } } if (enqueue) { + /* new level cache and enqueue */ node->step = first->step + 1; - struct word_tree *new = malloc(sizeof(*new)); + struct word_node *new = malloc(sizeof(*new) + 15 * sizeof(void *)); new->word = node->word; new->step = node->step; - new->par_cap = 10; new->par_num = 0; - new->parents = malloc(new->par_cap * sizeof(void *)); - list_add_tail(&new->sibling, &level_heads[first->step]); + list_add_tail(&new->sibling, &level_caches[first->step]); list_add_tail(&new->link, &queue); - parent_add(first, new); + new->parents[new->par_num++] = first; } } } @@ -204,56 +191,54 @@ static char*** findLadders(char* beginWord, char* endWord, char** wordList, int } if (list_empty(&queue)) { - *returnSize = 0; return NULL; } else { - first = list_first_entry(&queue, struct word_tree, link); + /* dequeue */ + first = list_first_entry(&queue, struct word_node, link); list_del(&first->link); } } - i = 0; int size = first->step; char ***results = malloc(1000 * sizeof(char **)); int *indexes = malloc(size * sizeof(int)); memset(indexes, 0, size * sizeof(int)); - struct word_tree **nodes = malloc(size * sizeof(*nodes)); - list_for_each(p, &level_heads[size - 1]) { - struct word_tree *end = list_entry(p, struct word_tree, sibling); + struct word_node **nodes = malloc(size * sizeof(*nodes)); + struct word_node *end; + list_for_each_entry(end, &level_caches[size - 1], sibling) { if (!strcmp(end->word, endWord)) { int move_on = 1; while (move_on) { move_on = 0; - struct word_tree *w = end; - char **list = results[i] = malloc(size * sizeof(char *)); - for (j = size - 1; j >= 0; j--) { - list[j] = malloc(len + 1); - strcpy(list[j], w->word); - nodes[j] = w; - w = w->parents[indexes[j]]; + wn = end; + char **list = results[*returnSize] = malloc(size * sizeof(char *)); + for (i = size - 1; i >= 0; i--) { + list[i] = malloc(word_len + 1); + strcpy(list[i], wn->word); + nodes[i] = wn; + wn = wn->parents[indexes[i]]; } /* Switch to another branch */ - for (j = 0; j < size; j++) { - if (indexes[j] < nodes[j]->par_num - 1) { - indexes[j]++; - /* Reset indexes of parents */ - memset(indexes, 0, j * sizeof(int)); + for (i = 0; i < size; i++) { + if (indexes[i] < nodes[i]->par_num - 1) { + indexes[i]++; + /* common prefix */ + memset(indexes, 0, i * sizeof(int)); move_on = 1; break; } } - i++; + (*returnSize)++; } } } - *returnColumnSizes = malloc(i * sizeof(int)); - for (j = 0; j < i; j++) { - (*returnColumnSizes)[j] = size; + *returnColumnSizes = malloc(*returnSize * sizeof(int)); + for (i = 0; i < *returnSize; i++) { + (*returnColumnSizes)[i] = size; } - *returnSize = i; return results; } diff --git a/0127_word_ladder/word_ladder.c b/0127_word_ladder/word_ladder.c index 013d081..f057487 100644 --- a/0127_word_ladder/word_ladder.c +++ b/0127_word_ladder/word_ladder.c @@ -1,5 +1,6 @@ #include #include +#include #include #define container_of(ptr, type, member) \ @@ -9,13 +10,11 @@ container_of(ptr, type, member) #define list_first_entry(ptr, type, field) list_entry((ptr)->next, type, field) -#define list_last_entry(ptr, type, field) list_entry((ptr)->prev, type, field) -#define list_for_each(p, head) \ - for (p = (head)->next; p != (head); p = p->next) - -#define list_for_each_safe(p, n, head) \ - for (p = (head)->next, n = p->next; p != (head); p = n, n = p->next) +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, __typeof(*pos), member); \ + &(pos)->member != (head); \ + pos = list_entry((pos)->member.next, __typeof(*pos), member)) struct list_head { struct list_head *next, *prev; @@ -78,12 +77,11 @@ static int BKDRHash(char* str, int size) return hash % size; } -static struct word_node *find(char *word, struct list_head *hheads, int size) +static struct word_node *find(char *word, struct list_head *dict, int size) { - struct list_head *p; + struct word_node *node; int hash = BKDRHash(word, size); - list_for_each(p, &hheads[hash]) { - struct word_node *node = list_entry(p, struct word_node, node); + list_for_each_entry(node, &dict[hash], node) { if (node->step == 0 && !strcmp(node->word, word)) { return node; } @@ -98,18 +96,25 @@ static int ladderLength(char* beginWord, char* endWord, char** wordList, int wor struct list_head queue; struct word_node *node; - struct list_head *hheads = malloc(wordListSize * sizeof(*hheads)); + struct list_head *dict = malloc(wordListSize * sizeof(*dict)); for (i = 0; i < wordListSize; i++) { - INIT_LIST_HEAD(hheads + i); + INIT_LIST_HEAD(dict + i); } /* Add into hash list */ + bool found = false; for (i = 0; i < wordListSize; i++) { node = malloc(sizeof(*node)); node->word = wordList[i]; node->step = 0; int hash = BKDRHash(wordList[i], wordListSize); - list_add(&node->node, &hheads[hash]); + list_add(&node->node, &dict[hash]); + if (!strcmp(endWord, wordList[i])) { + found = true; + } + } + if (!found) { + return 0; } /* FIFO */ @@ -127,8 +132,9 @@ static int ladderLength(char* beginWord, char* endWord, char** wordList, int wor for (c = 'a'; c <= 'z'; c++) { if (c == o) continue; word[i] = c; - node = find(word, hheads, wordListSize); + node = find(word, dict, wordListSize); if (node != NULL) { + /* enqueue */ list_add_tail(&node->link, &queue); node->step = first->step + 1; } @@ -139,6 +145,7 @@ static int ladderLength(char* beginWord, char* endWord, char** wordList, int wor if (list_empty(&queue)) { return 0; } else { + /* dequeue */ first = list_first_entry(&queue, struct word_node, link); list_del(&first->link); } diff --git a/0127_word_ladder/word_ladder.cc b/0127_word_ladder/word_ladder.cc new file mode 100644 index 0000000..f88eaa6 --- /dev/null +++ b/0127_word_ladder/word_ladder.cc @@ -0,0 +1,53 @@ +#include + +using namespace std; + +class Solution { +public: + int ladderLength(string beginWord, string endWord, vector& wordList) { + unordered_set dict(wordList.begin(), wordList.end()); + if (!dict.count(endWord)) { + return 0; + } + + // double BFS + int step = 1; + unordered_set s1, s2, tmp, visited; + s1.insert(beginWord); + s2.insert(endWord); + while (!s1.empty() && !s2.empty()) { + if (s1.size() > s2.size()) { + tmp = s1; + s1 = s2; + s2 = tmp; + } + tmp.clear(); + + for (auto str : s1) { + if (s2.count(str)) { + return step; + } + if (!visited.count(str)) { + visited.insert(str); + } + + for (int i = 0; i < str.length(); i++) { + char o = str[i]; + for (char c = 'a'; c <= 'z'; c++) { + if (c == o) continue; + str[i] = c; + if (dict.count(str) && !visited.count(str)) { + tmp.insert(str); + } + } + str[i] = o; + } + } + + // update + s1 = tmp; + step++; + } + return 0; + } +}; diff --git a/0128_longest_consecutive_sequence/consec_seq.c b/0128_longest_consecutive_sequence/consec_seq.c index 075844e..d42b664 100644 --- a/0128_longest_consecutive_sequence/consec_seq.c +++ b/0128_longest_consecutive_sequence/consec_seq.c @@ -1,69 +1,72 @@ #include #include + #define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - (size_t)&(((type *)0)->member))) #define list_entry(ptr, type, member) \ container_of(ptr, type, member) -#define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos; pos = pos->next) - -#define hlist_for_each_safe(pos, n, head) \ - for (pos = (head)->first; pos && ({ n = pos->next; true; }); pos = n) - -struct hlist_node; +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, __typeof(*pos), member); \ + &(pos)->member != (head); \ + pos = list_entry((pos)->member.next, __typeof(*pos), member)) -struct hlist_head { - struct hlist_node *first; +struct list_head { + struct list_head *next, *prev; }; -struct hlist_node { - struct hlist_node *next, **pprev; +struct seq_node { + int num; + struct list_head link; }; -static inline void INIT_HLIST_HEAD(struct hlist_head *h) +static inline void INIT_LIST_HEAD(struct list_head *list) { - h->first = NULL; + list->next = list->prev = list; } -static inline int hlist_empty(struct hlist_head *h) +static inline int list_empty(const struct list_head *head) { - return !h->first; + return (head->next == head); } -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) +static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { - if (h->first != NULL) { - h->first->pprev = &n->next; - } - n->next = h->first; - n->pprev = &h->first; - h->first = n; + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; } -static inline void hlist_del(struct hlist_node *n) +static inline void list_add(struct list_head *_new, struct list_head *head) { - struct hlist_node *next = n->next; - struct hlist_node **pprev = n->pprev; - *pprev = next; - if (next != NULL) { - next->pprev = pprev; - } + __list_add(_new, head, head->next); } -struct seq_node { - int num; - struct hlist_node node; -}; +static inline void list_add_tail(struct list_head *_new, struct list_head *head) +{ + __list_add(_new, head->prev, head); +} -static struct seq_node *find(int num, int size, struct hlist_head *heads) +static inline void __list_del(struct list_head *entry) { + entry->next->prev = entry->prev; + entry->prev->next = entry->next; +} + +static inline void list_del(struct list_head *entry) +{ + __list_del(entry); + entry->next = entry->prev = NULL; +} + +static struct seq_node *find(int num, int size, struct list_head *heads) +{ + struct seq_node *node; int hash = num < 0 ? -num % size : num % size; - struct hlist_node *pos; - hlist_for_each(pos, &heads[hash]) { - struct seq_node *node = list_entry(pos, struct seq_node, node); + list_for_each_entry(node, &heads[hash], link) { if (node->num == num) { return node; } @@ -71,14 +74,14 @@ static struct seq_node *find(int num, int size, struct hlist_head *heads) return NULL; } -static int longestConsecutive(int* nums, int numsSize) +int longestConsecutive(int* nums, int numsSize) { int i, hash, length = 0; struct seq_node *node; - struct hlist_head *heads = malloc(numsSize * sizeof(*heads)); + struct list_head *heads = malloc(numsSize * sizeof(*heads)); for (i = 0; i < numsSize; i++) { - INIT_HLIST_HEAD(&heads[i]); + INIT_LIST_HEAD(&heads[i]); } for (i = 0; i < numsSize; i++) { @@ -86,31 +89,20 @@ static int longestConsecutive(int* nums, int numsSize) hash = nums[i] < 0 ? -nums[i] % numsSize : nums[i] % numsSize; node = malloc(sizeof(*node)); node->num = nums[i]; - hlist_add_head(&node->node, &heads[hash]); + list_add(&node->link, &heads[hash]); } } for (i = 0; i < numsSize; i++) { - int len = 0; - int num; - node = find(nums[i], numsSize, heads); - while (node != NULL) { - len++; - num = node->num; - hlist_del(&node->node); - - int left = num; - while ((node = find(--left, numsSize, heads)) != NULL) { + /* Find the first consecutive number */ + node = find(nums[i] - 1, numsSize, heads); + if (node == NULL) { + int len = 0; + int num = nums[i]; + while ((node = find(num++, numsSize, heads)) != NULL) { len++; - hlist_del(&node->node); + list_del(&node->link); } - - int right = num; - while ((node = find(++right, numsSize, heads)) != NULL) { - len++; - hlist_del(&node->node); - } - length = len > length ? len : length; } } diff --git a/0128_longest_consecutive_sequence/consec_seq.cc b/0128_longest_consecutive_sequence/consec_seq.cc new file mode 100644 index 0000000..fa264fc --- /dev/null +++ b/0128_longest_consecutive_sequence/consec_seq.cc @@ -0,0 +1,27 @@ +#include + +using namespace std; + +class Solution { +public: + int longestConsecutive(vector& nums) { + int res = 0; + unordered_set s; + for (int i = 0; i < nums.size(); i++) { + s.insert(nums[i]); + } + for (int n : nums) { + if (!s.count(n - 1)) { + int len = 0; + int num = n; + while (s.count(num)) { + s.erase(num); + num++; + len++; + } + res = len > res ? len : res; + } + } + return res; + } +}; diff --git a/0129_sum_root_to_leaf_numbers/sum_tree.c b/0129_sum_root_to_leaf_numbers/sum_tree.c index 686b3d8..8580e8b 100644 --- a/0129_sum_root_to_leaf_numbers/sum_tree.c +++ b/0129_sum_root_to_leaf_numbers/sum_tree.c @@ -1,6 +1,7 @@ #include #include + struct TreeNode { int val; struct TreeNode *left; @@ -9,12 +10,13 @@ struct TreeNode { static int dfs(struct TreeNode* node, int sum) { - int total = 0; + /* Here we have to use pre-order */ + /* sum must be in argument stack of recusion.*/ sum = sum * 10 + node->val; - if (node->left == NULL && node->right == NULL) { return sum; } else { + int total = 0; if (node->left != NULL) { total += dfs(node->left, sum); } @@ -25,7 +27,7 @@ static int dfs(struct TreeNode* node, int sum) } } -static int sumNumbers(struct TreeNode* root) +int sumNumbers(struct TreeNode* root) { if (root == NULL) { return 0; diff --git a/0129_sum_root_to_leaf_numbers/sum_tree.cc b/0129_sum_root_to_leaf_numbers/sum_tree.cc new file mode 100644 index 0000000..5269090 --- /dev/null +++ b/0129_sum_root_to_leaf_numbers/sum_tree.cc @@ -0,0 +1,42 @@ +#include + +using namespace std; + +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode() : val(0), left(nullptr), right(nullptr) {} + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} + * }; + */ +class Solution { +public: + int sumNumbers(TreeNode* root) { + if (root == nullptr) { + return 0; + } + return dfs(root, 0); + } +private: + int dfs(TreeNode *root, int sum) { + // Here we have to use pre-order. + // sum must be in argument stack of recusion. + sum = sum * 10 + root->val; + if (root->left == nullptr && root->right == nullptr) { + return sum; + } else { + int total = 0; + if (root->left != nullptr) { + total += dfs(root->left, sum); + } + if (root->right != nullptr) { + total += dfs(root->right, sum); + } + return total; + } + } +}; diff --git a/0130_surrounded_regions/surrounded_regions.c b/0130_surrounded_regions/surrounded_regions.c index 304b4c7..701f5ed 100644 --- a/0130_surrounded_regions/surrounded_regions.c +++ b/0130_surrounded_regions/surrounded_regions.c @@ -2,6 +2,7 @@ #include #include + #define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - (size_t)&(((type *)0)->member))) @@ -9,18 +10,16 @@ container_of(ptr, type, member) #define list_first_entry(ptr, type, field) list_entry((ptr)->next, type, field) -#define list_last_entry(ptr, type, field) list_entry((ptr)->prev, type, field) - -#define list_for_each(p, head) \ - for (p = (head)->next; p != (head); p = p->next) - -#define list_for_each_safe(p, n, head) \ - for (p = (head)->next, n = p->next; p != (head); p = n, n = p->next) struct list_head { struct list_head *next, *prev; }; +struct node { + int x, y; + struct list_head link; +}; + static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list->prev = list; @@ -61,11 +60,6 @@ static inline void list_del(struct list_head *entry) entry->next = entry->prev = NULL; } -struct node { - struct list_head link; - int x, y; -}; - static struct node *node_new(struct list_head *free_list) { struct node *new; @@ -123,7 +117,7 @@ static void bfs(char **board, int row_size, int col_size, } } -void solve(char** board, int boardRowSize, int boardColSize) +void solve(char** board, int boardSize, int *boardColSize) { int i, j; struct node *new; @@ -132,48 +126,48 @@ void solve(char** board, int boardRowSize, int boardColSize) INIT_LIST_HEAD(&queue); INIT_LIST_HEAD(&free_list); - for (i = 0; i < boardColSize; i++) { + for (i = 0; i < boardColSize[0]; i++) { if (board[0][i] == 'O') { new = node_new(&free_list); new->x = 0; new->y = i; list_add_tail(&new->link, &queue); - bfs(board, boardRowSize, boardColSize, &queue, &free_list); + bfs(board, boardSize, boardColSize[0], &queue, &free_list); } } - for (i = 0; i < boardColSize; i++) { - if (board[boardRowSize - 1][i] == 'O') { + for (i = 0; i < boardColSize[0]; i++) { + if (board[boardSize - 1][i] == 'O') { new = node_new(&free_list); - new->x = boardRowSize - 1; + new->x = boardSize - 1; new->y = i; list_add_tail(&new->link, &queue); - bfs(board, boardRowSize, boardColSize, &queue, &free_list); + bfs(board, boardSize, boardColSize[0], &queue, &free_list); } } - for (i = 0; i < boardRowSize; i++) { + for (i = 0; i < boardSize; i++) { if (board[i][0] == 'O') { new = node_new(&free_list); new->x = i; new->y = 0; list_add_tail(&new->link, &queue); - bfs(board, boardRowSize, boardColSize, &queue, &free_list); + bfs(board, boardSize, boardColSize[i], &queue, &free_list); } } - for (i = 0; i < boardRowSize; i++) { - if (board[i][boardColSize - 1] == 'O') { + for (i = 0; i < boardSize; i++) { + if (board[i][boardColSize[i] - 1] == 'O') { new = node_new(&free_list); new->x = i; - new->y = boardColSize - 1; + new->y = boardColSize[i] - 1; list_add_tail(&new->link, &queue); - bfs(board, boardRowSize, boardColSize, &queue, &free_list); + bfs(board, boardSize, boardColSize[i], &queue, &free_list); } } - for (i = 0; i < boardRowSize; i++) { - for (j = 0; j < boardColSize; j++) { + for (i = 0; i < boardSize; i++) { + for (j = 0; j < boardColSize[i]; j++) { board[i][j] = board[i][j] == 'P' ? 'O' : 'X'; } } @@ -183,33 +177,33 @@ int main(void) { int i, j; int row_size = 5; - int col_size = 5; + int *col_sizes = malloc(row_size * sizeof(int)); char **board = malloc(row_size * sizeof(char *)); - board[0] = malloc(col_size); + board[0] = malloc(row_size); board[0][0] = 'X'; board[0][1] = 'X'; board[0][2] = 'X'; board[0][3] = 'X'; board[0][4] = 'X'; - board[1] = malloc(col_size); + board[1] = malloc(row_size); board[1][0] = 'O'; board[1][1] = 'X'; board[1][2] = 'O'; board[1][3] = 'O'; board[1][4] = 'X'; - board[2] = malloc(col_size); + board[2] = malloc(row_size); board[2][0] = 'O'; board[2][1] = 'O'; board[2][2] = 'X'; board[2][3] = 'O'; board[2][4] = 'X'; - board[3] = malloc(col_size); + board[3] = malloc(row_size); board[3][0] = 'X'; board[3][1] = 'X'; board[3][2] = 'O'; board[3][3] = 'X'; board[3][4] = 'X'; - board[4] = malloc(col_size); + board[4] = malloc(row_size); board[4][0] = 'X'; board[4][1] = 'X'; board[4][2] = 'O'; @@ -217,16 +211,17 @@ int main(void) board[4][4] = 'X'; for (i = 0; i < row_size; i++) { - for (j = 0; j < col_size; j++) { + col_sizes[i] = row_size; + for (j = 0; j < col_sizes[i]; j++) { printf("%c ", board[i][j]); } printf("\n"); } printf("\n"); - solve(board, row_size, col_size); + solve(board, row_size, col_sizes); for (i = 0; i < row_size; i++) { - for (j = 0; j < col_size; j++) { + for (j = 0; j < col_sizes[i]; j++) { printf("%c ", board[i][j]); } printf("\n"); diff --git a/0131_palindrome_patitioning/palindrome_partition.c b/0131_palindrome_patitioning/palindrome_partition.c index cc83084..f871f19 100644 --- a/0131_palindrome_patitioning/palindrome_partition.c +++ b/0131_palindrome_patitioning/palindrome_partition.c @@ -3,6 +3,7 @@ #include #include + struct palindrome { int low; int high; @@ -49,9 +50,9 @@ static void dfs(struct palindrome *pal_set, int num, int start, /** ** Return an array of arrays of size *returnSize. ** The sizes of the arrays are returned as *returnColumnSizes array. - ** Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). + ** Note: Both returned array and *returnColumnSizes array must be malloced, assume caller calls free(). **/ -static char ***partition(char* s, int* returnSize, int** returnColumnSizes) +char ***partition(char* s, int* returnSize, int** returnColumnSizes) { int len = strlen(s); if (len == 0) { diff --git a/0133_clone_graph/clone_graph.c b/0133_clone_graph/clone_graph.c index e6ef47c..1c18389 100644 --- a/0133_clone_graph/clone_graph.c +++ b/0133_clone_graph/clone_graph.c @@ -1,7 +1,6 @@ #include #include -#define NEIGHBORS_MAX_SIZE 100 #define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - (size_t)&(((type *)0)->member))) @@ -9,67 +8,59 @@ #define list_entry(ptr, type, member) \ container_of(ptr, type, member) -#define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos; pos = pos->next) +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, __typeof(*pos), member); \ + &(pos)->member != (head); \ + pos = list_entry((pos)->member.next, __typeof(*pos), member)) -#define hlist_for_each_safe(pos, n, head) \ - for (pos = (head)->first; pos && ({ n = pos->next; true; }); pos = n) - -struct hlist_node; +struct list_head { + struct list_head *next, *prev; +}; -struct hlist_head { - struct hlist_node *first; +struct UndirectedGraphNode { + int label; + struct UndirectedGraphNode *neighbors[100]; + int neighborsCount; }; -struct hlist_node { - struct hlist_node *next, **pprev; +struct label_node { + struct list_head link; + struct UndirectedGraphNode *gn; }; -static inline void INIT_HLIST_HEAD(struct hlist_head *h) { - h->first = NULL; +static inline void INIT_LIST_HEAD(struct list_head *list) +{ + list->next = list->prev = list; } -static inline int hlist_empty(struct hlist_head *h) { - return !h->first; +static inline int list_empty(const struct list_head *head) +{ + return (head->next == head); } -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) +static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { - if (h->first != NULL) { - h->first->pprev = &n->next; - } - n->next = h->first; - n->pprev = &h->first; - h->first = n; + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; } -static inline void hlist_del(struct hlist_node *n) +static inline void list_add(struct list_head *_new, struct list_head *head) { - struct hlist_node *next = n->next; - struct hlist_node **pprev = n->pprev; - *pprev = next; - if (next != NULL) { - next->pprev = pprev; - } + __list_add(_new, head, head->next); } -struct UndirectedGraphNode { - int label; - struct UndirectedGraphNode *neighbors[NEIGHBORS_MAX_SIZE]; - int neighborsCount; -}; - -struct label_node { - struct UndirectedGraphNode *gn; - struct hlist_node node; -}; +static inline void list_add_tail(struct list_head *_new, struct list_head *head) +{ + __list_add(_new, head->prev, head); +} -static struct UndirectedGraphNode *find(int label, int size, struct hlist_head *heads) +static struct UndirectedGraphNode *find(int label, int size, struct list_head *heads) { + struct label_node *ln; int hash = (label < 0 ? -label : label) % size; - struct hlist_node *p; - hlist_for_each(p, &heads[hash]) { - struct label_node *ln = list_entry(p, struct label_node, node); + list_for_each_entry(ln, &heads[hash], link) { if (ln->gn->label == label) { return ln->gn; } @@ -77,7 +68,7 @@ static struct UndirectedGraphNode *find(int label, int size, struct hlist_head * return NULL; } -static struct UndirectedGraphNode *dfs(struct UndirectedGraphNode *graph, struct hlist_head *heads, int size) +static struct UndirectedGraphNode *dfs(struct UndirectedGraphNode *graph, struct list_head *heads, int size) { if (graph == NULL) { return NULL; @@ -94,7 +85,7 @@ static struct UndirectedGraphNode *dfs(struct UndirectedGraphNode *graph, struct struct label_node *ln = malloc(sizeof(*ln)); ln->gn = node; int hash = (node->label < 0 ? -node->label : node->label) % size; - hlist_add_head(&ln->node, &heads[hash]); + list_add(&ln->link, &heads[hash]); int i; for (i = 0; i < node->neighborsCount; i++) { @@ -104,14 +95,13 @@ static struct UndirectedGraphNode *dfs(struct UndirectedGraphNode *graph, struct return node; } -static struct UndirectedGraphNode *cloneGraph(struct UndirectedGraphNode *graph) +struct UndirectedGraphNode *cloneGraph(struct UndirectedGraphNode *graph) { int i, cap = 1000; - struct hlist_head *heads = malloc(cap * sizeof(*heads)); + struct list_head *heads = malloc(cap * sizeof(*heads)); for (i = 0; i < cap; i++) { - INIT_HLIST_HEAD(&heads[i]); + INIT_LIST_HEAD(&heads[i]); } - return dfs(graph, heads, cap); } diff --git a/0135_candy/candy.c b/0135_candy/candy.c index 20721bd..063797d 100644 --- a/0135_candy/candy.c +++ b/0135_candy/candy.c @@ -1,10 +1,12 @@ #include #include -static int candy(int* ratings, int ratingsSize) + +int candy(int* ratings, int ratingsSize) { - if (ratingsSize == 0) return 0; - if (ratingsSize == 1) return 1; + if (ratingsSize == 0) { + return 0; + } int i, *candies = malloc(ratingsSize * sizeof(int)); candies[0] = 1; diff --git a/0135_candy/candy.cc b/0135_candy/candy.cc new file mode 100644 index 0000000..931e407 --- /dev/null +++ b/0135_candy/candy.cc @@ -0,0 +1,24 @@ +#include + +using namespace std; + +class Solution { +public: + int candy(vector& ratings) { + vector candies(ratings.size(), 1); + for (int i = 1; i < ratings.size(); i++) { + if (ratings[i] > ratings[i - 1]) { + candies[i] = candies[i - 1] + 1; + } + } + + int sum = candies[ratings.size() - 1]; + for (int i = ratings.size() - 2; i >= 0; i--) { + if (ratings[i] > ratings[i + 1] && candies[i] <= candies[i + 1]) { + candies[i] = candies[i + 1] + 1; + } + sum += candies[i]; + } + return sum; + } +}; 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/0139_word_break/word_break.c b/0139_word_break/word_break.c index 40992fa..145d99d 100644 --- a/0139_word_break/word_break.c +++ b/0139_word_break/word_break.c @@ -3,162 +3,46 @@ #include #include -#define container_of(ptr, type, member) \ - ((type *)((char *)(ptr) - (size_t)&(((type *)0)->member))) -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -#define list_for_each(p, head) \ - for (p = (head)->next; p != (head); p = p->next) - -#define list_for_each_safe(p, n, head) \ - for (p = (head)->next, n = p->next; p != (head); p = n, n = p->next) - -struct list_head { - struct list_head *next, *prev; -}; - -static inline void INIT_LIST_HEAD(struct list_head *list) -{ - list->next = list->prev = list; -} - -static inline int list_empty(const struct list_head *head) -{ - return (head->next == head); -} - -static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) -{ - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; -} - -static inline void list_add(struct list_head *_new, struct list_head *head) -{ - __list_add(_new, head, head->next); -} - -static inline void list_add_tail(struct list_head *_new, struct list_head *head) -{ - __list_add(_new, head->prev, head); -} - -static inline void __list_del(struct list_head *entry) -{ - entry->next->prev = entry->prev; - entry->prev->next = entry->next; -} - -static inline void list_del(struct list_head *entry) -{ - __list_del(entry); - entry->next = entry->prev = NULL; -} - -struct word_node { - char *word; - struct list_head link; -}; - -struct dfs_cache { - int num; - int cap; - struct list_head **heads; -}; - -static struct dfs_cache *resize(struct dfs_cache **caches, int index) -{ - int i; - struct dfs_cache *cache = caches[index]; - if (cache->num + 1 > cache->cap) { - cache->cap *= 2; - struct list_head **heads = malloc(cache->cap * sizeof(*heads)); - for (i = 0; i < cache->cap; i++) { - if (i < cache->num) { - heads[i] = cache->heads[i]; - } else { - heads[i] = malloc(sizeof(struct list_head)); - INIT_LIST_HEAD(heads[i]); - } - } - free(cache->heads); - cache->heads = heads; - } - - return cache; -} - -static struct dfs_cache *dfs(char *s, char **words, int *sizes, int num, - struct dfs_cache **caches, int index) -{ +static int dfs(char *s, char **words, int *lens, int size, bool *ends, int index) +{ int i, j; - struct word_node *wn; - struct dfs_cache *result; - if (*s == '\0') { - return NULL; - } else if (caches[index] != NULL) { - return caches[index]; + return true; + } else if (!ends[index]) { + return false; } else { - result = malloc(sizeof(*result)); - result->num = 0; - result->cap = 1; - result->heads = malloc(sizeof(struct list_head *)); - result->heads[0] = malloc(sizeof(struct list_head)); - INIT_LIST_HEAD(result->heads[0]); - caches[index] = result; - for (i = 0; i < num; i++) { - if (!memcmp(s, words[i], sizes[i])) { - struct dfs_cache *next = dfs(s + sizes[i], words, sizes, num, caches, index + sizes[i]); - if (next != NULL) { - int k = result->num; - for (j = k; j < k + next->num; j++) { - result = resize(caches, index); - wn = malloc(sizeof(*wn)); - wn->word = words[i]; - list_add(&wn->link, result->heads[j]); - - struct list_head *p; - list_for_each(p, next->heads[j - k]) { - struct word_node *wnn = list_entry(p, struct word_node, link); - wn = malloc(sizeof(*wn)); - wn->word = wnn->word; - list_add_tail(&wn->link, result->heads[j]); - } - result->num++; - } - } else { - return NULL; + for (i = 0; i < size; i++) { + ends[index] = false; + if (!strncmp(s, words[i], lens[i])) { + /* post-order traverse */ + bool ok = dfs(s + lens[i], words, lens, size, ends, index + lens[i]); + if (ok) { + /* string s all matched */ + return true; } } } - return result; + return ends[index]; } } -static bool wordBreak(char* s, char** wordDict, int wordDictSize) +bool wordBreak(char * s, char ** wordDict, int wordDictSize) { if (wordDictSize == 0) { return false; } - int i, total = 0; - int len = strlen(s); - int *sizes = malloc(wordDictSize * sizeof(int)); - + int i, len = strlen(s); + int *lens = malloc(wordDictSize * sizeof(int)); for (i = 0; i < wordDictSize; i++) { - sizes[i] = strlen(wordDict[i]); - total += sizes[i]; + lens[i] = strlen(wordDict[i]); } - struct dfs_cache **caches = malloc(len * sizeof(*caches)); - memset(caches, 0, len * sizeof(*caches)); - return dfs(s, wordDict, sizes, wordDictSize, caches, 0) == NULL; + bool *ends = malloc(len); + memset(ends, true, len); + return dfs(s, wordDict, lens, wordDictSize, ends, 0); } int main(int argc, char **argv) diff --git a/0140_word_break_ii/word_break.c b/0140_word_break_ii/word_break.c index 2813c4f..588bc1e 100644 --- a/0140_word_break_ii/word_break.c +++ b/0140_word_break_ii/word_break.c @@ -2,22 +2,32 @@ #include #include + #define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - (size_t)&(((type *)0)->member))) #define list_entry(ptr, type, member) \ container_of(ptr, type, member) -#define list_for_each(p, head) \ - for (p = (head)->next; p != (head); p = p->next) - -#define list_for_each_safe(p, n, head) \ - for (p = (head)->next, n = p->next; p != (head); p = n, n = p->next) +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, __typeof(*pos), member); \ + &(pos)->member != (head); \ + pos = list_entry((pos)->member.next, __typeof(*pos), member)) struct list_head { struct list_head *next, *prev; }; +struct word_node { + char *word; + struct list_head link; +}; + +struct solution { + int count; + struct list_head heads[]; +}; + static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list->prev = list; @@ -46,107 +56,57 @@ static inline void list_add_tail(struct list_head *_new, struct list_head *head) __list_add(_new, head->prev, head); } -static inline void __list_del(struct list_head *entry) -{ - entry->next->prev = entry->prev; - entry->prev->next = entry->next; -} - -static inline void list_del(struct list_head *entry) -{ - __list_del(entry); - entry->next = entry->prev = NULL; -} - -struct word_node { - char *word; - struct list_head link; -}; - -struct dfs_cache { - int num; - int cap; - struct list_head **heads; -}; - -static struct dfs_cache *resize(struct dfs_cache **caches, int index) +static void new_word_add(struct list_head *head, char *word) { - int i; - struct dfs_cache *cache = caches[index]; - if (cache->num + 1 > cache->cap) { - cache->cap *= 2; - struct list_head **heads = malloc(cache->cap * sizeof(*heads)); - for (i = 0; i < cache->cap; i++) { - if (i < cache->num) { - heads[i] = cache->heads[i]; - } else { - heads[i] = malloc(sizeof(struct list_head)); - INIT_LIST_HEAD(heads[i]); - } - } - free(cache->heads); - cache->heads = heads; - } - - return cache; + struct word_node *wn = malloc(sizeof(*wn)); + wn->word = word; + list_add_tail(&wn->link, head); } -static struct dfs_cache *dfs(char *s, char **words, int *sizes, int num, - struct dfs_cache **caches, int index) +static struct solution *dfs(char *s, char **words, int *lens, int size, + struct solution **sols, int index) { int i, j; - struct word_node *wn; - struct dfs_cache *result; - if (*s == '\0') { return NULL; - } else if (caches[index] != NULL) { - return caches[index]; + } else if (sols[index] != NULL) { + return sols[index]; } else { - result = malloc(sizeof(*result)); - result->num = 0; - result->cap = 1; - result->heads = malloc(sizeof(struct list_head *)); - result->heads[0] = malloc(sizeof(struct list_head)); - INIT_LIST_HEAD(result->heads[0]); - caches[index] = result; - for (i = 0; i < num; i++) { - if (!memcmp(s, words[i], sizes[i])) { - struct dfs_cache *next = dfs(s + sizes[i], words, sizes, num, caches, index + sizes[i]); - if (next != NULL) { - int k = result->num; - for (j = k; j < k + next->num; j++) { - result = resize(caches, index); - wn = malloc(sizeof(*wn)); - wn->word = words[i]; - list_add(&wn->link, result->heads[j]); - - struct list_head *p; - list_for_each(p, next->heads[j - k]) { - struct word_node *wnn = list_entry(p, struct word_node, link); - wn = malloc(sizeof(*wn)); - wn->word = wnn->word; - list_add_tail(&wn->link, result->heads[j]); + struct solution *sol = malloc(sizeof(*sol) + 60 * sizeof(struct list_head)); + sol->count = 0; + sols[index] = sol; + for (i = 0; i < size; i++) { + if (!strncmp(s, words[i], lens[i])) { + /* post-order traverse */ + struct solution *sub_sol = dfs(s + lens[i], words, lens, size, sols, index + lens[i]); + if (sub_sol != NULL) { + int k = sol->count; + for (j = k; j < k + sub_sol->count; j++) { + /* Append all sub-solutions */ + INIT_LIST_HEAD(&sol->heads[j]); + new_word_add(&sol->heads[j], words[i]); + struct word_node *wn; + list_for_each_entry(wn, &sub_sol->heads[j - k], link) { + new_word_add(&sol->heads[j], wn->word); } - result->num++; + sol->count++; } } else { - wn = malloc(sizeof(*wn)); - wn->word = words[i]; - list_add(&wn->link, result->heads[result->num++]); + /* leaf node */ + INIT_LIST_HEAD(&sol->heads[0]); + new_word_add(&sol->heads[sol->count++], words[i]); } } } - - return result; + return sol; } } /** - ** Return an array of size *returnSize. - ** Note: The returned array must be malloced, assume caller calls free(). - **/ -static char **wordBreak(char* s, char** wordDict, int wordDictSize, int *returnSize) + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +char **wordBreak(char* s, char** wordDict, int wordDictSize, int *returnSize) { if (wordDictSize == 0) { *returnSize = 0; @@ -155,25 +115,24 @@ static char **wordBreak(char* s, char** wordDict, int wordDictSize, int *returnS int i, total = 0; int len = strlen(s); - int *sizes = malloc(wordDictSize * sizeof(int)); + int *lens = malloc(wordDictSize * sizeof(int)); /* Add into hash list */ for (i = 0; i < wordDictSize; i++) { - sizes[i] = strlen(wordDict[i]); - total += sizes[i]; + lens[i] = strlen(wordDict[i]); + total += lens[i]; } - struct dfs_cache **caches = malloc(len * sizeof(*caches)); - memset(caches, 0, len * sizeof(*caches)); - struct dfs_cache *cache = dfs(s, wordDict, sizes, wordDictSize, caches, 0); + struct solution **sols = malloc(len * sizeof(void *)); + memset(sols, 0, len * sizeof(void *)); + struct solution *sol = dfs(s, wordDict, lens, wordDictSize, sols, 0); - char **results = malloc(cache->num * sizeof(char *)); - for (i = 0; i < cache->num; i++) { + char **results = malloc(sol->count * sizeof(char *)); + for (i = 0; i < sol->count; i++) { results[i] = malloc(total + 100); char *p = results[i]; - struct list_head *n; - list_for_each(n, cache->heads[i]) { - struct word_node *wn = list_entry(n, struct word_node, link); + struct word_node *wn; + list_for_each_entry(wn, &sol->heads[i], link) { char *q = wn->word; while ((*p++ = *q++) != '\0') {} *(p - 1) = ' '; @@ -181,7 +140,7 @@ static char **wordBreak(char* s, char** wordDict, int wordDictSize, int *returnS *(p - 1) = '\0'; } - *returnSize = cache->num; + *returnSize = sol->count; return results; } diff --git a/0146_lru_cache/lru_cache.c b/0146_lru_cache/lru_cache.c index e268453..205896c 100644 --- a/0146_lru_cache/lru_cache.c +++ b/0146_lru_cache/lru_cache.c @@ -10,30 +10,46 @@ #define list_first_entry(ptr, type, field) list_entry((ptr)->next, type, field) #define list_last_entry(ptr, type, field) list_entry((ptr)->prev, type, field) -#define list_for_each(p, head) \ - for (p = (head)->next; p != (head); p = p->next) +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, __typeof(*pos), member); \ + &(pos)->member != (head); \ + pos = list_entry((pos)->member.next, __typeof(*pos), member)) -#define list_for_each_safe(p, n, head) \ - for (p = (head)->next, n = p->next; p != (head); p = n, n = p->next) +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_entry((head)->next, __typeof(*pos), member), \ + n = list_entry(pos->member.next, __typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, __typeof(*n), member)) struct list_head { struct list_head *next, *prev; }; -static inline void -INIT_LIST_HEAD(struct list_head *list) +typedef struct { + int capacity; + int count; + struct list_head dhead; + struct list_head hheads[]; +} LRUCache; + +typedef struct { + int key; + int value; + struct list_head hlink; + struct list_head dlink; +} LRUNode; + +static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list->prev = list; } -static inline int -list_empty(const struct list_head *head) +static inline int list_empty(const struct list_head *head) { return (head->next == head); } -static inline void -__list_add(struct list_head *new, struct list_head *prev, struct list_head *next) +static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { next->prev = new; new->next = next; @@ -41,61 +57,40 @@ __list_add(struct list_head *new, struct list_head *prev, struct list_head *next prev->next = new; } -static inline void -list_add(struct list_head *_new, struct list_head *head) +static inline void list_add(struct list_head *_new, struct list_head *head) { __list_add(_new, head, head->next); } -static inline void -list_add_tail(struct list_head *_new, struct list_head *head) +static inline void list_add_tail(struct list_head *_new, struct list_head *head) { __list_add(_new, head->prev, head); } -static inline void -__list_del(struct list_head *entry) +static inline void __list_del(struct list_head *entry) { entry->next->prev = entry->prev; entry->prev->next = entry->next; } -static inline void -list_del(struct list_head *entry) +static inline void list_del(struct list_head *entry) { __list_del(entry); entry->next = entry->prev = NULL; } -static inline void -list_move(struct list_head *list, struct list_head *head) +static inline void list_move(struct list_head *list, struct list_head *head) { __list_del(list); list_add(list, head); } -static inline void -list_move_tail(struct list_head *entry, struct list_head *head) +static inline void list_move_tail(struct list_head *entry, struct list_head *head) { __list_del(entry); list_add_tail(entry, head); } -typedef struct { - int capacity; - int count; - struct list_head dhead; - struct list_head hheads[]; -} LRUCache; - -typedef struct { - int key; - int value; - struct list_head hlink; - struct list_head dlink; -} LRUNode; - - LRUCache *lRUCacheCreate(int capacity) { int i; @@ -111,9 +106,8 @@ LRUCache *lRUCacheCreate(int capacity) void lRUCacheFree(LRUCache *obj) { - struct list_head *pos, *n; - list_for_each_safe(pos, n, &obj->dhead) { - LRUNode *lru = list_entry(pos, LRUNode, dlink); + LRUNode *lru, *n; + list_for_each_entry_safe(lru, n, &obj->dhead, dlink) { list_del(&lru->dlink); free(lru); } @@ -122,10 +116,9 @@ void lRUCacheFree(LRUCache *obj) int lRUCacheGet(LRUCache *obj, int key) { + LRUNode *lru; int hash = key % obj->capacity; - struct list_head *pos; - list_for_each(pos, &obj->hheads[hash]) { - LRUNode *lru = list_entry(pos, LRUNode, hlink); + list_for_each_entry(lru, &obj->hheads[hash], hlink) { if (lru->key == key) { /* Move it to header */ list_move(&lru->dlink, &obj->dhead); @@ -139,9 +132,7 @@ void lRUCachePut(LRUCache *obj, int key, int value) { LRUNode *lru; int hash = key % obj->capacity; - struct list_head *pos; - list_for_each(pos, &obj->hheads[hash]) { - lru = list_entry(pos, LRUNode, hlink); + list_for_each_entry(lru, &obj->hheads[hash], hlink) { if (lru->key == key) { list_move(&lru->dlink, &obj->dhead); lru->value = value; @@ -172,9 +163,8 @@ void lRUCacheDump(LRUCache *obj) printf(">>> Total %d nodes: \n", obj->count); for (i = 0; i < obj->count; i++) { printf("hash:%d:", i); - struct list_head *pos; - list_for_each(pos, &obj->hheads[i]) { - lru = list_entry(pos, LRUNode, hlink); + list_for_each_entry(lru, &obj->hheads[i], hlink) { + lru = list_entry(lru, LRUNode, hlink); if (lru != NULL) { printf(" (%d %d)", lru->key, lru->value); } @@ -183,9 +173,7 @@ void lRUCacheDump(LRUCache *obj) } printf(">>> Double list dump\n"); - struct list_head *p; - list_for_each(p, &obj->dhead) { - lru = list_entry(p, LRUNode, dlink); + list_for_each_entry(lru, &obj->dhead, dlink) { printf("(%d %d)\n", lru->key, lru->value); } } diff --git a/0149_max_points_on_a_line/points_on_line.c b/0149_max_points_on_a_line/points_on_line.c index 96c0122..c0ad22f 100644 --- a/0149_max_points_on_a_line/points_on_line.c +++ b/0149_max_points_on_a_line/points_on_line.c @@ -3,71 +3,64 @@ #include #include + #define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - (size_t)&(((type *)0)->member))) #define list_entry(ptr, type, member) \ container_of(ptr, type, member) -#define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos; pos = pos->next) - -#define hlist_for_each_safe(pos, n, head) \ - for (pos = (head)->first; pos && ({ n = pos->next; true; }); pos = n) +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, __typeof(*pos), member); \ + &(pos)->member != (head); \ + pos = list_entry((pos)->member.next, __typeof(*pos), member)) -struct hlist_node; +struct list_head { + struct list_head *next, *prev; +}; -struct hlist_head { - struct hlist_node *first; +struct Point { + int x, y; }; -struct hlist_node { - struct hlist_node *next, **pprev; +struct point_node { + int p1; + int p2; + struct list_head link; }; -static inline void INIT_HLIST_HEAD(struct hlist_head *h) { - h->first = NULL; +static inline void INIT_LIST_HEAD(struct list_head *list) +{ + list->next = list->prev = list; } -static inline int hlist_empty(struct hlist_head *h) { - return !h->first; +static inline int list_empty(const struct list_head *head) +{ + return (head->next == head); } -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) +static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { - if (h->first != NULL) { - h->first->pprev = &n->next; - } - n->next = h->first; - n->pprev = &h->first; - h->first = n; + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; } -static inline void hlist_del(struct hlist_node *n) +static inline void list_add(struct list_head *_new, struct list_head *head) { - struct hlist_node *next = n->next; - struct hlist_node **pprev = n->pprev; - *pprev = next; - if (next != NULL) { - next->pprev = pprev; - } + __list_add(_new, head, head->next); } -struct Point { - int x, y; -}; - -struct point_node { - int p1; - int p2; - struct hlist_node node; -}; +static inline void list_add_tail(struct list_head *_new, struct list_head *head) +{ + __list_add(_new, head->prev, head); +} -static bool can_insert(struct hlist_head *head, int p1, int p2) +static bool can_insert(struct list_head *head, int p1, int p2) { - struct hlist_node *pos; - hlist_for_each(pos, head) { - struct point_node *pn = list_entry(pos, struct point_node, node); + struct point_node *pn; + list_for_each_entry(pn, head, link) { return p1 == pn->p1; } return true; @@ -102,9 +95,9 @@ static int maxPoints(struct Point *points, int pointsSize) dup_cnts[i] = 1; } - struct hlist_head *heads = malloc(slope_size * sizeof(*heads)); + struct list_head *heads = malloc(slope_size * sizeof(*heads)); for (i = 0; i < slope_size; i++) { - INIT_HLIST_HEAD(&heads[i]); + INIT_LIST_HEAD(&heads[i]); } for (i = 0; i < pointsSize; i++) { @@ -139,17 +132,16 @@ static int maxPoints(struct Point *points, int pointsSize) struct point_node *pn = malloc(sizeof(*pn)); pn->p1 = i; pn->p2 = j; - hlist_add_head(&pn->node, &heads[hash]); + list_add(&pn->link, &heads[hash]); } } } } for (i = 0; i < slope_size; i++) { - struct hlist_node *pos; int index = -1; - hlist_for_each(pos, &heads[i]) { - struct point_node *pn = list_entry(pos, struct point_node, node); + struct point_node *pn; + list_for_each_entry(pn, &heads[i], link) { index = pn->p1; slope_cnts[i]++; } diff --git a/0152_maximum_product_subarray/subarray.c b/0152_maximum_product_subarray/subarray.c index cabe83d..3af1389 100644 --- a/0152_maximum_product_subarray/subarray.c +++ b/0152_maximum_product_subarray/subarray.c @@ -2,6 +2,7 @@ #include #include + static inline int min(int a, int b) { return a < b ? a : b; @@ -31,8 +32,6 @@ static int maxProduct(int* nums, int numsSize) int main(int argc, char **argv) { - - int i, count = argc - 1; int *nums = malloc(count * sizeof(int)); for (i = 0; i < count; i++) { diff --git a/0153_find_minimum_in_rotated_sorted_array/minimum.c b/0153_find_minimum_in_rotated_sorted_array/minimum.c index 1073f1f..677d426 100644 --- a/0153_find_minimum_in_rotated_sorted_array/minimum.c +++ b/0153_find_minimum_in_rotated_sorted_array/minimum.c @@ -6,17 +6,15 @@ static int findMin(int* nums, int numsSize) { int lo = 0; int hi = numsSize - 1; - int min = INT_MAX; - while (lo <= hi) { + while (lo < hi) { int mid = lo + (hi - lo) / 2; - min = min < nums[mid] ? min : nums[mid]; - if (nums[mid] > nums[hi]) { - lo = mid + 1; + if (nums[mid] < nums[hi]) { + hi = mid; } else { - hi = mid - 1; + lo = mid + 1; } } - return min; + return nums[lo]; } int main(int argc, char **argv) diff --git a/0154_find_minimum_in_rotated_sorted_array_ii/minimum.c b/0154_find_minimum_in_rotated_sorted_array_ii/minimum.c index a1ec893..6e11f26 100644 --- a/0154_find_minimum_in_rotated_sorted_array_ii/minimum.c +++ b/0154_find_minimum_in_rotated_sorted_array_ii/minimum.c @@ -3,16 +3,21 @@ static int findMin(int* nums, int numsSize) { - if (numsSize == 1) { - return nums[0]; - } - int i, j; - for (i = 1; i < numsSize; i++) { - if (nums[i] < nums[i - 1]) { - return nums[i]; + int lo = 0; + int hi = numsSize - 1; + + while (lo < hi) { + int mid = lo + (hi - lo) / 2; + if (nums[mid] < nums[hi]) { + hi = mid; + } else if (nums[mid] > nums[hi]) { + lo = mid + 1; + } else { + hi--; } } - return nums[0]; + + return nums[lo]; } int main(int argc, char **argv) diff --git a/0162_find_peak_element/peak.c b/0162_find_peak_element/peak.c index bb1d2f5..c936ae5 100644 --- a/0162_find_peak_element/peak.c +++ b/0162_find_peak_element/peak.c @@ -1,14 +1,15 @@ #include #include -static int findPeakElement(int* nums, int numsSize) -{ - if (numsSize == 1) { - return nums[0]; - } +int findPeakElement(int* nums, int numsSize) +{ int i; - for (i = 1; i < numsSize && nums[i] > nums[i - 1]; i++) {} + for (i = 1; i < numsSize; i++) { + if (nums[i] < nums[i - 1]) { + break; + } + } return i - 1; } diff --git a/0162_find_peak_element/peak.cc b/0162_find_peak_element/peak.cc new file mode 100644 index 0000000..c60724e --- /dev/null +++ b/0162_find_peak_element/peak.cc @@ -0,0 +1,16 @@ +#include + +using namespace std; + +class Solution { +public: + int findPeakElement(vector& nums) { + int i; + for (i = 1; i < nums.size(); i++) { + if (nums[i] < nums[i - 1]) { + break; + } + } + return i - 1; + } +}; diff --git a/0166_fraction_to_recurring_decimal/fraction.c b/0166_fraction_to_recurring_decimal/fraction.c index fbb1db5..f1c90ff 100644 --- a/0166_fraction_to_recurring_decimal/fraction.c +++ b/0166_fraction_to_recurring_decimal/fraction.c @@ -3,70 +3,61 @@ #include #include + #define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - (size_t)&(((type *)0)->member))) #define list_entry(ptr, type, member) \ container_of(ptr, type, member) -#define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos; pos = pos->next) - -#define hlist_for_each_safe(pos, n, head) \ - for (pos = (head)->first; pos && ({ n = pos->next; true; }); pos = n) +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, __typeof(*pos), member); \ + &(pos)->member != (head); \ + pos = list_entry((pos)->member.next, __typeof(*pos), member)) -struct hlist_node; - -struct hlist_head { - struct hlist_node *first; +struct list_head { + struct list_head *next, *prev; }; -struct hlist_node { - struct hlist_node *next, **pprev; +struct rem_node { + int key; + int index; + struct list_head link; }; -static inline void INIT_HLIST_HEAD(struct hlist_head *h) +static inline void INIT_LIST_HEAD(struct list_head *list) { - h->first = NULL; + list->next = list->prev = list; } -static inline int hlist_empty(struct hlist_head *h) +static inline int list_empty(const struct list_head *head) { - return !h->first; + return (head->next == head); } -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) +static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { - if (h->first != NULL) { - h->first->pprev = &n->next; - } - n->next = h->first; - n->pprev = &h->first; - h->first = n; + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; } -static inline void hlist_del(struct hlist_node *n) +static inline void list_add(struct list_head *_new, struct list_head *head) { - struct hlist_node *next = n->next; - struct hlist_node **pprev = n->pprev; - *pprev = next; - if (next != NULL) { - next->pprev = pprev; - } + __list_add(_new, head, head->next); } -struct rem_node { - struct hlist_node node; - int key; - int index; -}; +static inline void list_add_tail(struct list_head *_new, struct list_head *head) +{ + __list_add(_new, head->prev, head); +} -static int find(struct hlist_head *heads, int size, int key) +static int find(struct list_head *heads, int size, int key) { + struct rem_node *node; int hash = key % size; - struct hlist_node *pos; - hlist_for_each(pos, &heads[hash]) { - struct rem_node *node = list_entry(pos, struct rem_node, node); + list_for_each_entry(node, &heads[hash], link) { if (key == node->key) { return node->index; } @@ -74,7 +65,7 @@ static int find(struct hlist_head *heads, int size, int key) return -1; } -static char* fractionToDecimal(int numerator, int denominator) +char* fractionToDecimal(int numerator, int denominator) { int size = 1024; char *result = malloc(size); @@ -129,9 +120,9 @@ static char* fractionToDecimal(int numerator, int denominator) char *q = decimal; size = 1333; - struct hlist_head *heads = malloc(size * sizeof(*heads)); + struct list_head *heads = malloc(size * sizeof(*heads)); for (i = 0; i < size; i++) { - INIT_HLIST_HEAD(&heads[i]); + INIT_LIST_HEAD(&heads[i]); } i = 0; @@ -154,7 +145,7 @@ static char* fractionToDecimal(int numerator, int denominator) node->index = i; int hash = remainder % size; - hlist_add_head(&node->node, &heads[hash]); + list_add(&node->link, &heads[hash]); *q++ = (remainder * 10) / d + '0'; remainder = (remainder * 10) % d; diff --git a/0167_two_sum_ii/two_sum.c b/0167_two_sum_ii/two_sum.c index 86d4c4d..7478668 100644 --- a/0167_two_sum_ii/two_sum.c +++ b/0167_two_sum_ii/two_sum.c @@ -9,14 +9,14 @@ static int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) { int i = 0, j = numbersSize - 1; while (i < j) { - int diff = target - numbers[i] - numbers[j]; - if (diff > 0) { + int sum = numbers[i] + numbers[j]; + if (sum < target) { i++; - } else if (diff < 0) { + } else if (sum > target) { j--; } else { *returnSize = 2; - int *indexes = malloc(*returnSize * sizeof(int)); + int *indexes = malloc(2 * sizeof(int)); indexes[0] = i + 1; indexes[1] = j + 1; return indexes; diff --git a/0167_two_sum_ii/two_sum.cc b/0167_two_sum_ii/two_sum.cc index 4ba80b8..c8c1610 100644 --- a/0167_two_sum_ii/two_sum.cc +++ b/0167_two_sum_ii/two_sum.cc @@ -9,10 +9,10 @@ class Solution { int i = 0; int j = numbers.size() - 1; while (i < j) { - int diff = target - numbers[i] - numbers[j]; - if (diff > 0) { + int sum = numbers[i] + numbers[j]; + if (sum < target) { i++; - } else if (diff < 0) { + } else if (sum > target) { j--; } else { res.push_back(i + 1); 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/0198_house_robber/robber.c b/0198_house_robber/robber.c index d76228b..82fa8ad 100644 --- a/0198_house_robber/robber.c +++ b/0198_house_robber/robber.c @@ -14,10 +14,12 @@ static int rob(int* nums, int numsSize) int untaken = 0; /* Record max profits of nums[0...i] respectively */ for (i = 0; i < numsSize; i++) { - int tmp_taken = taken; + int last_taken = taken; /* Taken or untaken nums[i] */ + /* last taken + nums[i] */ taken = untaken + nums[i]; - untaken = max(tmp_taken, untaken); + /* max(last untaken, last taken) */ + untaken = max(last_taken, untaken); } return max(taken, untaken); diff --git a/0198_house_robber/robber.cc b/0198_house_robber/robber.cc index 3d2ffb5..010c571 100644 --- a/0198_house_robber/robber.cc +++ b/0198_house_robber/robber.cc @@ -8,9 +8,11 @@ class Solution { int taken = 0; int untaken = 0; for (int i = 0; i < nums.size(); i++) { - int tmp_taken = taken; + int last_taken = taken; + /* last untaken + nums[i]*/ taken = untaken + nums[i]; - untaken = max(untaken, tmp_taken); + /* max(last untaken, last taken) */ + untaken = max(untaken, last_taken); } return max(taken, untaken); } 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/0204_count_primes/count_primes.c b/0204_count_primes/count_primes.c index f64c6e6..69b4bef 100644 --- a/0204_count_primes/count_primes.c +++ b/0204_count_primes/count_primes.c @@ -1,12 +1,14 @@ #include #include #include -#include -static int countPrimes(int n) + +int countPrimes(int n) { - if (n < 3) return 0; - + if (n < 3) { + return 0; + } + int i, j; bool *marked = malloc(n); memset(marked, false, n); diff --git a/0204_count_primes/count_primes.cc b/0204_count_primes/count_primes.cc new file mode 100644 index 0000000..20b752c --- /dev/null +++ b/0204_count_primes/count_primes.cc @@ -0,0 +1,26 @@ +#include + +using namespace std; + +class Solution { +public: + int countPrimes(int n) { + if (n < 3) { + return 0; + } + + vector marked(n); + int count = n >> 1; + for (int i = 3; i * i <= n; i += 2) { + if (!marked[i]) { + for (int j = i * i; j < n; j += (i << 1)) { + if (!marked[j]) { + marked[j] = true; + --count; + } + } + } + } + return count; + } +}; diff --git a/0205_isomorphic_strings/isomorphic_strings.cpp b/0205_isomorphic_strings/isomorphic_strings.cpp new file mode 100644 index 0000000..5eb6551 --- /dev/null +++ b/0205_isomorphic_strings/isomorphic_strings.cpp @@ -0,0 +1,45 @@ +#include +using namespace std; + +class Solution +{ +public: + string mp(string s) + { + map m; + string ans = ""; + for (auto c : s) + { + if (m.find(c) == m.end()) + { + m[c] = m.size(); + } + ans += m[c]; + } + return ans; + } + bool isIsomorphic(string s, string t) + { + if (mp(s) == mp(t)) + { + return true; + } + return false; + } +}; + +int main() +{ + string s, t; + cout << "Enter 2 Strings : "; + cin >> s >> t; + Solution sol; + if (sol.isIsomorphic(s, t)) + { + cout << "True"; + } + else + { + cout << "False"; + } +} \ No newline at end of file diff --git a/0206_reverse_linked_list/reverse_list.c b/0206_reverse_linked_list/reverse_list.c index c45ccc5..22c65bd 100644 --- a/0206_reverse_linked_list/reverse_list.c +++ b/0206_reverse_linked_list/reverse_list.c @@ -1,6 +1,7 @@ #include #include + struct ListNode { int val; struct ListNode *next; @@ -17,21 +18,23 @@ static struct ListNode *recursive(struct ListNode *prev, struct ListNode *p) return recursive(p, q); } -static struct ListNode *reverseList(struct ListNode *head) +struct ListNode *reverseList(struct ListNode *head) { return recursive(NULL, head); } -/* Iteration */ #if 0 -static struct ListNode *reverseList(struct ListNode *head) +/* Iteration */ +struct ListNode *reverseList(struct ListNode *head) { struct ListNode *prev = NULL; struct ListNode *p = head; while (p != NULL) { + /* prev <- p <- q */ struct ListNode *q = p->next; p->next = prev; + /* step */ prev = p; p = q; } diff --git a/0206_reverse_linked_list/reverse_list.cc b/0206_reverse_linked_list/reverse_list.cc new file mode 100644 index 0000000..426a748 --- /dev/null +++ b/0206_reverse_linked_list/reverse_list.cc @@ -0,0 +1,30 @@ +#include + +using namespace std; + +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode() : val(0), next(nullptr) {} + * ListNode(int x) : val(x), next(nullptr) {} + * ListNode(int x, ListNode *next) : val(x), next(next) {} + * }; + */ +class Solution { +public: + ListNode* reverseList(ListNode* head) { + ListNode *prev = nullptr; + ListNode *p = head; + while (p != nullptr) { + // prev <- p <- q + ListNode *q = p->next; + p->next = prev; + // step + prev = p; + p = q; + } + return prev; + } +}; diff --git a/0207_course_schedule/course_schedule.cc b/0207_course_schedule/course_schedule.cc new file mode 100644 index 0000000..1b1ef6f --- /dev/null +++ b/0207_course_schedule/course_schedule.cc @@ -0,0 +1,37 @@ +#include + +using namespace std; + +class Solution { +public: + bool isCycle(int course, vector>& adj, vector& visited) { + if(visited[course] == 2) return true ; + if(visited[course] == 1) return false ; + visited[course] = 2 ; + for(auto connectedCourse : adj[course]) { + if(isCycle(connectedCourse, adj, visited)) { + return true ; + } + } + visited[course] = 1 ; + return false ; + } + + bool canFinish(int numCourses, vector>& prerequisites) { + vector> adj(numCourses) ; + for(auto courses : prerequisites) { + auto course1 = courses[0] ; + auto course2 = courses[1] ; + adj[course2].push_back(course1) ; + } + vector visited(numCourses, 0) ; + for(int course = 0 ; course < numCourses ; course++) { + if(!visited[course]) { + if(isCycle(course, adj, visited)) { + return false; + } + } + } + return true ; + } +}; \ No newline at end of file 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 c4f6294..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,43 +2,106 @@ #include -static int partition(int *nums, int lo, int hi) +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 max_heapify(int *nums, int size, int parent) +{ + int i = parent; /* parent is the root */ + int l = parent * 2 + 1; + int r = parent * 2 + 2; + + if (l < size && nums[l] > nums[i]) { + i = l; + } + + if (r < size && nums[r] > nums[i]) { + i = r; + } + + /* percolate up */ + if (i != parent) { + swap(&nums[i], &nums[parent]); + max_heapify(nums, size, i); + } +} + +static void build_max_heap(int *nums, int size) +{ + int i; + for (i = size / 2; i >= 0; i--) { + max_heapify(nums, size, i); + } +} + +static void quick_select(int *nums, int lo, int hi, int k) { if (lo >= hi) { - return hi; + return; } - int i = lo; + int i = lo - 1; int j = hi; int pivot = nums[hi]; + while (i < j) { - while (i < j && nums[i] <= pivot) { i++; } - /* Loop invariant: nums[i] > pivot or i == j */ - nums[j] = nums[i]; - while (i < j && nums[j] >= pivot) { j--; } - /* Loop invariant: nums[j] > pivot or i == j */ - nums[i] = nums[j]; - } - /* Loop invariant: i == j */ - nums[i] = pivot; - return i; + /* 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 < 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 */ + 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 { + quick_select(nums, i + 1, hi, k); + } } int findKthLargest(int* nums, int numsSize, int k) { - int lo = 0, hi = numsSize - 1; - for (; ;) { - int p = partition(nums, lo, hi); - if (p < numsSize - k) { - lo = p + 1; - } else if (p > numsSize - k) { - hi = p - 1; - } else { - lo = p; - break; - } +#if 1 + quick_select(nums, 0, numsSize - 1, k); + return nums[k - 1]; +#else + int i; + + build_max_heap(nums, numsSize); + + /* nums[0] is the largest element and the last is the least */ + for (i = numsSize - 1; i >= numsSize - k + 1; i--) { + swap(&nums[0], &nums[i]); + max_heapify(nums, numsSize, 0); } - return nums[lo]; + + return nums[0]; +#endif } diff --git a/0216_combination_sum_iii/combination_sum.cc b/0216_combination_sum_iii/combination_sum.cc new file mode 100644 index 0000000..40189b1 --- /dev/null +++ b/0216_combination_sum_iii/combination_sum.cc @@ -0,0 +1,27 @@ +#include + +using namespace std; + +class Solution { +public: + vector> combinationSum3(int k, int n) { + vector> res; + dfs(1, 9, k, n, res); + return res; + } +private: + vector stack; + void dfs(int start, int size, int k, int target, vector>& res) { + if (stack.size() == k) { + if (target == 0) { + res.push_back(stack); + } + } else { + for (int i = start; i <= size; i++) { + stack.push_back(i); + dfs(i + 1, size, k, target - i, res); + stack.pop_back(); + } + } + } +}; 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/0235_lowest_common_ancestor_of_a_binary_search_tree/bst_lca.c b/0235_lowest_common_ancestor_of_a_binary_search_tree/bst_lca.c index 502863a..aecdf1c 100644 --- a/0235_lowest_common_ancestor_of_a_binary_search_tree/bst_lca.c +++ b/0235_lowest_common_ancestor_of_a_binary_search_tree/bst_lca.c @@ -8,7 +8,7 @@ struct TreeNode { struct TreeNode *right; }; -static struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) +struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) { if (root == NULL || root->val == p->val || root->val == q->val) { return root; diff --git a/0235_lowest_common_ancestor_of_a_binary_search_tree/bst_lca.cc b/0235_lowest_common_ancestor_of_a_binary_search_tree/bst_lca.cc new file mode 100644 index 0000000..82fbf71 --- /dev/null +++ b/0235_lowest_common_ancestor_of_a_binary_search_tree/bst_lca.cc @@ -0,0 +1,28 @@ +#include + +using namespace std; + +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ + +class Solution { +public: + TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { + if (root == nullptr || root->val == p->val || root->val == q->val) { + return root; + } else if (root->val < p->val && root->val < q->val) { + return lowestCommonAncestor(root->right, p, q); + } else if (root->val > p->val && root->val > q->val) { + return lowestCommonAncestor(root->left, p, q); + } else { + return root; + } + } +}; diff --git a/0236_lowest_common_ancestor_of_a_binary_tree/bst_lca.c b/0236_lowest_common_ancestor_of_a_binary_tree/bst_lca.c index 30afec2..4eefea8 100644 --- a/0236_lowest_common_ancestor_of_a_binary_tree/bst_lca.c +++ b/0236_lowest_common_ancestor_of_a_binary_tree/bst_lca.c @@ -9,7 +9,7 @@ struct TreeNode { struct TreeNode *right; }; -static struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) +struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) { if (root == NULL || root == p || root == q) { /* edge cases: if return NULL then no p or q node in this path */ diff --git a/0236_lowest_common_ancestor_of_a_binary_tree/bst_lca.cc b/0236_lowest_common_ancestor_of_a_binary_tree/bst_lca.cc new file mode 100644 index 0000000..96caff4 --- /dev/null +++ b/0236_lowest_common_ancestor_of_a_binary_tree/bst_lca.cc @@ -0,0 +1,28 @@ +#include + +using namespace std; + /** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ +class Solution { +public: + TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { + if (root == nullptr || root == p || root == q) { + return root; + } + + TreeNode *l = lowestCommonAncestor(root->left, p, q); + TreeNode *r = lowestCommonAncestor(root->right, p, q); + if (l != nullptr && r != nullptr) { + return root; + } else { + return l != nullptr ? l : r; + } + } +}; diff --git a/0300_longest_increasing_subsequence/Makefile b/0300_longest_increasing_subsequence/Makefile new file mode 100644 index 0000000..ba1e9d7 --- /dev/null +++ b/0300_longest_increasing_subsequence/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test lis.c diff --git a/0300_longest_increasing_subsequence/lis.c b/0300_longest_increasing_subsequence/lis.c new file mode 100644 index 0000000..2713e88 --- /dev/null +++ b/0300_longest_increasing_subsequence/lis.c @@ -0,0 +1,69 @@ +#include +#include + + +static int max(int a, int b) +{ + return a > b ? a : b; +} + +static int binary_search(int *nums, int lo, int hi, int target) +{ + while (lo + 1 < hi) { + int mid = lo + (hi - lo) / 2; + if (nums[mid] < target) { + lo = mid; + } else { + hi = mid; + } + } + return hi; +} + +int lengthOfLIS(int* nums, int numsSize) +{ +#if 0 + int i, piles = 0; + int *tops = malloc(numsSize * sizeof(int)); + for (i = 0; i < numsSize; i++) { + int pos = binary_search(tops, -1, piles, nums[i]); + if (pos == piles) { + piles++; + } + tops[pos] = nums[i]; + } + return piles; +#else + int i, j, res = 0; + int *dp = malloc(numsSize * sizeof(int)); + + /* dp array records subsequence length of nums[0...i], so we need to + * initialize each dp[i] with one element length in the beginning. */ + for (i = 0; i < numsSize; i++) { + dp[i] = 1; + for (j = 0; j < i; j++) { + if (nums[j] > nums[i]) { + dp[i] = max(dp[i], dp[j] + 1); + } + } + } + + for (i = 0; i < numsSize; i++) { + res = max(res, dp[i]); + } + + return res; +#endif +} + +int main(int argc, char **argv) +{ + int i; + int *nums = malloc((argc - 1) * sizeof(int)); + for (i = 0; i < argc - 1; i++) { + nums[i] = atoi(argv[i + 1]); + } + + printf("%d\n", lengthOfLIS(nums, argc - 1)); + return 0; +} diff --git a/0300_longest_increasing_subsequence/lis.cc b/0300_longest_increasing_subsequence/lis.cc new file mode 100644 index 0000000..98e81ac --- /dev/null +++ b/0300_longest_increasing_subsequence/lis.cc @@ -0,0 +1,18 @@ +#include + +using namespace std; + +class Solution { +public: + int lengthOfLIS(vector& nums) { + vector ans; + for (int x : nums) { + auto it = lower_bound(ans.begin(), ans.end(), x); + if (it == ans.end()) { + ans.push_back(x); + } + else *it = x; + } + return ans.size(); + } +}; diff --git a/0322_coin_change/coin_change.c b/0322_coin_change/coin_change.c index 10c8244..9eb270c 100644 --- a/0322_coin_change/coin_change.c +++ b/0322_coin_change/coin_change.c @@ -6,13 +6,14 @@ int coinChange(int* coins, int coinsSize, int amount) { int i, j; int *dp = malloc((amount + 1) * sizeof(int)); - for (i = 1; i <= amount; i++) { - /* INT_MAX */ - dp[i] = amount + 1; - } + /* The dp array records minimum coin number corresponding to the + * amount of coins. So we need to initialize each dp[i] with + * amount + 1 as an invalid value */ dp[0] = 0; for (i = 1; i <= amount; i++) { + /* initialized with INT_MAX */ + dp[i] = amount + 1; for (j = 0; j < coinsSize; j++) { if (i - coins[j] >= 0) { int tmp = 1 + dp[i - coins[j]]; diff --git a/0322_coin_change/coin_change.cc b/0322_coin_change/coin_change.cc index 4b2fa6e..31ddb51 100644 --- a/0322_coin_change/coin_change.cc +++ b/0322_coin_change/coin_change.cc @@ -19,7 +19,7 @@ class Solution { #else // BFS solution is slow... queue q; - unordered_set s; + unordered_set visited; int step = 0; q.push(amount); while (!q.empty()) { @@ -31,8 +31,8 @@ class Solution { for (int coin : coins) { int n = q.front() - coin; if (n >= 0) { - if (s.count(n) == 0) { - s.insert(n); + if (visited.count(n) == 0) { + visited.insert(n); q.push(n); } } diff --git a/0354_russian_doll_envelopes/Makefile b/0354_russian_doll_envelopes/Makefile new file mode 100644 index 0000000..df77fea --- /dev/null +++ b/0354_russian_doll_envelopes/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test russian_doll.c diff --git a/0354_russian_doll_envelopes/russian_doll.c b/0354_russian_doll_envelopes/russian_doll.c new file mode 100644 index 0000000..389f389 --- /dev/null +++ b/0354_russian_doll_envelopes/russian_doll.c @@ -0,0 +1,72 @@ +#include +#include + + +static int compare(const void *a, const void *b) +{ + int wa = ((const int *)a)[0]; + int wb = ((const int *)b)[0]; + int ha = ((const int *)a)[1]; + int hb = ((const int *)b)[1]; + return wa == wb ? hb - ha : wa - wb; +} + +static int binary_search(int *nums, int lo, int hi, int target) +{ + while (lo + 1 < hi) { + int mid = lo + (hi - lo) / 2; + if (nums[mid] < target) { + lo = mid; + } else { + hi = mid; + } + } + return hi; +} + +int maxEnvelopes(int** envelopes, int envelopesSize, int* envelopesColSize) +{ + if (envelopesSize == 0) { + return 0; + } + + int size = envelopesColSize[0]; + int i, *tmp = malloc(envelopesSize * size * sizeof(int)); + for (i = 0; i < envelopesSize; i++) { + tmp[i * size] = envelopes[i][0]; + tmp[i * size + 1] = envelopes[i][1]; + } + qsort(tmp, envelopesSize, size * sizeof(int), compare); + + int piles = 0; + int *heights = malloc(envelopesSize * sizeof(int)); + for (i = 0; i < envelopesSize; i++) { + int pos = binary_search(heights, -1, piles, tmp[i * size + 1]); + if (pos == piles) { + piles++; + } + heights[pos] = tmp[i * size + 1]; + } + return piles; +} + +int main(int argc, char **argv) +{ + if (argc < 3 || argc % 2 == 0) { + fprintf(stderr, "Usage: ./test w0 h0 w1 h1..."); + exit(-1); + } + + int i, size = (argc - 1) / 2; + int *col_sizes = malloc(size * sizeof(int)); + int **envelopes = malloc(size * sizeof(int *)); + for (i = 0; i < size; i++) { + col_sizes[i] = 2; + envelopes[i] = malloc(col_sizes[i] * sizeof(int)); + envelopes[i][0] = atoi(argv[i * 2 + 1]); + envelopes[i][1] = atoi(argv[i * 2 + 2]); + } + + printf("%d\n", maxEnvelopes(envelopes, size, col_sizes)); + return 0; +} diff --git a/0354_russian_doll_envelopes/russian_doll.cc b/0354_russian_doll_envelopes/russian_doll.cc new file mode 100644 index 0000000..3079ee3 --- /dev/null +++ b/0354_russian_doll_envelopes/russian_doll.cc @@ -0,0 +1,39 @@ +#include + +using namespace std; + +class Solution { +public: + int maxEnvelopes(vector>& envelopes) { + vector piles; + sort(envelopes.begin(), envelopes.end(), compare); + for (const auto& e : envelopes) { + int pos = binary_search(piles, -1, piles.size(), e[1]); + if (pos == piles.size()) { + piles.push_back(e[1]); + } + piles[pos] = e[1]; + } + return piles.size(); + } +private: + static bool compare(const vector& a, const vector& b) { + int wa = a[0]; + int wb = b[0]; + int ha = a[1]; + int hb = b[1]; + return wa == wb ? ha > hb : wa < wb; + } + + int binary_search(vector& nums, int lo, int hi, int target) { + while (lo + 1 < hi) { + int mid = lo + (hi - lo) / 2; + if (nums[mid] < target) { + lo = mid; + } else { + hi = mid; + } + } + return hi; + } +}; diff --git a/0438_find_all_anagrams_in_a_string/Makefile b/0438_find_all_anagrams_in_a_string/Makefile new file mode 100644 index 0000000..99bb57e --- /dev/null +++ b/0438_find_all_anagrams_in_a_string/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test anagrams_in_string.c diff --git a/0438_find_all_anagrams_in_a_string/anagrams_in_string.c b/0438_find_all_anagrams_in_a_string/anagrams_in_string.c new file mode 100644 index 0000000..f780591 --- /dev/null +++ b/0438_find_all_anagrams_in_a_string/anagrams_in_string.c @@ -0,0 +1,56 @@ +#include +#include + + +/** + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* findAnagrams(char * s, char * p, int* returnSize) +{ + *returnSize = 0; + int *res = malloc(11000 * sizeof(int)); + int i, pat_len = 0; + int count[128] = { 0 }; + int l = 0, r = 0, len = 0; + + for (i = 0; p[i] != '\0'; i++) { + count[p[i]]++; + } + pat_len = i; + + while (s[r] != '\0') { + if (--count[s[r++]] >= 0) { + len++; + } + + while (len >= pat_len) { + if (r - l == pat_len) { + res[(*returnSize)++] = l; + } + if (++count[s[l++]] > 0) { + len--; + } + } + } + + return res; +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./test string pattern\n"); + exit(-1); + } + + char *t = argv[1]; + char *s = argv[2]; + int i, count; + int *results = findAnagrams(s, t, &count); + for (i = 0; i < count; i++) { + printf("%d ", results[i]); + } + printf("\n"); + + return 0; +} diff --git a/0438_find_all_anagrams_in_a_string/anagrams_in_string.cc b/0438_find_all_anagrams_in_a_string/anagrams_in_string.cc new file mode 100644 index 0000000..7a50a3c --- /dev/null +++ b/0438_find_all_anagrams_in_a_string/anagrams_in_string.cc @@ -0,0 +1,32 @@ +#include + +using namespace std; + +class Solution { +public: + vector findAnagrams(string s, string p) { + int count[128] = { 0 }; + for (char c : p) { + count[c]++; + } + + vector res; + int l = 0, r = 0, len = 0; + while (r < s.length()) { + if (--count[s[r++]] >= 0) { + len++; + } + + if (r - l >= p.length()) { + if (len == p.length()) { + res.push_back(l); + } + if (++count[s[l++]] > 0) { + len--; + } + } + } + + return res; + } +}; diff --git a/0460_lfu_cache/lfu_cache.c b/0460_lfu_cache/lfu_cache.c index c77ba2c..fdcfb77 100644 --- a/0460_lfu_cache/lfu_cache.c +++ b/0460_lfu_cache/lfu_cache.c @@ -2,6 +2,7 @@ #include #include + #define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - (size_t)&(((type *)0)->member))) @@ -11,11 +12,16 @@ #define list_first_entry(ptr, type, field) list_entry((ptr)->next, type, field) #define list_last_entry(ptr, type, field) list_entry((ptr)->prev, type, field) -#define list_for_each(p, head) \ - for (p = (head)->next; p != (head); p = p->next) +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, __typeof(*pos), member); \ + &(pos)->member != (head); \ + pos = list_entry((pos)->member.next, __typeof(*pos), member)) -#define list_for_each_safe(p, n, head) \ - for (p = (head)->next, n = p->next; p != (head); p = n, n = p->next) +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_entry((head)->next, __typeof(*pos), member), \ + n = list_entry(pos->member.next, __typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, __typeof(*n), member)) struct list_head { struct list_head *next, *prev; @@ -348,10 +354,9 @@ int lFUCacheGet(LFUCache* obj, int key) return; } - struct list_head *pos; + LFUNode *lfu; int hash = key % obj->capacity; - list_for_each(pos, &obj->hheads[hash]) { - LFUNode *lfu = list_entry(pos, LFUNode, key_link); + list_for_each_entry(lfu, &obj->hheads[hash], key_link) { if (lfu->key == key) { freq_incr(obj->tree, lfu, key); return lfu->val; @@ -368,9 +373,7 @@ void lFUCachePut(LFUCache* obj, int key, int value) LFUNode *lfu; int hash = key % obj->capacity; - struct list_head *pos; - list_for_each(pos, &obj->hheads[hash]) { - lfu = list_entry(pos, LFUNode, key_link); + list_for_each(lfu, &obj->hheads[hash], key_link) { if (lfu->key == key) { freq_incr(obj->tree, lfu, key); lfu->val = value; @@ -404,9 +407,8 @@ void lFUCacheFree(LFUCache* obj) { int i; for (i = 0; i < obj->capacity; i++) { - struct list_head *pos, *n; - list_for_each_safe(pos, n, &obj->hheads[i]) { - LFUNode *lfu = list_entry(pos, LFUNode, key_link); + LFUNode *lfu, *n; + list_for_each_entry_safe(lfu, n, &obj->hheads[i], key_link) { list_del(&lfu->dlink); list_del(&lfu->key_link); free(lfu); diff --git a/0516_longest_palindromic_subsequence/Makefile b/0516_longest_palindromic_subsequence/Makefile new file mode 100644 index 0000000..f5e6e53 --- /dev/null +++ b/0516_longest_palindromic_subsequence/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test lps.c diff --git a/0516_longest_palindromic_subsequence/lps.c b/0516_longest_palindromic_subsequence/lps.c new file mode 100644 index 0000000..9972a01 --- /dev/null +++ b/0516_longest_palindromic_subsequence/lps.c @@ -0,0 +1,47 @@ +#include +#include +#include + + +static inline int max(int a, int b) +{ + return a > b ? a : b; +} + +int longestPalindromeSubseq(char * s) +{ + int i, j, k; + int len = strlen(s); + int **dp = malloc(len * sizeof(int *)); + + /* The dp array indicates the length of palindrome subsequence of + * nums[i...j] */ + for (i = 0; i < len; i++) { + dp[i] = malloc(len * sizeof(int)); + memset(dp[i], 0, len * sizeof(int)); + dp[i][i] = 1; + } + + for (k = 1; k < len; k++) { + for (i = 0; i < len - k; i++) { + j = i + k; + if (s[i] == s[j]) { + dp[i][j] = dp[i + 1][j - 1] + 2; + } else { + dp[i][j] = max(dp[i][j - 1], dp[i + 1][j]); + } + } + } + return dp[0][len - 1]; +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test s\n"); + exit(-1); + } + + printf("%d\n", longestPalindromeSubseq(argv[1])); + return 0; +} diff --git a/0516_longest_palindromic_subsequence/lps.cc b/0516_longest_palindromic_subsequence/lps.cc new file mode 100644 index 0000000..240fec0 --- /dev/null +++ b/0516_longest_palindromic_subsequence/lps.cc @@ -0,0 +1,25 @@ +#include + +using namespace std; + +class Solution { +public: + int longestPalindromeSubseq(string s) { + int len = s.length(); + vector dp(len, 1); + // We have to use level traverse to reduce the dp table size + for (int i = len - 2; i >= 0; i--) { + int left_down = 0; + for (int j = i + 1; j < len; j++) { + int down = dp[j]; + if (s[i] == s[j]) { + dp[j] = left_down + 2; + } else { + dp[j] = max(down, dp[j - 1]); + } + left_down = down; + } + } + return dp[len - 1]; + } +}; 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/Makefile b/0567_permutation_in_string/Makefile new file mode 100644 index 0000000..34c55c8 --- /dev/null +++ b/0567_permutation_in_string/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test permutation_in_string.c diff --git a/0567_permutation_in_string/permutation_in_string.c b/0567_permutation_in_string/permutation_in_string.c new file mode 100644 index 0000000..bdb4ea8 --- /dev/null +++ b/0567_permutation_in_string/permutation_in_string.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include + + +bool checkInclusion(char * s1, char * s2) +{ + int i, count[128] = { 0 }, pat_len; + int l = 0, r = 0, len = 0; + + for (i = 0; s1[i] != '\0'; i++) { + count[s1[i]]++; + } + pat_len = i; + + while (s2[r] != '\0') { + if (--count[s2[r++]] >= 0) { + len++; + } + + while (len >= pat_len) { + if (r - l == pat_len) { + return true; + } + if (++count[s2[l++]] > 0) { + len--; + } + } + } + + return false; +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./test string pattern\n"); + exit(-1); + } + + char *t = argv[1]; + char *s = argv[2]; + printf("%s\n", checkInclusion(t, s) ? "true" : "false"); + return 0; +} diff --git a/0567_permutation_in_string/permutation_in_string.cc b/0567_permutation_in_string/permutation_in_string.cc new file mode 100644 index 0000000..541b1cb --- /dev/null +++ b/0567_permutation_in_string/permutation_in_string.cc @@ -0,0 +1,31 @@ +#include + +using namespace std; + +class Solution { +public: + bool checkInclusion(string s1, string s2) { + int count[128] = { 0 }; + for (char c : s1) { + count[c]++; + } + + int l = 0, r = 0, len = 0; + while (r < s2.length()) { + if (--count[s2[r++]] >= 0) { + len++; + } + + if (r - l >= s1.length()) { + if (len == s1.length()) { + return true; + } + if (++count[s2[l++]] > 0) { + len--; + } + } + } + + return false; + } +}; diff --git a/0704_binary_search/binary_search.c b/0704_binary_search/binary_search.c new file mode 100644 index 0000000..23f4ef3 --- /dev/null +++ b/0704_binary_search/binary_search.c @@ -0,0 +1,23 @@ +#include + +int search(int* nums, int numsSize, int target){ + if(target > nums[numsSize-1] || target < nums[0])return -1; + int begin = -1 ,end = numsSize; + while(begin < end-1){ + int half = (begin+end)/2; + if(nums[half] +#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; +} diff --git a/0990_satisfiability_of_equality_equations/Makefile b/0990_satisfiability_of_equality_equations/Makefile new file mode 100644 index 0000000..1e9c818 --- /dev/null +++ b/0990_satisfiability_of_equality_equations/Makefile @@ -0,0 +1,2 @@ +all: + gcc -o test equality_equations.c diff --git a/0990_satisfiability_of_equality_equations/equality_equations.c b/0990_satisfiability_of_equality_equations/equality_equations.c new file mode 100644 index 0000000..4d93265 --- /dev/null +++ b/0990_satisfiability_of_equality_equations/equality_equations.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include + + +struct ufs { + int parents[512]; +}; + +static inline void ufs_init(struct ufs *set) +{ + int i; + for (i = 0; i < sizeof(set->parents) / sizeof(int); i++) { + set->parents[i] = i; + } +} + +static inline int ufs_find(struct ufs *set, int node) +{ + assert(node >= 0 && node <= sizeof(set->parents) / sizeof(int)); + if (set->parents[node] != node) { + set->parents[node] = ufs_find(set, set->parents[node]); + } + return set->parents[node]; +} + +static inline void ufs_union(struct ufs *set, int p, int q) +{ + int root_p, root_q; + + root_p = ufs_find(set, p); + root_q = ufs_find(set, q); + /* Omit root_p == root_q if-condition */ + set->parents[root_p] = root_q; +} + +static inline bool ufs_connected(struct ufs *set, int p, int q) +{ + return ufs_find(set, p) == ufs_find(set, q); +} + +bool equationsPossible(char ** equations, int equationsSize) +{ + int i; + struct ufs *set; + + set = malloc(sizeof(*set)); + ufs_init(set); + + for (i = 0; i < equationsSize; i++) { + if (equations[i][1] == '=') { + ufs_union(set, equations[i][0], equations[i][3]); + } + } + + for (i = 0; i < equationsSize; i++) { + if (equations[i][1] == '!') { + if (ufs_connected(set, equations[i][0], equations[i][3])) { + return false; + } + } + } + + return true; +} + +int main(int argc, char **argv) +{ + //char *equations[] = {"a==b", "c==c", "x==y" }; + char *equations[] = {"a==b", "b!=c", "a==c" }; + printf("%s\n", equationsPossible(equations, sizeof(equations)/sizeof(char *)) ? "true" : "false"); + return 0; +} diff --git a/0991_broken_calculator/Makefile b/0991_broken_calculator/Makefile new file mode 100644 index 0000000..b12a1c8 --- /dev/null +++ b/0991_broken_calculator/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test calculator.c diff --git a/0991_broken_calculator/calculator.c b/0991_broken_calculator/calculator.c new file mode 100644 index 0000000..810e7ac --- /dev/null +++ b/0991_broken_calculator/calculator.c @@ -0,0 +1,27 @@ +#include +#include + + +int brokenCalc(int X, int Y) +{ + int step = 0; + while (X < Y) { + Y = Y & 1 ? Y + 1 : Y / 2; + step++; + } + step += X - Y; + return step; +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./test x y"); + exit(-1); + } + + int x = atoi(argv[1]); + int y = atoi(argv[2]); + printf("%d\n", brokenCalc(x, y)); + return 0; +} diff --git a/0991_broken_calculator/calculator.cc b/0991_broken_calculator/calculator.cc new file mode 100644 index 0000000..64d459a --- /dev/null +++ b/0991_broken_calculator/calculator.cc @@ -0,0 +1,12 @@ +class Solution { +public: + int brokenCalc(int X, int Y) { + int step = 0; + while (X < Y) { + Y = Y & 1 ? Y + 1 : Y / 2; + step++; + } + step += X - Y; + return step; + } +}; diff --git a/1143_longest_common_subsequence/Makefile b/1143_longest_common_subsequence/Makefile new file mode 100644 index 0000000..5b6f54f --- /dev/null +++ b/1143_longest_common_subsequence/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test lcs.c diff --git a/1143_longest_common_subsequence/lcs.c b/1143_longest_common_subsequence/lcs.c new file mode 100644 index 0000000..8171754 --- /dev/null +++ b/1143_longest_common_subsequence/lcs.c @@ -0,0 +1,46 @@ +#include +#include +#include + + +static int max(int a, int b) +{ + return a > b ? a : b; +} + +int longestCommonSubsequence(char * text1, char * text2) +{ + int i, j; + int l1 = strlen(text1); + int l2 = strlen(text2); + int **dp = malloc((l1 + 1) * sizeof(int *)); + for (i = 0; i < l1 + 1; i++) { + dp[i] = malloc((l2 + 1) * sizeof(int)); + } + memset(dp[0], 0, (l2 + 1) * sizeof(int)); + for (i = 1; i <= l1; i++) { + dp[i][0] = 0; + } + + for (i = 1; i <= l1; i++) { + for (j = 1; j <= l2; j++) { + if (text1[i - 1] == text2[j - 1]) { + dp[i][j] = dp[i - 1][j - 1] + 1; + } else { + dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); + } + } + } + return dp[l1][l2]; +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./test s1 s2\n"); + exit(-1); + } + + printf("%d\n", longestCommonSubsequence(argv[1], argv[2])); + return 0; +} diff --git a/1143_longest_common_subsequence/lcs.cc b/1143_longest_common_subsequence/lcs.cc new file mode 100644 index 0000000..78c7cac --- /dev/null +++ b/1143_longest_common_subsequence/lcs.cc @@ -0,0 +1,26 @@ +#include + +using namespace std; + +class Solution { +public: + int longestCommonSubsequence(string text1, string text2) { + int l1 = text1.length(); + int l2 = text2.length(); + vector dp(l2 + 1); + int up = 0; + for (int i = 1; i <= l1; i++) { + int left_up = 0; + for (int j = 1; j <= l2; j++) { + up = dp[j]; + if (text1[i - 1] == text2[j - 1]) { + dp[j] = left_up + 1; + } else { + dp[j] = max(up, dp[j - 1]); + } + left_up = up; + } + } + return dp[l2]; + } +}; diff --git a/1312_minimum_insertion_steps_to_make_a_string_palindrome/Makefile b/1312_minimum_insertion_steps_to_make_a_string_palindrome/Makefile new file mode 100644 index 0000000..2800b4e --- /dev/null +++ b/1312_minimum_insertion_steps_to_make_a_string_palindrome/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test insertion.c diff --git a/1312_minimum_insertion_steps_to_make_a_string_palindrome/insertion.c b/1312_minimum_insertion_steps_to_make_a_string_palindrome/insertion.c new file mode 100644 index 0000000..f1d1ef3 --- /dev/null +++ b/1312_minimum_insertion_steps_to_make_a_string_palindrome/insertion.c @@ -0,0 +1,39 @@ +#include +#include +#include + + +static inline int min(int a, int b) +{ + return a < b ? a : b; +} + +int minInsertions(char * s){ + int i, j, len = strlen(s); + int *dp = malloc(len * sizeof(int)); + memset(dp, 0, len * sizeof(int)); + for (i = len - 2; i >= 0; i--) { + int left_down = 0; + for (j = i + 1; j < len; j++) { + int down = dp[j]; + if (s[i] == s[j]) { + dp[j] = left_down; + } else { + dp[j] = min(down, dp[j - 1]) + 1; + } + left_down = down; + } + } + return dp[len - 1]; +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test s\n"); + exit(-1); + } + + printf("%d\n", minInsertions(argv[1])); + return 0; +} diff --git a/1312_minimum_insertion_steps_to_make_a_string_palindrome/insertion.cc b/1312_minimum_insertion_steps_to_make_a_string_palindrome/insertion.cc new file mode 100644 index 0000000..bcd41ae --- /dev/null +++ b/1312_minimum_insertion_steps_to_make_a_string_palindrome/insertion.cc @@ -0,0 +1,24 @@ +#include + +using namespace std; + +class Solution { +public: + int minInsertions(string s) { + int len = s.length(); + vector dp(len); + for (int i = len - 2; i >= 0; i--) { + int left_down = 0; + for (int j = i + 1; j < len; j++) { + int down = dp[j]; + if (s[i] == s[j]) { + dp[j] = left_down; + } else { + dp[j] = min(down, dp[j - 1]) + 1; + } + left_down = down; + } + } + return dp[len - 1]; + } +}; diff --git a/README.md b/README.md index bc89fa0..fca7707 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# leetcode -Let's fuck it up +# LEETCODE SOLUTIONS +Easy and Understandable C/C++ Solutions of Some Leetcode Questions.