diff --git a/001_two_sum/Makefile b/0001_two_sum/Makefile similarity index 100% rename from 001_two_sum/Makefile rename to 0001_two_sum/Makefile diff --git a/001_two_sum/two_sum.c b/0001_two_sum/two_sum.c similarity index 94% rename from 001_two_sum/two_sum.c rename to 0001_two_sum/two_sum.c index e91c9ff..6a701ea 100644 --- a/001_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/001_two_sum/two_sum.cc b/0001_two_sum/two_sum.cc similarity index 92% rename from 001_two_sum/two_sum.cc rename to 0001_two_sum/two_sum.cc index c06f0b4..7dca0f0 100644 --- a/001_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/002_add_two_numbers/Makefile b/0002_add_two_numbers/Makefile similarity index 100% rename from 002_add_two_numbers/Makefile rename to 0002_add_two_numbers/Makefile diff --git a/002_add_two_numbers/add_two_numbers.c b/0002_add_two_numbers/add_two_numbers.c similarity index 96% rename from 002_add_two_numbers/add_two_numbers.c rename to 0002_add_two_numbers/add_two_numbers.c index acc3ebb..2dd91d5 100644 --- a/002_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/002_add_two_numbers/add_two_numbers.cc b/0002_add_two_numbers/add_two_numbers.cc similarity index 100% rename from 002_add_two_numbers/add_two_numbers.cc rename to 0002_add_two_numbers/add_two_numbers.cc diff --git a/003_longest_substring_without_repeat/Makefile b/0003_longest_substring_without_repeat/Makefile similarity index 100% rename from 003_longest_substring_without_repeat/Makefile rename to 0003_longest_substring_without_repeat/Makefile diff --git a/0003_longest_substring_without_repeat/longest_substring_without_repeat.c b/0003_longest_substring_without_repeat/longest_substring_without_repeat.c new file mode 100644 index 0000000..51c7c27 --- /dev/null +++ b/0003_longest_substring_without_repeat/longest_substring_without_repeat.c @@ -0,0 +1,32 @@ +#include +#include +#include + + +int lengthOfLongestSubstring(char *s) +{ + int count[256] = {0}; + int len = 0; + int i, j; + + 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; + } + } + + return i - j > len ? i - j : len; +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test string\n"); + exit(-1); + } + + printf("%d\n", lengthOfLongestSubstring(argv[1])); + return 0; +} diff --git a/0003_longest_substring_without_repeat/longest_substring_without_repeat.cc b/0003_longest_substring_without_repeat/longest_substring_without_repeat.cc new file mode 100644 index 0000000..af643ca --- /dev/null +++ b/0003_longest_substring_without_repeat/longest_substring_without_repeat.cc @@ -0,0 +1,22 @@ +#include + +using namespace std; + +class Solution { +public: + int lengthOfLongestSubstring(string s) { + vector count(256); + int len = 0; + int i, j; + + 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; + } + } + + return i - j > len ? i - j : len; + } +}; diff --git a/004_median_of_two_sorted_array/Makefile b/0004_median_of_two_sorted_array/Makefile similarity index 100% rename from 004_median_of_two_sorted_array/Makefile rename to 0004_median_of_two_sorted_array/Makefile diff --git a/004_median_of_two_sorted_array/median_of_two_sorted_array.c b/0004_median_of_two_sorted_array/median_of_two_sorted_array.c similarity index 100% rename from 004_median_of_two_sorted_array/median_of_two_sorted_array.c rename to 0004_median_of_two_sorted_array/median_of_two_sorted_array.c diff --git a/004_median_of_two_sorted_array/median_of_two_sorted_array.cc b/0004_median_of_two_sorted_array/median_of_two_sorted_array.cc similarity index 100% rename from 004_median_of_two_sorted_array/median_of_two_sorted_array.cc rename to 0004_median_of_two_sorted_array/median_of_two_sorted_array.cc diff --git a/005_longest_palindromic_substring/Makefile b/0005_longest_palindromic_substring/Makefile similarity index 100% rename from 005_longest_palindromic_substring/Makefile rename to 0005_longest_palindromic_substring/Makefile diff --git a/005_longest_palindromic_substring/longest_palindromic_substring.c b/0005_longest_palindromic_substring/longest_palindromic_substring.c similarity index 100% rename from 005_longest_palindromic_substring/longest_palindromic_substring.c rename to 0005_longest_palindromic_substring/longest_palindromic_substring.c 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/015_three_sum/three_sum.cc b/0015_three_sum/three_sum.cc similarity index 100% rename from 015_three_sum/three_sum.cc rename to 0015_three_sum/three_sum.cc diff --git a/016_three_sum_closest/Makefile b/0016_three_sum_closest/Makefile similarity index 100% rename from 016_three_sum_closest/Makefile rename to 0016_three_sum_closest/Makefile diff --git a/016_three_sum_closest/three_sum_closest.c b/0016_three_sum_closest/three_sum_closest.c similarity index 100% rename from 016_three_sum_closest/three_sum_closest.c rename to 0016_three_sum_closest/three_sum_closest.c diff --git a/016_three_sum_closest/three_sum_closest.cc b/0016_three_sum_closest/three_sum_closest.cc similarity index 100% rename from 016_three_sum_closest/three_sum_closest.cc rename to 0016_three_sum_closest/three_sum_closest.cc diff --git a/017_letter_combinations_of_a_phone_number/Makefile b/0017_letter_combinations_of_a_phone_number/Makefile similarity index 100% rename from 017_letter_combinations_of_a_phone_number/Makefile rename to 0017_letter_combinations_of_a_phone_number/Makefile diff --git a/017_letter_combinations_of_a_phone_number/letter_combinations.c b/0017_letter_combinations_of_a_phone_number/letter_combinations.c similarity index 100% rename from 017_letter_combinations_of_a_phone_number/letter_combinations.c rename to 0017_letter_combinations_of_a_phone_number/letter_combinations.c 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/018_four_sum/Makefile b/0018_four_sum/Makefile similarity index 100% rename from 018_four_sum/Makefile rename to 0018_four_sum/Makefile diff --git a/018_four_sum/four_sum.c b/0018_four_sum/four_sum.c similarity index 75% rename from 018_four_sum/four_sum.c rename to 0018_four_sum/four_sum.c index 87ce58b..8b06eaf 100644 --- a/018_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/018_four_sum/four_sum.cc b/0018_four_sum/four_sum.cc similarity index 94% rename from 018_four_sum/four_sum.cc rename to 0018_four_sum/four_sum.cc index dd7a5e5..d661eb9 100644 --- a/018_four_sum/four_sum.cc +++ b/0018_four_sum/four_sum.cc @@ -33,7 +33,7 @@ class Solution { } } } else { - for (vector::iterator it = lo; it + k - 1 != hi + 1; it++) { + for (auto it = lo; it + k - 1 != hi + 1; it++) { if (it > lo && *(it - 1) == *it) { continue; } stack.push_back(*it); k_sum(it + 1, hi, target - *it, k - 1, stack, res); diff --git a/019_remove_nth_node_from_end_of_list/Makefile b/0019_remove_nth_node_from_end_of_list/Makefile similarity index 100% rename from 019_remove_nth_node_from_end_of_list/Makefile rename to 0019_remove_nth_node_from_end_of_list/Makefile diff --git a/019_remove_nth_node_from_end_of_list/remove_end.c b/0019_remove_nth_node_from_end_of_list/remove_end.c similarity index 100% rename from 019_remove_nth_node_from_end_of_list/remove_end.c rename to 0019_remove_nth_node_from_end_of_list/remove_end.c diff --git a/019_remove_nth_node_from_end_of_list/remove_end.cc b/0019_remove_nth_node_from_end_of_list/remove_end.cc similarity index 100% rename from 019_remove_nth_node_from_end_of_list/remove_end.cc rename to 0019_remove_nth_node_from_end_of_list/remove_end.cc diff --git a/001_two_sum/two_sum.py b/001_two_sum/two_sum.py deleted file mode 100644 index 2606238..0000000 --- a/001_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/020_valid_parentheses/Makefile b/0020_valid_parentheses/Makefile similarity index 100% rename from 020_valid_parentheses/Makefile rename to 0020_valid_parentheses/Makefile diff --git a/020_valid_parentheses/valid_parentheses.c b/0020_valid_parentheses/valid_parentheses.c similarity index 100% rename from 020_valid_parentheses/valid_parentheses.c rename to 0020_valid_parentheses/valid_parentheses.c diff --git a/020_valid_parentheses/valid_parentheses.cc b/0020_valid_parentheses/valid_parentheses.cc similarity index 100% rename from 020_valid_parentheses/valid_parentheses.cc rename to 0020_valid_parentheses/valid_parentheses.cc diff --git a/021_merge_two_sorted_lists/Makefile b/0021_merge_two_sorted_lists/Makefile similarity index 100% rename from 021_merge_two_sorted_lists/Makefile rename to 0021_merge_two_sorted_lists/Makefile diff --git a/021_merge_two_sorted_lists/merge_lists.c b/0021_merge_two_sorted_lists/merge_lists.c similarity index 71% rename from 021_merge_two_sorted_lists/merge_lists.c rename to 0021_merge_two_sorted_lists/merge_lists.c index 34ecdb0..021a584 100644 --- a/021_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/021_merge_two_sorted_lists/merge_lists.cc b/0021_merge_two_sorted_lists/merge_lists.cc similarity index 69% rename from 021_merge_two_sorted_lists/merge_lists.cc rename to 0021_merge_two_sorted_lists/merge_lists.cc index a5d7a63..58a47f7 100644 --- a/021_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/022_generate_parathesis/Makefile b/0022_generate_parathesis/Makefile similarity index 100% rename from 022_generate_parathesis/Makefile rename to 0022_generate_parathesis/Makefile diff --git a/022_generate_parathesis/parenthesis.c b/0022_generate_parathesis/parenthesis.c similarity index 100% rename from 022_generate_parathesis/parenthesis.c rename to 0022_generate_parathesis/parenthesis.c diff --git a/022_generate_parathesis/parenthesis.cc b/0022_generate_parathesis/parenthesis.cc similarity index 100% rename from 022_generate_parathesis/parenthesis.cc rename to 0022_generate_parathesis/parenthesis.cc 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/023_merge_k_sorted_lists/Makefile b/0023_merge_k_sorted_lists/Makefile similarity index 100% rename from 023_merge_k_sorted_lists/Makefile rename to 0023_merge_k_sorted_lists/Makefile diff --git a/0023_merge_k_sorted_lists/merge_lists.c b/0023_merge_k_sorted_lists/merge_lists.c new file mode 100644 index 0000000..5695b91 --- /dev/null +++ b/0023_merge_k_sorted_lists/merge_lists.c @@ -0,0 +1,182 @@ +#include +#include +#include + +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode { + int val; + struct ListNode *next; +}; + +static inline void swap(struct ListNode **a, struct ListNode **b) +{ + struct ListNode *t = *a; + *a = *b; + *b = t; +} + +static void min_heapify(struct ListNode **nodes, int size, int parent) +{ + int i = parent; /* parent is the root */ + int l = parent * 2 + 1; + int r = parent * 2 + 2; + + if (l < size && nodes[l]->val < nodes[i]->val) { + i = l; + } + + if (r < size && nodes[r]->val < nodes[i]->val) { + i = r; + } + + /* percolate up */ + if (i != parent) { + swap(&nodes[i], &nodes[parent]); + min_heapify(nodes, size, i); + } +} + +static void build_min_heap(struct ListNode **nodes, int size) +{ + int i; + + if (size <= 0) return; + + for (i = size / 2; i >= 0; i--) { + min_heapify(nodes, size, i); + } +} + +static struct ListNode *get(struct ListNode **nodes, int size) +{ + struct ListNode *p = nodes[0]; + nodes[0] = nodes[--size]; + min_heapify(nodes, size, 0); + return p; +} + +static void put(struct ListNode **nodes, int size, struct ListNode *n) +{ + nodes[size++] = n; + build_min_heap(nodes, size); +} + +static struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) +{ + 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* dfs(struct ListNode** lists, int lo, int hi) +{ + if (lo > hi) // listsSize might be zero + return NULL; + + if (lo == hi) + return lists[lo]; + + int mid = lo + (hi - lo) / 2; + return mergeTwoLists(dfs(lists, lo, mid), dfs(lists, mid + 1, hi)); +} + + +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) { + nodes[size++] = lists[i]; + } + } + + 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(nodes, size, n->next); + size++; + } + n->next = NULL; + } + + return dummy.next; +#endif +} + +int main(void) +{ + int i, size; + struct ListNode *p, *prev, *sorted, dummy1, dummy2, **lists; + + dummy1.next = NULL; + prev = &dummy1; + for (i = 0; i < 3; i++) { + p = malloc(sizeof(*p)); + p->val = i * 2; + p->next = NULL; + prev->next = p; + prev = p; + } + for (p = dummy1.next; p != NULL; p = p->next) { + printf("%d ", p->val); + } + putchar('\n'); + + dummy2.next = NULL; + prev = &dummy2; + for (i = 0; i < 5; i++) { + p = malloc(sizeof(*p)); + p->val = i * 2 + 1; + p->next = NULL; + prev->next = p; + prev = p; + } + for (p = dummy2.next; p != NULL; p = p->next) { + printf("%d ", p->val); + } + putchar('\n'); + + size = 2; + lists = malloc(size * sizeof(struct ListNode *)); + lists[0] = NULL;//dummy1.next; + lists[1] = NULL;//dummy2.next; + sorted = mergeKLists(lists, size); + for (p = sorted; p != NULL; p = p->next) { + printf("%d ", p->val); + } + putchar('\n'); + + return 0; +} diff --git a/023_merge_k_sorted_lists/merge_lists.cc b/0023_merge_k_sorted_lists/merge_lists.cc similarity index 87% rename from 023_merge_k_sorted_lists/merge_lists.cc rename to 0023_merge_k_sorted_lists/merge_lists.cc index f2e1556..0e9d8d4 100644 --- a/023_merge_k_sorted_lists/merge_lists.cc +++ b/0023_merge_k_sorted_lists/merge_lists.cc @@ -18,10 +18,10 @@ class Solution { auto cmp = [](struct ListNode *n1, struct ListNode *n2) { return n1->val > n2->val; } - priority_queue, decltype(cmp)> queue(cmp); + priority_queue, decltype(cmp)> queue(cmp); for (int i = 0; i < lists.size(); i++) { - if (lists[] != nullptr) { + if (lists[i] != nullptr) { queue.push(lists[i]); } } diff --git a/024_swap_nodes_in_pairs/Makefile b/0024_swap_nodes_in_pairs/Makefile similarity index 100% rename from 024_swap_nodes_in_pairs/Makefile rename to 0024_swap_nodes_in_pairs/Makefile diff --git a/024_swap_nodes_in_pairs/swap_nodes.c b/0024_swap_nodes_in_pairs/swap_nodes.c similarity index 100% rename from 024_swap_nodes_in_pairs/swap_nodes.c rename to 0024_swap_nodes_in_pairs/swap_nodes.c diff --git a/024_swap_nodes_in_pairs/swap_nodes.cc b/0024_swap_nodes_in_pairs/swap_nodes.cc similarity index 100% rename from 024_swap_nodes_in_pairs/swap_nodes.cc rename to 0024_swap_nodes_in_pairs/swap_nodes.cc diff --git a/025_reverse_nodes_in_k_group/Makefile b/0025_reverse_nodes_in_k_group/Makefile similarity index 100% rename from 025_reverse_nodes_in_k_group/Makefile rename to 0025_reverse_nodes_in_k_group/Makefile diff --git a/025_reverse_nodes_in_k_group/reverse_nodes.c b/0025_reverse_nodes_in_k_group/reverse_nodes.c similarity index 80% rename from 025_reverse_nodes_in_k_group/reverse_nodes.c rename to 0025_reverse_nodes_in_k_group/reverse_nodes.c index c28dab0..ecbe9a1 100644 --- a/025_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/025_reverse_nodes_in_k_group/reverse_nodes.cc b/0025_reverse_nodes_in_k_group/reverse_nodes.cc similarity index 100% rename from 025_reverse_nodes_in_k_group/reverse_nodes.cc rename to 0025_reverse_nodes_in_k_group/reverse_nodes.cc diff --git a/026_remove_duplicates_from_sorted_array/Makefile b/0026_remove_duplicates_from_sorted_array/Makefile similarity index 100% rename from 026_remove_duplicates_from_sorted_array/Makefile rename to 0026_remove_duplicates_from_sorted_array/Makefile diff --git a/026_remove_duplicates_from_sorted_array/rm_dup.c b/0026_remove_duplicates_from_sorted_array/rm_dup.c similarity index 74% rename from 026_remove_duplicates_from_sorted_array/rm_dup.c rename to 0026_remove_duplicates_from_sorted_array/rm_dup.c index 95b2e0b..1bc5764 100644 --- a/026_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/026_remove_duplicates_from_sorted_array/rm_dup.cc b/0026_remove_duplicates_from_sorted_array/rm_dup.cc similarity index 51% rename from 026_remove_duplicates_from_sorted_array/rm_dup.cc rename to 0026_remove_duplicates_from_sorted_array/rm_dup.cc index 2ceef80..ebfc556 100644 --- a/026_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/027_remove_element/Makefile b/0027_remove_element/Makefile similarity index 100% rename from 027_remove_element/Makefile rename to 0027_remove_element/Makefile diff --git a/027_remove_element/rm_elem.c b/0027_remove_element/rm_elem.c similarity index 90% rename from 027_remove_element/rm_elem.c rename to 0027_remove_element/rm_elem.c index 21109fb..6e56505 100644 --- a/027_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/027_remove_element/rm_elem.cc b/0027_remove_element/rm_elem.cc similarity index 100% rename from 027_remove_element/rm_elem.cc rename to 0027_remove_element/rm_elem.cc diff --git a/028_implement_strstr/Makefile b/0028_implement_strstr/Makefile similarity index 100% rename from 028_implement_strstr/Makefile rename to 0028_implement_strstr/Makefile diff --git a/028_implement_strstr/strstr.c b/0028_implement_strstr/strstr.c similarity index 95% rename from 028_implement_strstr/strstr.c rename to 0028_implement_strstr/strstr.c index 24a8c32..f8204ba 100644 --- a/028_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 new file mode 100644 index 0000000..1262839 --- /dev/null +++ b/0028_implement_strstr/strstr.cc @@ -0,0 +1,44 @@ +#include + +using namespace std; + +class Solution { +public: + + // 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/029_divide_two_integers/Makefile b/0029_divide_two_integers/Makefile similarity index 100% rename from 029_divide_two_integers/Makefile rename to 0029_divide_two_integers/Makefile diff --git a/029_divide_two_integers/divide.c b/0029_divide_two_integers/divide.c similarity index 100% rename from 029_divide_two_integers/divide.c rename to 0029_divide_two_integers/divide.c diff --git a/029_divide_two_integers/divide.cc b/0029_divide_two_integers/divide.cc similarity index 100% rename from 029_divide_two_integers/divide.cc rename to 0029_divide_two_integers/divide.cc diff --git a/030_substring_with_concatenation_of_all_words/Makefile b/0030_substring_with_concatenation_of_all_words/Makefile similarity index 100% rename from 030_substring_with_concatenation_of_all_words/Makefile rename to 0030_substring_with_concatenation_of_all_words/Makefile diff --git a/030_substring_with_concatenation_of_all_words/concatenation.c b/0030_substring_with_concatenation_of_all_words/concatenation.c similarity index 63% rename from 030_substring_with_concatenation_of_all_words/concatenation.c rename to 0030_substring_with_concatenation_of_all_words/concatenation.c index aefda09..475cc45 100644 --- a/030_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/030_substring_with_concatenation_of_all_words/concatenation.cc b/0030_substring_with_concatenation_of_all_words/concatenation.cc similarity index 100% rename from 030_substring_with_concatenation_of_all_words/concatenation.cc rename to 0030_substring_with_concatenation_of_all_words/concatenation.cc diff --git a/031_next_permutation/Makefile b/0031_next_permutation/Makefile similarity index 100% rename from 031_next_permutation/Makefile rename to 0031_next_permutation/Makefile diff --git a/031_next_permutation/next_permutation.c b/0031_next_permutation/next_permutation.c similarity index 83% rename from 031_next_permutation/next_permutation.c rename to 0031_next_permutation/next_permutation.c index 49ddbe5..8cd3024 100644 --- a/031_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/031_next_permutation/next_permutation.cc b/0031_next_permutation/next_permutation.cc similarity index 54% rename from 031_next_permutation/next_permutation.cc rename to 0031_next_permutation/next_permutation.cc index d1c7f72..f12077d 100644 --- a/031_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/032_longest_valid_parentheses/Makefile b/0032_longest_valid_parentheses/Makefile similarity index 100% rename from 032_longest_valid_parentheses/Makefile rename to 0032_longest_valid_parentheses/Makefile diff --git a/032_longest_valid_parentheses/valid_parentheses.c b/0032_longest_valid_parentheses/valid_parentheses.c similarity index 100% rename from 032_longest_valid_parentheses/valid_parentheses.c rename to 0032_longest_valid_parentheses/valid_parentheses.c diff --git a/032_longest_valid_parentheses/valid_parentheses.cc b/0032_longest_valid_parentheses/valid_parentheses.cc similarity index 100% rename from 032_longest_valid_parentheses/valid_parentheses.cc rename to 0032_longest_valid_parentheses/valid_parentheses.cc diff --git a/033_search_in_rotated_sorted_array/Makefile b/0033_search_in_rotated_sorted_array/Makefile similarity index 100% rename from 033_search_in_rotated_sorted_array/Makefile rename to 0033_search_in_rotated_sorted_array/Makefile diff --git a/033_search_in_rotated_sorted_array/rotated_array.c b/0033_search_in_rotated_sorted_array/rotated_array.c similarity index 90% rename from 033_search_in_rotated_sorted_array/rotated_array.c rename to 0033_search_in_rotated_sorted_array/rotated_array.c index 822c2ee..07d508c 100644 --- a/033_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/033_search_in_rotated_sorted_array/rotated_array.cc b/0033_search_in_rotated_sorted_array/rotated_array.cc similarity index 88% rename from 033_search_in_rotated_sorted_array/rotated_array.cc rename to 0033_search_in_rotated_sorted_array/rotated_array.cc index 6332d10..67d0ec8 100644 --- a/033_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/034_search_for_a_range/Makefile b/0034_search_for_a_range/Makefile similarity index 100% rename from 034_search_for_a_range/Makefile rename to 0034_search_for_a_range/Makefile diff --git a/034_search_for_a_range/range_search.c b/0034_search_for_a_range/range_search.c similarity index 100% rename from 034_search_for_a_range/range_search.c rename to 0034_search_for_a_range/range_search.c diff --git a/034_search_for_a_range/range_search.cc b/0034_search_for_a_range/range_search.cc similarity index 100% rename from 034_search_for_a_range/range_search.cc rename to 0034_search_for_a_range/range_search.cc diff --git a/035_search_insert_position/Makefile b/0035_search_insert_position/Makefile similarity index 100% rename from 035_search_insert_position/Makefile rename to 0035_search_insert_position/Makefile diff --git a/035_search_insert_position/insert_position.c b/0035_search_insert_position/insert_position.c similarity index 100% rename from 035_search_insert_position/insert_position.c rename to 0035_search_insert_position/insert_position.c diff --git a/035_search_insert_position/insert_position.cc b/0035_search_insert_position/insert_position.cc similarity index 100% rename from 035_search_insert_position/insert_position.cc rename to 0035_search_insert_position/insert_position.cc diff --git a/036_valid_sudoku/Makefile b/0036_valid_sudoku/Makefile similarity index 100% rename from 036_valid_sudoku/Makefile rename to 0036_valid_sudoku/Makefile diff --git a/036_valid_sudoku/valid_sudoku.c b/0036_valid_sudoku/valid_sudoku.c similarity index 100% rename from 036_valid_sudoku/valid_sudoku.c rename to 0036_valid_sudoku/valid_sudoku.c diff --git a/0036_valid_sudoku/valid_sudoku.cc b/0036_valid_sudoku/valid_sudoku.cc new file mode 100644 index 0000000..02fb8e6 --- /dev/null +++ b/0036_valid_sudoku/valid_sudoku.cc @@ -0,0 +1,58 @@ +#include + +using namespace std; + +class Solution { +public: + bool isValidSudoku(vector>& board) { + /* check row validity */ + for (int i = 0; i < board.size(); i++) { + vector mark(10); + /* check row validity */ + for (int j = 0; j < board.size(); j++) { + if (!valid(board, mark, i, j)) { + return false; + } + } + } + + /* check column validity */ + for (int j = 0; j < board.size(); j++) { + vector mark(10); + for (int i = 0; i < board.size(); i++) { + if (!valid(board, mark, i, j)) { + return false; + } + } + } + + /* check sub-box validity */ + for (int k = 0; k < board.size(); k++) { + int sr = k / 3 * 3; + int sc = (k % 3) * 3; + vector mark(10); + for (int i = sr; i < sr + 3; i++) { + for (int j = sc; j < sc + 3; j++) { + if (!valid(board, mark, i, j)) { + return false; + } + } + } + } + + return true; + } + +private: + bool valid(vector>& board, vector& mark, int i, int j) { + if (board[i][j] != '.') { + int index = board[i][j] - '0'; + if (mark[index]) { + return false; + } else { + mark[index] = 1; + } + } + return true; + } +}; diff --git a/037_sudoku_solver/Makefile b/0037_sudoku_solver/Makefile similarity index 100% rename from 037_sudoku_solver/Makefile rename to 0037_sudoku_solver/Makefile diff --git a/037_sudoku_solver/sudoku_solver.c b/0037_sudoku_solver/sudoku_solver.c similarity index 100% rename from 037_sudoku_solver/sudoku_solver.c rename to 0037_sudoku_solver/sudoku_solver.c diff --git a/0037_sudoku_solver/sudoku_solver.cc b/0037_sudoku_solver/sudoku_solver.cc new file mode 100644 index 0000000..1f6503e --- /dev/null +++ b/0037_sudoku_solver/sudoku_solver.cc @@ -0,0 +1,67 @@ +#include + +using namespace std; + +class Solution { +public: + void solveSudoku(vector>& board) { + int size = board.size(); + vector> rows(size, vector(10)); + vector> cols(size, vector(10)); + vector> boxes(size, vector(10)); + + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + if (board[i][j] != '.') { + int num = board[i][j] - '0'; + int idx = i / 3 * 3 + j / 3; + rows[i][num] = true; + cols[j][num] = true; + boxes[idx][num] = true; + } + } + } + + dfs(board, 0, rows, cols, boxes); + } + +private: + bool valid(int num, int row, int col, int idx, vector>& rows, + vector>& cols, vector>& boxes) { + return !rows[row][num] && !cols[col][num] && !boxes[idx][num]; + } + + bool dfs(vector>& board, int size, vector>& rows, + vector>& cols, vector>& boxes) { + if (size == 9 * 9) { + return true; + } else { + bool ok = false; + int row = size / 9; + int col = size % 9; + int idx = row / 3 * 3 + col / 3; + if (board[row][col] == '.') { + for (int i = 1; i <= 9; i++) { + if (valid(i, row, col, idx, rows, cols, boxes)) { + /* lock this grid as well as the number */ + board[row][col] = i + '0'; + rows[row][i] = true; + cols[col][i] = true; + boxes[idx][i] = true; + ok = dfs(board, size + 1, rows, cols, boxes); + if (!ok) { + /* release this grid as well as the number */ + rows[row][i] = false; + cols[col][i] = false; + boxes[idx][i] = false; + board[row][col] = '.'; + } + } + } + } else { + ok = dfs(board, size + 1, rows, cols, boxes); + } + return ok; + } + } +}; diff --git a/038_count_and_say/Makefile b/0038_count_and_say/Makefile similarity index 100% rename from 038_count_and_say/Makefile rename to 0038_count_and_say/Makefile diff --git a/038_count_and_say/count_and_say.c b/0038_count_and_say/count_and_say.c similarity index 100% rename from 038_count_and_say/count_and_say.c rename to 0038_count_and_say/count_and_say.c diff --git a/039_combination_sum/Makefile b/0039_combination_sum/Makefile similarity index 100% rename from 039_combination_sum/Makefile rename to 0039_combination_sum/Makefile diff --git a/039_combination_sum/combination_sum.c b/0039_combination_sum/combination_sum.c similarity index 81% rename from 039_combination_sum/combination_sum.c rename to 0039_combination_sum/combination_sum.c index c360117..0fcb96b 100644 --- a/039_combination_sum/combination_sum.c +++ b/0039_combination_sum/combination_sum.c @@ -2,19 +2,23 @@ #include #include + static void dfs(int *nums, int size, int start, int target, int *stack, int len, int **results, int *count, int *column_sizes) { int i; - if (target == 0) { + if (target < 0) { + return; + } else if (target == 0) { results[*count] = malloc(len * sizeof(int)); memcpy(results[*count], stack, len * sizeof(int)); column_sizes[*count] = len; (*count)++; - } else if (target > 0) { + } else { for (i = start; i < size; i++) { stack[len] = nums[i]; - dfs(nums, size, i, target - nums[i], stack, len + 1, results, column_sizes, count); + /* The elements in solution can be duplicate for the purpose of the problem */ + dfs(nums, size, i, target - nums[i], stack, len + 1, results, count, column_sizes); } } } @@ -24,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 new file mode 100644 index 0000000..a95ab08 --- /dev/null +++ b/0039_combination_sum/combination_sum.cc @@ -0,0 +1,29 @@ +#include + +using namespace std; + +class Solution { +public: + vector> combinationSum(vector& candidates, int target) { + vector> res; + dfs(candidates, 0, target, res); + return res; + } + +private: + vector stack; + void dfs(vector& candidates, int start, int target, vector>& res) { + if (target < 0) { + return; + } else if (target == 0) { + res.push_back(stack); + } else { + for (int i = start; i < candidates.size(); i++) { + stack.push_back(candidates[i]); + /* 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/003_longest_substring_without_repeat/longest_substring_without_repeat.c b/003_longest_substring_without_repeat/longest_substring_without_repeat.c deleted file mode 100644 index 701efa4..0000000 --- a/003_longest_substring_without_repeat/longest_substring_without_repeat.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include - -static int lengthOfLongestSubstring(char *s) -{ - int offset[128]; - int max_len = 0; - int len = 0; - int index = 0; - - 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; - } - offset[*s++] = index++; - } - - return max_len; -} - -int main(int argc, char **argv) -{ - if (argc != 2) { - fprintf(stderr, "Usage: ./test string\n"); - exit(-1); - } - - printf("%d\n", lengthOfLongestSubstring(argv[1])); - return 0; -} diff --git a/003_longest_substring_without_repeat/longest_substring_without_repeat.cc b/003_longest_substring_without_repeat/longest_substring_without_repeat.cc deleted file mode 100644 index 08a12e2..0000000 --- a/003_longest_substring_without_repeat/longest_substring_without_repeat.cc +++ /dev/null @@ -1,30 +0,0 @@ -#include - -using namespace std; - -class Solution { -public: - int lengthOfLongestSubstring(string s) { - vector indexes(128, -1); - int max_len = 0; - int len = 0; - - 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]]; - } - } - max_len = max(max_len, len); - indexes[s[i]] = i; - } - - return max_len; - } -}; diff --git a/040_combination_sum_ii/Makefile b/0040_combination_sum_ii/Makefile similarity index 100% rename from 040_combination_sum_ii/Makefile rename to 0040_combination_sum_ii/Makefile diff --git a/040_combination_sum_ii/combination_sum.c b/0040_combination_sum_ii/combination_sum.c similarity index 62% rename from 040_combination_sum_ii/combination_sum.c rename to 0040_combination_sum_ii/combination_sum.c index a46d3ab..4623149 100644 --- a/040_combination_sum_ii/combination_sum.c +++ b/0040_combination_sum_ii/combination_sum.c @@ -1,36 +1,36 @@ +#include #include #include #include #include + static int compare(const void *a, const void *b) { return *(int *) a - *(int *) b; } -static void dfs(int *nums, int size, int start, int target, int *solution, int len, - bool *used, int **results, int *count, int *column_sizes) +static void dfs(int *nums, int size, int start, int target, int *solution, + int len, int **results, int *count, int *col_sizes) { int i; - if (target == 0) { + if (target < 0) { + return; + } 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 if (target > 0) { + } else { + int last = INT_MIN; for (i = start; i < size; i++) { - if (!used[i]) { - if (i > 0 && !used[i - 1] && nums[i - 1] == nums[i]) { - /* Forbid same elements in same level */ - /* Used marks allow same elements in different levels */ - continue; - } - used[i] = true; + if (last != nums[i]) { + /* No duplicate combinations in the same level position */ solution[len] = nums[i]; - /* i + 1 limits the selecting range in following levels */ - dfs(nums, size, i + 1, target - nums[i], solution, len + 1, used, results, count, column_sizes); - used[i] = false; + /* i + 1 limits the candidate range in next levels */ + dfs(nums, size, i + 1, target - nums[i], solution, len + 1, results, count, col_sizes); } + last = nums[i]; } } } @@ -40,17 +40,15 @@ static void dfs(int *nums, int size, int start, int target, int *solution, int l ** 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); int *solution = malloc(target * sizeof(int)); int **results = malloc(100 * sizeof(int *)); - bool *used = malloc(candidatesSize); - memset(used, false, candidatesSize); *returnColumnSizes = malloc(100 * sizeof(int)); *returnSize = 0; - dfs(candidates, candidatesSize, 0, target, solution, 0, used, results, returnSize, *returnColumnSizes); + dfs(candidates, candidatesSize, 0, target, solution, 0, results, returnSize, *returnColumnSizes); return results; } diff --git a/0040_combination_sum_ii/combination_sum.cc b/0040_combination_sum_ii/combination_sum.cc new file mode 100644 index 0000000..277b432 --- /dev/null +++ b/0040_combination_sum_ii/combination_sum.cc @@ -0,0 +1,35 @@ +#include + +using namespace std; + +class Solution { +public: + vector> combinationSum2(vector& candidates, int target) { + vector> res; + sort(candidates.begin(), candidates.end()); + dfs(candidates, 0, target, res); + return res; + } + +private: + vector stack; + void dfs(vector& candidates, int start, int target, vector>& res) { + if (target < 0) { + return; + } else if (target == 0) { + res.push_back(stack); + } else { + int last = INT_MIN; + for (int i = start; i < candidates.size(); i++) { + if (last != candidates[i]) { + /* 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], res); + stack.pop_back(); + } + last = candidates[i]; + } + } + } +}; diff --git a/041_first_missing_positive/Makefile b/0041_first_missing_positive/Makefile similarity index 100% rename from 041_first_missing_positive/Makefile rename to 0041_first_missing_positive/Makefile diff --git a/041_first_missing_positive/missing_positive.c b/0041_first_missing_positive/missing_positive.c similarity index 86% rename from 041_first_missing_positive/missing_positive.c rename to 0041_first_missing_positive/missing_positive.c index c047ef0..974263d 100644 --- a/041_first_missing_positive/missing_positive.c +++ b/0041_first_missing_positive/missing_positive.c @@ -10,7 +10,7 @@ static inline void swap(int *a, int *b) static int firstMissingPositive(int* nums, int numsSize) { - if (numsSize < 1) { + if (numsSize == 0) { return 1; } @@ -18,7 +18,7 @@ static int firstMissingPositive(int* nums, int numsSize) while (i < numsSize) { /* nums[i] should be i+1 and nums[nums[i] - 1] should be nums[i] */ if (nums[i] != i + 1 && nums[i] > 0 && nums[i] <= numsSize && nums[nums[i] - 1] != nums[i]) { - /* nums[nums[i] - 1] <- nums[i] */ + /* let nums[nums[i] - 1] = nums[i] */ swap(nums + i, nums + nums[i] - 1); } else { i++; @@ -26,8 +26,11 @@ static int firstMissingPositive(int* nums, int numsSize) } for (i = 0; i < numsSize; i++) { - if (nums[i] != i + 1) break; + if (nums[i] != i + 1) { + break; + } } + return i + 1; } diff --git a/0041_first_missing_positive/missing_positive.cc b/0041_first_missing_positive/missing_positive.cc new file mode 100644 index 0000000..4058980 --- /dev/null +++ b/0041_first_missing_positive/missing_positive.cc @@ -0,0 +1,31 @@ +#include + +using namespace std; + +class Solution { +public: + int firstMissingPositive(vector& nums) { + if (nums.size() == 0) { + return 1; + } + + int i = 0; + while (i < nums.size()) { + /* nums[i] should be i+1 and nums[nums[i] - 1] should be nums[i] */ + if (nums[i] > 0 && nums[i] != i + 1 && nums[i] - 1 < nums.size() && nums[nums[i] - 1] != nums[i]) { + // Let nums[nums[i] - 1] = nums[i] + swap(nums[i], nums[nums[i] - 1]); + } else { + i++; + } + } + + for (i = 0; i < nums.size(); i++) { + if (nums[i] != i + 1) { + break; + } + } + + return i + 1; + } +}; diff --git a/042_trapping_rain_water/Makefile b/0042_trapping_rain_water/Makefile similarity index 100% rename from 042_trapping_rain_water/Makefile rename to 0042_trapping_rain_water/Makefile diff --git a/0042_trapping_rain_water/trap_water.c b/0042_trapping_rain_water/trap_water.c new file mode 100644 index 0000000..d0abc5b --- /dev/null +++ b/0042_trapping_rain_water/trap_water.c @@ -0,0 +1,66 @@ +#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) +{ + /* In fact if we find the relative higher bar position and then the + * water level of the position would be determined by the opposite side. + */ + int res = 0; + int l = 0, lmax = 0; + int r = heightSize - 1, rmax = 0; + + while (l < r) { + /* 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 { + res += rmax - height[r]; + r--; + } + } + + return res; +} + +int main(int argc, char **argv) +{ + int i, count = argc - 1; + int *nums = malloc(count * sizeof(int)); + for (i = 0; i < count; i++) { + nums[i] = atoi(argv[i + 1]); + } + printf("%d\n", trap(nums, count)); + return 0; +} diff --git a/0042_trapping_rain_water/trap_water.cc b/0042_trapping_rain_water/trap_water.cc new file mode 100644 index 0000000..5649a61 --- /dev/null +++ b/0042_trapping_rain_water/trap_water.cc @@ -0,0 +1,31 @@ +#include + +using namespace std; + +class Solution { +public: + int trap(vector& height) { + /* In fact if we find the relative higher bar position and then the + * water level of the position would be determined by the opposite side. + */ + int res = 0; + 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 { + res += r_max - height[r]; + r--; + } + } + + return res; + } +}; diff --git a/043_multiply_strings/Makefile b/0043_multiply_strings/Makefile similarity index 100% rename from 043_multiply_strings/Makefile rename to 0043_multiply_strings/Makefile diff --git a/0043_multiply_strings/multiply_strings.c b/0043_multiply_strings/multiply_strings.c new file mode 100644 index 0000000..9143d10 --- /dev/null +++ b/0043_multiply_strings/multiply_strings.c @@ -0,0 +1,48 @@ +#include +#include +#include + + +static char* multiply(char* num1, char* num2) +{ + if (*num1 == '\0') { + return num1; + } + + if (*num2 == '\0') { + return num2; + } + + int i, j; + int len1 = strlen(num1); + int len2 = strlen(num2); + char *result = malloc(len1 + len2 + 1); + memset(result, '0', len1 + len2 + 1); + result[len1 + len2] = '\0'; + + for (i = len2 - 1; i >= 0; i--) { + int carry = 0; + for (j = len1 - 1; j >= 0; j--) { + carry += (num2[i] - '0') * (num1[j] - '0') + (result[i + j + 1] - '0'); + result[i + j + 1] = carry % 10 + '0'; + carry /= 10; + } + result[i + j + 1] = carry + '0'; + } + + while (result[0] == '0' && result[1] != '\0') { + result++; + } + + return result; +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./test m1 m2\n"); + exit(-1); + } + printf("%s\n", multiply(argv[1], argv[2])); + return 0; +} diff --git a/0043_multiply_strings/multiply_strings.cc b/0043_multiply_strings/multiply_strings.cc new file mode 100644 index 0000000..77436e4 --- /dev/null +++ b/0043_multiply_strings/multiply_strings.cc @@ -0,0 +1,27 @@ +#include + +using namespace std; + +class Solution { +public: + string multiply(string num1, string num2) { + string res(num1.length() + num2.length(), '0'); + for (int i = num2.length() - 1; i >= 0; i--) { + int j, carry = 0; + for (j = num1.length() - 1; j >= 0; j--) { + carry += (num1[j] - '0') * (num2[i] - '0') + (res[i + j + 1] - '0'); + res[i + j + 1] = carry % 10 + '0'; + carry /= 10; + } + res[i + j + 1] = carry + '0'; + } + + int i; + for (i = 0; i < res.length() - 1; i++) { + if (res[i] != '0') { + break; + } + } + return res.substr(i); + } +}; diff --git a/044_wildcard_matching/Makefile b/0044_wildcard_matching/Makefile similarity index 100% rename from 044_wildcard_matching/Makefile rename to 0044_wildcard_matching/Makefile diff --git a/0044_wildcard_matching/wildcard_matching.c b/0044_wildcard_matching/wildcard_matching.c new file mode 100644 index 0000000..34dd54b --- /dev/null +++ b/0044_wildcard_matching/wildcard_matching.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include + + +static bool isMatch(char* s, char* p) +{ + char *last_s = NULL; + char *last_p = NULL; + while (*s != '\0') { + if (*p == '*') { + /* skip the '*', and mark a flag */ + if (*++p == '\0') { + return true; + } + /* use last_s and last_p to store where the "*" match starts. */ + last_s = s; + last_p = p; + } else if (*p == '?' || *s == *p) { + s++; + p++; + } else if (last_s != NULL) { + /* check "last_s" to know whether meet "*" before + * if meet "*" previously, and the *s != *p + * reset the p, using '*' to match this situation + */ + p = last_p; + s = ++last_s; + } else { + /* *p is not wildcard char, + * doesn't match *s, + * there are no '*' wildcard matched before + */ + return false; + } + } + + /* s is done, but "p" still have chars. */ + while (*p == '*') { + p++; + } + return *p == '\0'; +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./test string pattern\n"); + exit(-1); + } + + printf("%s\n", isMatch(argv[1], argv[2]) ? "true" : "false"); + return 0; +} diff --git a/045_jump_game_ii/Makefile b/0045_jump_game_ii/Makefile similarity index 100% rename from 045_jump_game_ii/Makefile rename to 0045_jump_game_ii/Makefile diff --git a/0045_jump_game_ii/jump_game.c b/0045_jump_game_ii/jump_game.c new file mode 100644 index 0000000..0d9ffb2 --- /dev/null +++ b/0045_jump_game_ii/jump_game.c @@ -0,0 +1,39 @@ +#include +#include + + +static inline int max(int a, int b) +{ + return a > b ? a : b; +} + +static int jump(int* nums, int numsSize) +{ + int i, right = 0; + int steps = 0; + int fartest = 0; + /* 1. Exhaust all the right boundries in the location range of [i...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++; + } + } + + return steps; +} + +int main(int argc, char **argv) +{ + int i, count = argc - 1; + int *nums = malloc(count * sizeof(int)); + for (i = 0; i < count; i++) { + nums[i] = atoi(argv[i + 1]); + } + printf("%d\n", jump(nums, count)); + return 0; +} diff --git a/0045_jump_game_ii/jump_game.cc b/0045_jump_game_ii/jump_game.cc new file mode 100644 index 0000000..cf61281 --- /dev/null +++ b/0045_jump_game_ii/jump_game.cc @@ -0,0 +1,25 @@ +#include + +using namespace std; + +class Solution { +public: + int jump(vector& nums) { + int steps = 0; + 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++; + } + } + + return steps; + } +}; diff --git a/046_permutations/Makefile b/0046_permutations/Makefile similarity index 100% rename from 046_permutations/Makefile rename to 0046_permutations/Makefile diff --git a/046_permutations/permutations.c b/0046_permutations/permutations.c similarity index 51% rename from 046_permutations/permutations.c rename to 0046_permutations/permutations.c index 009669c..49b0b73 100644 --- a/046_permutations/permutations.c +++ b/0046_permutations/permutations.c @@ -3,6 +3,7 @@ #include #include +#if 0 static void swap(int *a, int *b) { int tmp = *a; @@ -10,6 +11,27 @@ static void swap(int *a, int *b) *b = tmp; } +static void dfs(int *nums, int size, int start, + int **results, int *count, int *col_size) +{ + int i; + if (start == size) { + results[*count] = malloc(size * sizeof(int)); + memcpy(results[*count], nums, size * sizeof(int)); + col_size[*count] = size; + (*count)++; + } else { + for (i = start; i < size; i++) { + /* A swap can make a new permutation but not be listed in order */ + swap(nums + start, nums + i); + dfs(nums, size, start + 1, results, count, col_size); + /* restore the array in backtrace */ + swap(nums + start, nums + i); + } + } +} +#endif + static void dfs(int *nums, int size, bool *used, int *stack, int len, int **results, int *count, int *col_size) { @@ -19,14 +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 { - for (i = 0; i < size; i++) { - if (!used[i]) { - 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; } } } @@ -34,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 *)); @@ -62,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 new file mode 100644 index 0000000..35b4efe --- /dev/null +++ b/0046_permutations/permutations.cc @@ -0,0 +1,35 @@ +#include + +using namespace std; + +class Solution { +public: + vector> permute(vector& nums) { + vector> res; + vector used(nums.size()); + dfs(nums, used, res); + return res; + } + +private: + vector stack; + void dfs(vector& nums, vector& used, vector>& res) { + if (stack.size() == nums.size()) { + res.push_back(stack); + 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/047_permutations_ii/Makefile b/0047_permutations_ii/Makefile similarity index 100% rename from 047_permutations_ii/Makefile rename to 0047_permutations_ii/Makefile diff --git a/047_permutations_ii/permutations.c b/0047_permutations_ii/permutations.c similarity index 62% rename from 047_permutations_ii/permutations.c rename to 0047_permutations_ii/permutations.c index 1ba93e2..612867b 100644 --- a/047_permutations_ii/permutations.c +++ b/0047_permutations_ii/permutations.c @@ -12,24 +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 { - for (i = 0; i < size; i++) { - if (!used[i]) { - if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]) { - /* Forbid same elements on same level */ - /* Used marks allow same elements in different levels */ - 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; } } } @@ -46,8 +51,8 @@ static int **permute(int* nums, int numsSize, int* returnSize, int **returnColum int count = 0, cap = 10000; int *stack = malloc(numsSize * sizeof(int)); int **results = malloc(cap * sizeof(int *)); - bool *used = malloc(numsSize); - memset(used, false, numsSize); + bool *used = malloc(numsSize * sizeof(bool)); + memset(used, false, numsSize * sizeof(bool)); *returnSize = 0; *returnColumnSize = malloc(cap * sizeof(int)); dfs(nums, numsSize, used, stack, 0, results, returnSize, *returnColumnSize); @@ -67,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 new file mode 100644 index 0000000..de8bdff --- /dev/null +++ b/0047_permutations_ii/permutations.cc @@ -0,0 +1,39 @@ +#include + +using namespace std; + +class Solution { +public: + vector> permuteUnique(vector& nums) { + vector> res; + vector used(nums.size()); + sort(nums.begin(), nums.end()); + dfs(nums, used, res); + return res; + } + +private: + 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 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.push_back(nums[i]); + used[i] = true; + dfs(nums, used, res); + stack.pop_back(); + used[i] = false; + } + } + } + } +}; diff --git a/048_rotate_image/Makefile b/0048_rotate_image/Makefile similarity index 100% rename from 048_rotate_image/Makefile rename to 0048_rotate_image/Makefile diff --git a/0048_rotate_image/rotate.c b/0048_rotate_image/rotate.c new file mode 100644 index 0000000..b519ad9 --- /dev/null +++ b/0048_rotate_image/rotate.c @@ -0,0 +1,49 @@ +#include +#include + +static void rotate(int** matrix, int matrixSize, int *matrixColSize) +{ + int i, j; + for (i = 0; i < matrixSize / 2; i++) { + int col_size = matrixColSize[i]; + int low = i, high = col_size - i - 1; + for (j = low; j < high; j++) { + int tmp = matrix[i][j]; + matrix[i][j] = matrix[col_size - 1 - j][i]; + matrix[col_size - 1 - j][i] = matrix[matrixSize - 1 - i][col_size - 1 - j]; + matrix[matrixSize - 1 - i][col_size - 1 - j] = matrix[j][matrixSize - 1 - i]; + matrix[j][matrixSize - 1 - i] = tmp; + } + } +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test 3\n"); + } + + int i, j, count = 0; + int row_size = atoi(argv[1]); + int *col_sizes = malloc(row_size * sizeof(int)); + int **matrix = malloc(row_size * sizeof(int *)); + for (i = 0; i < row_size; i++) { + col_sizes[i] = row_size; + matrix[i] = malloc(col_sizes[i] * sizeof(int)); + for (j = 0; j < col_sizes[i]; j++) { + matrix[i][j] = ++count; + printf("%d ", matrix[i][j]); + } + printf("\n"); + } + + rotate(matrix, row_size, col_sizes); + for (i = 0; i < row_size; i++) { + for (j = 0; j < col_sizes[i]; j++) { + printf("%02d ", matrix[i][j]); + } + putchar('\n'); + } + + return 0; +} diff --git a/0048_rotate_image/rotate.cc b/0048_rotate_image/rotate.cc new file mode 100644 index 0000000..806e151 --- /dev/null +++ b/0048_rotate_image/rotate.cc @@ -0,0 +1,20 @@ +#include + +using namespace std; + +class Solution { +public: + void rotate(vector>& matrix) { + int size = matrix.size(); + for (int i = 0; i < size / 2; i++) { + int low = i, high = size - i - 1; + for (int j = low; j < high; j++) { + int tmp = matrix[i][j]; + matrix[i][j] = matrix[size - 1 - j][i]; + matrix[size - 1 - j][i] = matrix[size - 1 - i][size - 1 - j]; + matrix[size - 1 - i][size - 1 - j] = matrix[j][size - 1 - i]; + matrix[j][size - 1 - i] = tmp; + } + } + } +}; diff --git a/049_group_anagrams/Makefile b/0049_group_anagrams/Makefile similarity index 100% rename from 049_group_anagrams/Makefile rename to 0049_group_anagrams/Makefile diff --git a/049_group_anagrams/anagrams.c b/0049_group_anagrams/anagrams.c similarity index 75% rename from 049_group_anagrams/anagrams.c rename to 0049_group_anagrams/anagrams.c index 710b4d6..fb9765f 100644 --- a/049_group_anagrams/anagrams.c +++ b/0049_group_anagrams/anagrams.c @@ -2,6 +2,7 @@ #include #include + struct word_hash { char *word; int num; @@ -25,10 +26,10 @@ static inline int BKDRHash(char *s, size_t size) /** ** Return an array of arrays of size *returnSize. - ** The sizes of the arrays are returned as *columnSizes array. - ** Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). + ** 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** columnSizes, int* returnSize) +char*** groupAnagrams(char** strs, int strsSize, int* returnSize, int** returnColumnSizes) { int i, j, count = 0; int hash_size = strsSize; @@ -42,7 +43,7 @@ static char*** groupAnagrams(char** strs, int strsSize, int** columnSizes, int* qsort(words[i], len, sizeof(char), compare); int hash = BKDRHash(words[i], hash_size); /* find available hash bucket */ - for (j = hash; ht[j].num > 0 && strcmp(ht[j].word, words[i]); j = ++j % hash_size) {} + for (j = hash; ht[j].num > 0 && strcmp(ht[j].word, words[i]); j = (j + 1) % hash_size) {} if (ht[j].num == 0) { ht[j].word = words[i]; count++; @@ -51,12 +52,11 @@ static char*** groupAnagrams(char** strs, int strsSize, int** columnSizes, int* } int k = 0; - struct hlist_node *p; char ***lists = malloc(count * sizeof(char **)); - *columnSizes = malloc(count * sizeof(int)); + *returnColumnSizes = malloc(count * sizeof(int)); for (i = 0; i < hash_size; i++) { if (ht[i].num > 0) { - (*columnSizes)[k] = ht[i].num; + (*returnColumnSizes)[k] = ht[i].num; lists[k] = malloc(ht[i].num * sizeof(char *)); for (j = 0; j < ht[i].num; j++) { int index = ht[i].indexes[j]; @@ -72,10 +72,10 @@ static char*** groupAnagrams(char** strs, int strsSize, int** columnSizes, int* int main(int argc, char **argv) { - int *column_sizes, count = 0, i, j; - char ***lists = groupAnagrams(argv + 1, argc - 1, &column_sizes, &count); + 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 new file mode 100644 index 0000000..0090531 --- /dev/null +++ b/0049_group_anagrams/anagrams.cc @@ -0,0 +1,30 @@ +#include + +using namespace std; + +class Solution { +public: + vector> groupAnagrams(vector& strs) { + vector> res; + unordered_map> ht; + for (const auto& str : strs) { + int counts[26] = { 0 }; + for (char c : str) { + counts[c - 'a']++; + } + + string key; + for (int i : counts) { + key.push_back('#'); + key.push_back(i + '0'); + } + + ht[key].push_back(str); + } + + for (const auto& t : ht) { + res.push_back(t.second); + } + return res; + } +}; diff --git a/050_pow/Makefile b/0050_pow/Makefile similarity index 100% rename from 050_pow/Makefile rename to 0050_pow/Makefile diff --git a/050_pow/pow.c b/0050_pow/pow.c similarity index 87% rename from 050_pow/pow.c rename to 0050_pow/pow.c index ce98a46..065e92f 100644 --- a/050_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/0050_pow/pow.cc b/0050_pow/pow.cc new file mode 100644 index 0000000..1b925cb --- /dev/null +++ b/0050_pow/pow.cc @@ -0,0 +1,27 @@ +#include + +using namespace std; + +class Solution { +public: + double myPow(double x, int n) { + if (n == INT_MIN) { + double t = dfs(x, -(n / 2)); + return 1 / t * 1 / t; + } else { + return n < 0 ? 1 / dfs(x, -n) : dfs(x, n); + } + } + +private: + double dfs(double x, int n) { + if (n == 0) { + return 1; + } else if (n == 1) { + return x; + } else { + double t = dfs(x, n / 2); + return (n % 2) ? (x * t * t) : (t * t); + } + } +}; diff --git a/051_n_queens/Makefile b/0051_n_queens/Makefile similarity index 100% rename from 051_n_queens/Makefile rename to 0051_n_queens/Makefile diff --git a/051_n_queens/n_queens.c b/0051_n_queens/n_queens.c similarity index 97% rename from 051_n_queens/n_queens.c rename to 0051_n_queens/n_queens.c index 0b2a1c5..5892c12 100644 --- a/051_n_queens/n_queens.c +++ b/0051_n_queens/n_queens.c @@ -65,7 +65,6 @@ static void dfs(int n, int row, int *stack, char ***solutions, int *count, int * if (row == 0 || !conflict(stack, row, col)) { stack[row] = col; dfs(n, row + 1, stack, solutions, count, col_sizes); - continue; } } } @@ -74,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/0051_n_queens/n_queens.cc b/0051_n_queens/n_queens.cc new file mode 100644 index 0000000..7b44b99 --- /dev/null +++ b/0051_n_queens/n_queens.cc @@ -0,0 +1,40 @@ +#include + +using namespace std; + +class Solution { +public: + vector> solveNQueens(int n) { + vector> res; + vector stack(n); + vector solution(n, string(n, '.')); + dfs(n, 0, stack, solution, res); + return res; + } + +private: + void dfs(int n, int row, vector& stack, vector& solution, vector>& res) { + if (row == n) { + res.push_back(solution); + } else { + for (int i = 0; i < n; i++) { + if (row == 0 || !conflict(stack, row, i)) { + solution[row][i] = 'Q'; + stack[row] = i; + dfs(n, row + 1, stack, solution, res); + solution[row][i] = '.'; + } + } + } + } + + bool conflict(vector& stack, int row, int col) { + for (int i = 0; i < row; i++) { + /* If occupied or in one line */ + if (col == stack[i] || abs(row - i) == abs(col - stack[i])) { + return true; + } + } + return false; + } +} diff --git a/052_n_queens_ii/Makefile b/0052_n_queens_ii/Makefile similarity index 100% rename from 052_n_queens_ii/Makefile rename to 0052_n_queens_ii/Makefile diff --git a/052_n_queens_ii/n_queens.c b/0052_n_queens_ii/n_queens.c similarity index 100% rename from 052_n_queens_ii/n_queens.c rename to 0052_n_queens_ii/n_queens.c diff --git a/0052_n_queens_ii/n_queens.cc b/0052_n_queens_ii/n_queens.cc new file mode 100644 index 0000000..ace2dc6 --- /dev/null +++ b/0052_n_queens_ii/n_queens.cc @@ -0,0 +1,37 @@ +#include + +using namespace std; + +class Solution { +public: + int totalNQueens(int n) { + vector stack(n); + return dfs(n, 0, stack); + } + +private: + int dfs(int n, int row, vector& stack) { + int count = 0; + if (row == n) { + return count + 1; + } else { + for (int i = 0; i < n; i++) { + if (row == 0 || !conflict(stack, row, i)) { + stack[row] = i; + count += dfs(n, row + 1, stack); + } + } + return count; + } + } + + bool conflict(vector& stack, int row, int col) { + for (int i = 0; i < row; i++) { + /* If occupied or in one line */ + if (col == stack[i] || abs(row - i) == abs(col - stack[i])) { + return true; + } + } + return false; + } +} diff --git a/053_maximum_subarray/Makefile b/0053_maximum_subarray/Makefile similarity index 100% rename from 053_maximum_subarray/Makefile rename to 0053_maximum_subarray/Makefile diff --git a/053_maximum_subarray/max_subarray.c b/0053_maximum_subarray/max_subarray.c similarity index 100% rename from 053_maximum_subarray/max_subarray.c rename to 0053_maximum_subarray/max_subarray.c diff --git a/0053_maximum_subarray/max_subarray.cc b/0053_maximum_subarray/max_subarray.cc new file mode 100644 index 0000000..834c1e8 --- /dev/null +++ b/0053_maximum_subarray/max_subarray.cc @@ -0,0 +1,19 @@ +#include + +using namespace std; + +class Solution { +public: + int maxSubArray(vector& nums) { + int sum = 0, max_sum = INT_MIN; + for (int i = 0; i < nums.size(); i++) { + if (sum < 0) { + sum = nums[i]; + } else { + sum += nums[i]; + } + max_sum = max(sum, max_sum); + } + return max_sum; + } +}; diff --git a/054_spiral_matrix/Makefile b/0054_spiral_matrix/Makefile similarity index 100% rename from 054_spiral_matrix/Makefile rename to 0054_spiral_matrix/Makefile diff --git a/054_spiral_matrix/spiral_matrix.c b/0054_spiral_matrix/spiral_matrix.c similarity index 72% rename from 054_spiral_matrix/spiral_matrix.c rename to 0054_spiral_matrix/spiral_matrix.c index 54114ea..5ae413f 100644 --- a/054_spiral_matrix/spiral_matrix.c +++ b/0054_spiral_matrix/spiral_matrix.c @@ -1,16 +1,22 @@ #include #include + /** ** Note: The returned array must be malloced, assume caller calls free(). **/ -static int* spiralOrder(int** matrix, int matrixRowSize, int matrixColSize) +int* spiralOrder(int** matrix, int matrixSize, int *matrixColSize, int *returnSize) { + if (matrixSize == 0) { + *returnSize = 0; + return NULL; + } + int hor_top = 0; - int hor_bottom = matrixRowSize - 1; + int hor_bottom = matrixSize - 1; int ver_left = 0; - int ver_right = matrixColSize - 1; - int *nums = malloc(matrixRowSize * matrixColSize * sizeof(int)); + int ver_right = matrixColSize[0] - 1; + int *nums = malloc(matrixSize * matrixColSize[0] * sizeof(int)); int count = 0; int i, direction = 0; @@ -47,6 +53,7 @@ static int* spiralOrder(int** matrix, int matrixRowSize, int matrixColSize) direction %= 4; } + *returnSize = count; return nums; } @@ -54,20 +61,23 @@ int main(int argc, char **argv) { int i, j, count = 0; int row = 3; - int col = 3; + int *cols = malloc(row * sizeof(int)); int **mat = malloc(row * sizeof(int *)); for (i = 0; i < row; i++) { - mat[i] = malloc(col * sizeof(int)); - for (j = 0; j < col; j++) { + cols[i] = row; + mat[i] = malloc(cols[i] * sizeof(int)); + for (j = 0; j < cols[i]; j++) { mat[i][j] = ++count; printf("%d ", mat[i][j]); } printf("\n"); } - int *nums = spiralOrder(mat, row, col); - for (i = 0; i < row * col; i++) { + + int *nums = spiralOrder(mat, row, cols, &count); + for (i = 0; i < count; i++) { printf("%d ", nums[i]); } printf("\n"); + return 0; } diff --git a/0054_spiral_matrix/spiral_matrix.cc b/0054_spiral_matrix/spiral_matrix.cc new file mode 100644 index 0000000..b411d33 --- /dev/null +++ b/0054_spiral_matrix/spiral_matrix.cc @@ -0,0 +1,49 @@ +#include + +using namespace std; + +class Solution { +public: + vector spiralOrder(vector>& matrix) { + vector res; + int hor_top = 0; + int hor_bottom = matrix.size() - 1; + int ver_left = 0; + int ver_right = matrix[0].size() - 1; + int direction = 0; + while (hor_top <= hor_bottom && ver_left <= ver_right) { + switch (direction) { + case 0: + for (int i = ver_left; i <= ver_right; i++) { + res.push_back(matrix[hor_top][i]); + } + hor_top++; + break; + case 1: + for (int i = hor_top; i <= hor_bottom; i++) { + res.push_back(matrix[i][ver_right]); + } + ver_right--; + break; + case 2: + for (int i = ver_right; i >= ver_left; i--) { + res.push_back(matrix[hor_bottom][i]); + } + hor_bottom--; + break; + case 3: + for (int i = hor_bottom; i >= hor_top; i--) { + res.push_back(matrix[i][ver_left]); + } + ver_left++; + break; + default: + break; + } + direction++; + direction %= 4; + } + + return res; + } +}; diff --git a/055_jump_game/Makefile b/0055_jump_game/Makefile similarity index 100% rename from 055_jump_game/Makefile rename to 0055_jump_game/Makefile diff --git a/055_jump_game/jump_game.c b/0055_jump_game/jump_game.c similarity index 93% rename from 055_jump_game/jump_game.c rename to 0055_jump_game/jump_game.c index 7dd5825..66e454b 100644 --- a/055_jump_game/jump_game.c +++ b/0055_jump_game/jump_game.c @@ -12,6 +12,7 @@ static bool canJump(int* nums, int numsSize) int i, pos = 0; for (i = 0; i < numsSize - 1; i++) { if (pos < i || pos >= numsSize - 1) { + /* pos < i means nums[pos] == 0 */ break; } /* if all positive number it always can arrive. */ diff --git a/056_merge_intervals/Makefile b/0056_merge_intervals/Makefile similarity index 100% rename from 056_merge_intervals/Makefile rename to 0056_merge_intervals/Makefile diff --git a/056_merge_intervals/merge_intervals.c b/0056_merge_intervals/merge_intervals.c similarity index 93% rename from 056_merge_intervals/merge_intervals.c rename to 0056_merge_intervals/merge_intervals.c index c9ca555..133a778 100644 --- a/056_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) { @@ -36,6 +36,7 @@ int** merge(int** intervals, int intervalsSize, int* intervalsColSize, int* retu intervals[len][0] = tmp[i * 2]; intervals[len][1] = tmp[i * 2 + 1]; } else if (tmp[i * 2 + 1] > intervals[len][1]) { + /* merge this interval */ intervals[len][1] = tmp[i * 2 + 1]; } } diff --git a/057_insert_interval/Makefile b/0057_insert_interval/Makefile similarity index 100% rename from 057_insert_interval/Makefile rename to 0057_insert_interval/Makefile diff --git a/057_insert_interval/insert_interval.c b/0057_insert_interval/insert_interval.c similarity index 90% rename from 057_insert_interval/insert_interval.c rename to 0057_insert_interval/insert_interval.c index 02cb9a3..b97da9a 100644 --- a/057_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)); @@ -35,6 +36,7 @@ int** insert(int** intervals, int intervalsSize, int* intervalsColSize, int* new results[len][0] = tmp[i * 2]; results[len][1] = tmp[i * 2 + 1]; } else if (tmp[i * 2 + 1] > results[len][1]) { + /* merge this interval */ results[len][1] = tmp[i * 2 + 1]; } } diff --git a/058_length_of_last_word/Makefile b/0058_length_of_last_word/Makefile similarity index 100% rename from 058_length_of_last_word/Makefile rename to 0058_length_of_last_word/Makefile diff --git a/058_length_of_last_word/word_length.c b/0058_length_of_last_word/word_length.c similarity index 56% rename from 058_length_of_last_word/word_length.c rename to 0058_length_of_last_word/word_length.c index b18cec9..bad2085 100644 --- a/058_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/059_spiral_matrix_ii/Makefile b/0059_spiral_matrix_ii/Makefile similarity index 100% rename from 059_spiral_matrix_ii/Makefile rename to 0059_spiral_matrix_ii/Makefile diff --git a/059_spiral_matrix_ii/spiral_matrix.c b/0059_spiral_matrix_ii/spiral_matrix.c similarity index 74% rename from 059_spiral_matrix_ii/spiral_matrix.c rename to 0059_spiral_matrix_ii/spiral_matrix.c index a224c50..d4c5339 100644 --- a/059_spiral_matrix_ii/spiral_matrix.c +++ b/0059_spiral_matrix_ii/spiral_matrix.c @@ -1,16 +1,22 @@ #include #include + /** - ** Return an array of arrays. - ** Note: The returned array must be malloced, assume caller calls free(). - **/ -static int** generateMatrix(int n) { + * 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** generateMatrix(int n, int* returnSize, int** returnColumnSizes) +{ int i; int **matrix = malloc(n * sizeof(int *)); int *nums = malloc(n * n * sizeof(int)); + *returnSize = n; + *returnColumnSizes = malloc(n * sizeof(int)); for (i = 0; i < n; i++) { matrix[i] = &nums[i * n]; + (*returnColumnSizes)[i] = n; } int direction = 0; @@ -60,9 +66,10 @@ int main(int argc, char **argv) exit(-1); } - int i, j; + int i, j, count; int n = atoi(argv[1]); - int **matrix = generateMatrix(n); + int *col_sizes; + int **matrix = generateMatrix(n, &count, &col_sizes); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { printf("%d ", matrix[i][j]); 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/060_permutation_sequence/Makefile b/0060_permutation_sequence/Makefile similarity index 100% rename from 060_permutation_sequence/Makefile rename to 0060_permutation_sequence/Makefile diff --git a/060_permutation_sequence/permutation_sequence.c b/0060_permutation_sequence/permutation_sequence.c similarity index 100% rename from 060_permutation_sequence/permutation_sequence.c rename to 0060_permutation_sequence/permutation_sequence.c diff --git a/061_rotate_list/Makefile b/0061_rotate_list/Makefile similarity index 100% rename from 061_rotate_list/Makefile rename to 0061_rotate_list/Makefile diff --git a/061_rotate_list/rotate_list.c b/0061_rotate_list/rotate_list.c similarity index 77% rename from 061_rotate_list/rotate_list.c rename to 0061_rotate_list/rotate_list.c index 9f8eb56..ae77398 100644 --- a/061_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/062_unique_path/Makefile b/0062_unique_path/Makefile similarity index 100% rename from 062_unique_path/Makefile rename to 0062_unique_path/Makefile diff --git a/062_unique_path/unique_path.c b/0062_unique_path/unique_path.c similarity index 100% rename from 062_unique_path/unique_path.c rename to 0062_unique_path/unique_path.c diff --git a/063_unique_paths_ii/Makefile b/0063_unique_paths_ii/Makefile similarity index 100% rename from 063_unique_paths_ii/Makefile rename to 0063_unique_paths_ii/Makefile diff --git a/063_unique_paths_ii/unique_path.c b/0063_unique_paths_ii/unique_path.c similarity index 100% rename from 063_unique_paths_ii/unique_path.c rename to 0063_unique_paths_ii/unique_path.c diff --git a/064_minumum_path_sum/Makefile b/0064_minumum_path_sum/Makefile similarity index 100% rename from 064_minumum_path_sum/Makefile rename to 0064_minumum_path_sum/Makefile diff --git a/064_minumum_path_sum/minimum_path_sum.c b/0064_minumum_path_sum/minimum_path_sum.c similarity index 100% rename from 064_minumum_path_sum/minimum_path_sum.c rename to 0064_minumum_path_sum/minimum_path_sum.c diff --git a/065_valid_number/Makefile b/0065_valid_number/Makefile similarity index 100% rename from 065_valid_number/Makefile rename to 0065_valid_number/Makefile diff --git a/065_valid_number/valid_number.c b/0065_valid_number/valid_number.c similarity index 100% rename from 065_valid_number/valid_number.c rename to 0065_valid_number/valid_number.c diff --git a/066_plus_one/Makefile b/0066_plus_one/Makefile similarity index 100% rename from 066_plus_one/Makefile rename to 0066_plus_one/Makefile diff --git a/066_plus_one/plus_one.c b/0066_plus_one/plus_one.c similarity index 81% rename from 066_plus_one/plus_one.c rename to 0066_plus_one/plus_one.c index 4f6005c..a613f37 100644 --- a/066_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/0066_plus_one/plus_one.cc b/0066_plus_one/plus_one.cc new file mode 100644 index 0000000..902f431 --- /dev/null +++ b/0066_plus_one/plus_one.cc @@ -0,0 +1,23 @@ +#include + +using namespace std; + +class Solution { +public: + vector plusOne(vector& digits) { + int carry = 1; + vector res; + for (int i = digits.size() - 1; i >= 0; i--) { + int d = digits[i] + carry; + res.push_back(d % 10); + carry = d / 10; + } + + if (carry > 0) { + res.push_back(carry); + } + + reverse(res.begin(), res.end()); + return res; + } +}; diff --git a/067_add_binary/Makefile b/0067_add_binary/Makefile similarity index 100% rename from 067_add_binary/Makefile rename to 0067_add_binary/Makefile diff --git a/067_add_binary/add_binary.c b/0067_add_binary/add_binary.c similarity index 100% rename from 067_add_binary/add_binary.c rename to 0067_add_binary/add_binary.c diff --git a/0067_add_binary/add_binary.cc b/0067_add_binary/add_binary.cc new file mode 100644 index 0000000..aa44444 --- /dev/null +++ b/0067_add_binary/add_binary.cc @@ -0,0 +1,74 @@ +#include + +using namespace std; + +class Solution { +public: + string addBinary(string a, string b) { + string res; + int carry = 0; + int i = a.length() - 1; + int j = b.length() - 1; + for (; i >= 0 && j >= 0; i--, j--) { + if (a[i] == '1' && b[j] == '1') { + if (carry > 0) { + res.push_back('1'); + } else { + res.push_back('0'); + } + carry = 1; + } else if (a[i] == '0' && b[j] == '0') { + if (carry > 0) { + res.push_back('1'); + } else { + res.push_back('0'); + } + carry = 0; + } else { + if (carry > 0) { + res.push_back('0'); + carry = 1; + } else { + res.push_back('1'); + carry = 0; + } + } + } + + while (i >= 0) { + if (a[i--] == '1') { + if (carry > 0) { + res.push_back('0'); + carry = 1; + } else { + res.push_back('1'); + carry = 0; + } + } else { + res.push_back(carry + '0'); + carry = 0; + } + } + + while (j >= 0) { + if (b[j--] == '1') { + if (carry > 0) { + res.push_back('0'); + carry = 1; + } else { + res.push_back('1'); + carry = 0; + } + } else { + res.push_back(carry + '0'); + carry = 0; + } + } + + if (carry > 0) { + res.push_back('1'); + } + reverse(res.begin(), res.end()); + return res; + } +}; diff --git a/068_text_justification/Makefile b/0068_text_justification/Makefile similarity index 100% rename from 068_text_justification/Makefile rename to 0068_text_justification/Makefile diff --git a/068_text_justification/justification.c b/0068_text_justification/justification.c similarity index 100% rename from 068_text_justification/justification.c rename to 0068_text_justification/justification.c diff --git a/069_sqrt/Makefile b/0069_sqrt/Makefile similarity index 100% rename from 069_sqrt/Makefile rename to 0069_sqrt/Makefile diff --git a/0069_sqrt/sqrt.c b/0069_sqrt/sqrt.c new file mode 100644 index 0000000..70a8411 --- /dev/null +++ b/0069_sqrt/sqrt.c @@ -0,0 +1,92 @@ +#include +#include +#include + +#if 0 +static double mySqrt(double x) +{ + double lo = 0; + double hi = x; + double diff = 1e-8; + double mid = (lo + hi) / 2; + while (fabs(mid * mid - x) > diff) { + if (mid < x / mid) { + lo = mid; + } else if (mid > x / mid) { + hi = mid; + } else { + break; + } + mid = (lo + hi) / 2; + } + + return mid; +} + +static double mySqrt(double n) +{ + /* Solute the zero point of f(x). Let F(x) = f(x) - n = 0 */ + /* then (x - x0)F'(x0) + F(x0) = 0 which is the first order of Tylor series */ + double x = 1.0; + while (fabs(x * x - n) > 1e-8) { + // x = x - (x * x - n) / (2 * x); + x = (x - n / x) / 2; + } + return x; +} + +static double mySqrt(double n) +{ + /* Gradient descent + * MSE Loss = (x * x - n) ^ 2 + * G = 4 * x ^ 3 - 4 * n * x + * x = x - a * G + */ + double a = 1e-4; + double x = 1.0; + while (fabs(x * x - n) > 1e-8) { + x = x - a * 4 * x * (x * x - n); + } + return x; +} +#endif + +int mySqrt(int x) +{ + if (x == 0) { + return 0; + } + + unsigned int lo = 1; + unsigned int hi = (unsigned int) x; + unsigned int mid = lo + (hi - lo) / 2; + // Firstly test mid > x / mid to decide whether hi = mid; + // else then test mid + 1 > x / (mid + 1) to decide whether the mid is located; + // Otherwise assign low = mid. + for (; ;) { + if (mid > x/mid) { + hi = mid; + } else { + if (mid + 1 > x/(mid + 1)) { + break; + } else { + lo = mid; + } + } + mid = lo + (hi - lo) / 2; + } + + return mid; +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test n\n"); + exit(-1); + } + + //printf("%f\n", mySqrt(1.5));//atoi(argv[1]))); + printf("%d\n", mySqrt(atoi(argv[1]))); + return 0; +} 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/070_climbing_stairs/Makefile b/0070_climbing_stairs/Makefile similarity index 100% rename from 070_climbing_stairs/Makefile rename to 0070_climbing_stairs/Makefile diff --git a/070_climbing_stairs/climb_stairs.c b/0070_climbing_stairs/climb_stairs.c similarity index 50% rename from 070_climbing_stairs/climb_stairs.c rename to 0070_climbing_stairs/climb_stairs.c index 3ecc50c..31b1904 100644 --- a/070_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/0070_climbing_stairs/climb_stairs.cc b/0070_climbing_stairs/climb_stairs.cc new file mode 100644 index 0000000..c4b4490 --- /dev/null +++ b/0070_climbing_stairs/climb_stairs.cc @@ -0,0 +1,18 @@ +#include + +using namespace std; + +class Solution { +public: + int climbStairs(int n) { + int a = 1; + int b = 2; + int c = 0; + for (int i = 3; i <= n; i++) { + c = a + b; + a = b; + b = c; + } + return n == 1 ? a : (n == 2 ? b : c); + } +}; diff --git a/071_simplify_path/Makefile b/0071_simplify_path/Makefile similarity index 100% rename from 071_simplify_path/Makefile rename to 0071_simplify_path/Makefile diff --git a/071_simplify_path/simplify_path.c b/0071_simplify_path/simplify_path.c similarity index 100% rename from 071_simplify_path/simplify_path.c rename to 0071_simplify_path/simplify_path.c diff --git a/072_edit_distance/Makefile b/0072_edit_distance/Makefile similarity index 100% rename from 072_edit_distance/Makefile rename to 0072_edit_distance/Makefile diff --git a/072_edit_distance/edit_distance.c b/0072_edit_distance/edit_distance.c similarity index 72% rename from 072_edit_distance/edit_distance.c rename to 0072_edit_distance/edit_distance.c index b035609..92f96a8 100644 --- a/072_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 new file mode 100644 index 0000000..be8543a --- /dev/null +++ b/0072_edit_distance/edit_distance.cc @@ -0,0 +1,32 @@ +#include + +using namespace std; + +class Solution { +public: + int minDistance(string word1, string word2) { + int l1 = word1.length(); + int l2 = word2.length(); + vector dp(l2 + 1); + for (int i = 0; i <= l2; i++) { + dp[i] = i; + } + + 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[j] = left_up; + } else { + dp[j] = 1 + min(left_up, min(up, dp[j - 1])); + } + left_up = up; + } + } + + return dp[l2]; + } +}; diff --git a/073_set_matrix_zeroes/Makefile b/0073_set_matrix_zeroes/Makefile similarity index 100% rename from 073_set_matrix_zeroes/Makefile rename to 0073_set_matrix_zeroes/Makefile diff --git a/0073_set_matrix_zeroes/set_zero.c b/0073_set_matrix_zeroes/set_zero.c new file mode 100644 index 0000000..b56fd87 --- /dev/null +++ b/0073_set_matrix_zeroes/set_zero.c @@ -0,0 +1,41 @@ +#include +#include + + +void setZeroes(int** matrix, int matrixSize, int* matrixColSize) +{ + 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) bRow = true; + if (col == 0) bCol = true; + matrix[0][col] = matrix[row][0] = 0; + } + } + } + + 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; + } + } + } + + if (bRow) { + memset(matrix[0], 0, matrixColSize[0] * sizeof(int)); + } + + if (bCol) { + for (row = 0; row < matrixSize; row++) { + matrix[row][0] = 0; + } + } +} + +int main(int argc, char **argv) +{ + return 0; +} diff --git a/0073_set_matrix_zeroes/set_zero.cc b/0073_set_matrix_zeroes/set_zero.cc new file mode 100644 index 0000000..1b08fdd --- /dev/null +++ b/0073_set_matrix_zeroes/set_zero.cc @@ -0,0 +1,38 @@ +#include + +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/074_search_a_2d_matrix/Makefile b/0074_search_a_2d_matrix/Makefile similarity index 100% rename from 074_search_a_2d_matrix/Makefile rename to 0074_search_a_2d_matrix/Makefile diff --git a/074_search_a_2d_matrix/matrix_search.c b/0074_search_a_2d_matrix/matrix_search.c similarity index 100% rename from 074_search_a_2d_matrix/matrix_search.c rename to 0074_search_a_2d_matrix/matrix_search.c diff --git a/075_sort_colors/Makefile b/0075_sort_colors/Makefile similarity index 100% rename from 075_sort_colors/Makefile rename to 0075_sort_colors/Makefile diff --git a/075_sort_colors/sort_colors.c b/0075_sort_colors/sort_colors.c similarity index 94% rename from 075_sort_colors/sort_colors.c rename to 0075_sort_colors/sort_colors.c index 0791746..290c02d 100644 --- a/075_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/076_minimum_window_substring/Makefile b/0076_minimum_window_substring/Makefile similarity index 100% rename from 076_minimum_window_substring/Makefile rename to 0076_minimum_window_substring/Makefile diff --git a/076_minimum_window_substring/window_substring.c b/0076_minimum_window_substring/window_substring.c similarity index 61% rename from 076_minimum_window_substring/window_substring.c rename to 0076_minimum_window_substring/window_substring.c index a9e87ab..cd7f525 100644 --- a/076_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 new file mode 100644 index 0000000..8fd41bd --- /dev/null +++ b/0076_minimum_window_substring/window_substring.cc @@ -0,0 +1,39 @@ +#include + +using namespace std; + +class Solution { +public: + string minWindow(string s, string t) { + vector count(128); + for (char c : t) { + count[c]++; + } + + int l = 0, r = 0; + 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) { + hit_num++; + } + + 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) { + hit_num--; + } + } + } + + return min_len == INT_MAX ? "" : s.substr(start, min_len); + } +}; diff --git a/077_combinations/Makefile b/0077_combinations/Makefile similarity index 100% rename from 077_combinations/Makefile rename to 0077_combinations/Makefile diff --git a/077_combinations/combinations.c b/0077_combinations/combinations.c similarity index 77% rename from 077_combinations/combinations.c rename to 0077_combinations/combinations.c index 7625498..2ef84f7 100644 --- a/077_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) { @@ -14,7 +15,6 @@ static void dfs(int n, int k, int start, int *stack, int len, (*count)++; } else { for (i = start; i <= n; i++) { - /* No used marks since the order does not matter */ stack[len] = i; dfs(n, k, i + 1, stack, len + 1, results, count, col_sizes); } @@ -24,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; } @@ -44,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 new file mode 100644 index 0000000..1aabf42 --- /dev/null +++ b/0077_combinations/combinations.cc @@ -0,0 +1,26 @@ +#include + +using namespace std; + +class Solution { +public: + vector> combine(int n, int k) { + vector> res; + dfs(n, k, 1, res); + return res; + } + +private: + 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, res); + stack.pop_back(); + } + } + } +}; diff --git a/078_subsets/Makefile b/0078_subsets/Makefile similarity index 100% rename from 078_subsets/Makefile rename to 0078_subsets/Makefile diff --git a/078_subsets/subsets.c b/0078_subsets/subsets.c similarity index 73% rename from 078_subsets/subsets.c rename to 0078_subsets/subsets.c index a98cfcf..aeb75b1 100644 --- a/078_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 new file mode 100644 index 0000000..c6593d2 --- /dev/null +++ b/0078_subsets/subsets.cc @@ -0,0 +1,23 @@ +#include + +using namespace std; + +class Solution { +public: + vector> subsets(vector& nums) { + vector> res; + dfs(nums, 0, res); + return res; + } + +private: + 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, res); + stack.pop_back(); + } + } +}; diff --git a/079_word_search/Makefile b/0079_word_search/Makefile similarity index 100% rename from 079_word_search/Makefile rename to 0079_word_search/Makefile diff --git a/079_word_search/word_search.c b/0079_word_search/word_search.c similarity index 100% rename from 079_word_search/word_search.c rename to 0079_word_search/word_search.c diff --git a/080_remove_duplicates_from_sorted_array_ii/Makefile b/0080_remove_duplicates_from_sorted_array_ii/Makefile similarity index 100% rename from 080_remove_duplicates_from_sorted_array_ii/Makefile rename to 0080_remove_duplicates_from_sorted_array_ii/Makefile diff --git a/080_remove_duplicates_from_sorted_array_ii/rm_dups.c b/0080_remove_duplicates_from_sorted_array_ii/rm_dups.c similarity index 100% rename from 080_remove_duplicates_from_sorted_array_ii/rm_dups.c rename to 0080_remove_duplicates_from_sorted_array_ii/rm_dups.c diff --git a/081_search_in_rotated_sorted_array_ii/Makefile b/0081_search_in_rotated_sorted_array_ii/Makefile similarity index 100% rename from 081_search_in_rotated_sorted_array_ii/Makefile rename to 0081_search_in_rotated_sorted_array_ii/Makefile diff --git a/081_search_in_rotated_sorted_array_ii/search_rotated_array.c b/0081_search_in_rotated_sorted_array_ii/search_rotated_array.c similarity index 100% rename from 081_search_in_rotated_sorted_array_ii/search_rotated_array.c rename to 0081_search_in_rotated_sorted_array_ii/search_rotated_array.c diff --git a/082_remove_duplicates_from_sorted_list_ii/Makefile b/0082_remove_duplicates_from_sorted_list_ii/Makefile similarity index 100% rename from 082_remove_duplicates_from_sorted_list_ii/Makefile rename to 0082_remove_duplicates_from_sorted_list_ii/Makefile diff --git a/082_remove_duplicates_from_sorted_list_ii/rm_dup.c b/0082_remove_duplicates_from_sorted_list_ii/rm_dup.c similarity index 100% rename from 082_remove_duplicates_from_sorted_list_ii/rm_dup.c rename to 0082_remove_duplicates_from_sorted_list_ii/rm_dup.c diff --git a/083_remove_duplicates_from_sorted_list/Makefile b/0083_remove_duplicates_from_sorted_list/Makefile similarity index 100% rename from 083_remove_duplicates_from_sorted_list/Makefile rename to 0083_remove_duplicates_from_sorted_list/Makefile diff --git a/083_remove_duplicates_from_sorted_list/rm_dup.c b/0083_remove_duplicates_from_sorted_list/rm_dup.c similarity index 71% rename from 083_remove_duplicates_from_sorted_list/rm_dup.c rename to 0083_remove_duplicates_from_sorted_list/rm_dup.c index f5b7c7f..e8d7d4a 100644 --- a/083_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/0083_remove_duplicates_from_sorted_list/rm_dup.cc b/0083_remove_duplicates_from_sorted_list/rm_dup.cc new file mode 100644 index 0000000..3ee3dbf --- /dev/null +++ b/0083_remove_duplicates_from_sorted_list/rm_dup.cc @@ -0,0 +1,34 @@ +#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* deleteDuplicates(ListNode* head) { + if (head == nullptr) { + return nullptr; + } + + ListNode* prev = head; + ListNode *p = prev->next; + while (p != nullptr) { + if (p->val != prev->val) { + prev->next = p; + prev = p; + } + p = p->next; + } + prev->next = p; + return head; + } +}; diff --git a/084_largest_rectangle_in_histogram/Makefile b/0084_largest_rectangle_in_histogram/Makefile similarity index 100% rename from 084_largest_rectangle_in_histogram/Makefile rename to 0084_largest_rectangle_in_histogram/Makefile diff --git a/084_largest_rectangle_in_histogram/rect_in_histogram.c b/0084_largest_rectangle_in_histogram/rect_in_histogram.c similarity index 50% rename from 084_largest_rectangle_in_histogram/rect_in_histogram.c rename to 0084_largest_rectangle_in_histogram/rect_in_histogram.c index 49116ff..4e302ad 100644 --- a/084_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/085_maximal_rectangle/Makefile b/0085_maximal_rectangle/Makefile similarity index 100% rename from 085_maximal_rectangle/Makefile rename to 0085_maximal_rectangle/Makefile diff --git a/085_maximal_rectangle/maximal_rectangle.c b/0085_maximal_rectangle/maximal_rectangle.c similarity index 50% rename from 085_maximal_rectangle/maximal_rectangle.c rename to 0085_maximal_rectangle/maximal_rectangle.c index c33ad1c..3f620c3 100644 --- a/085_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/086_partition_list/Makefile b/0086_partition_list/Makefile similarity index 100% rename from 086_partition_list/Makefile rename to 0086_partition_list/Makefile diff --git a/086_partition_list/partition_list.c b/0086_partition_list/partition_list.c similarity index 100% rename from 086_partition_list/partition_list.c rename to 0086_partition_list/partition_list.c diff --git a/087_scramble_string/Makefile b/0087_scramble_string/Makefile similarity index 100% rename from 087_scramble_string/Makefile rename to 0087_scramble_string/Makefile diff --git a/087_scramble_string/scramble_string.c b/0087_scramble_string/scramble_string.c similarity index 100% rename from 087_scramble_string/scramble_string.c rename to 0087_scramble_string/scramble_string.c diff --git a/088_merge_sorted_array/Makefile b/0088_merge_sorted_array/Makefile similarity index 100% rename from 088_merge_sorted_array/Makefile rename to 0088_merge_sorted_array/Makefile diff --git a/088_merge_sorted_array/merge_array.c b/0088_merge_sorted_array/merge_array.c similarity index 84% rename from 088_merge_sorted_array/merge_array.c rename to 0088_merge_sorted_array/merge_array.c index 7f65d98..ddfbc20 100644 --- a/088_merge_sorted_array/merge_array.c +++ b/0088_merge_sorted_array/merge_array.c @@ -1,10 +1,11 @@ #include #include + static void merge(int* nums1, int m, int* nums2, int n) { int i = m - 1, j = n - 1, k = nums1Size - 1; - while (i >= 0 && j >= 0 && k >= 0) { + while (i >= 0 && j >= 0) { if (nums1[i] >= nums2[j]) { nums1[k--] = nums1[i--]; } else { @@ -12,10 +13,8 @@ static void merge(int* nums1, int m, int* nums2, int n) } } - if (i == -1) { - while (j >= 0) { - nums1[k--] = nums2[j--]; - } + while (j >= 0) { + nums1[k--] = nums2[j--]; } } diff --git a/0088_merge_sorted_array/merge_array.cc b/0088_merge_sorted_array/merge_array.cc new file mode 100644 index 0000000..e08025a --- /dev/null +++ b/0088_merge_sorted_array/merge_array.cc @@ -0,0 +1,23 @@ +#include + +using namespace std; + +class Solution { +public: + void merge(vector& nums1, int m, vector& nums2, int n) { + int i = m - 1; + int j = n - 1; + int k = nums1.size() - 1; + while (i >= 0 && j >= 0) { + if (nums1[i] < nums2[j]) { + nums1[k--] = nums2[j--]; + } else { + nums1[k--] = nums1[i--]; + } + } + + while (j >= 0) { + nums1[k--] = nums2[j--]; + } + } +}; diff --git a/089_gray_code/Makefile b/0089_gray_code/Makefile similarity index 100% rename from 089_gray_code/Makefile rename to 0089_gray_code/Makefile diff --git a/089_gray_code/gray_code.c b/0089_gray_code/gray_code.c similarity index 100% rename from 089_gray_code/gray_code.c rename to 0089_gray_code/gray_code.c diff --git a/090_subsets_ii/Makefile b/0090_subsets_ii/Makefile similarity index 100% rename from 090_subsets_ii/Makefile rename to 0090_subsets_ii/Makefile diff --git a/090_subsets_ii/subsets.c b/0090_subsets_ii/subsets.c similarity index 58% rename from 090_subsets_ii/subsets.c rename to 0090_subsets_ii/subsets.c index e2f40db..4c3897d 100644 --- a/090_subsets_ii/subsets.c +++ b/0090_subsets_ii/subsets.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -8,46 +9,39 @@ static inline int compare(const void *a, const void *b) return *(int *) a - *(int *) b; } -static void dfs(int *nums, int size, int start, int *buf, int level, - bool *used, int **sets, int *count, int *sizes) +static void dfs(int *nums, int size, int start, int *buf, + int level, int **sets, int *count, int *sizes) { - int i; + int i, last = INT_MIN; sets[*count] = malloc(level * sizeof(int)); memcpy(sets[*count], buf, level * sizeof(int)); sizes[*count] = level; (*count)++; for (i = start; i < size; i++) { - if (!used[i]) { - if (i > 0 && !used[i - 1] && nums[i - 1] == nums[i]) { - /* Forbid same elements on same level */ - /* Used marks allow same elements in different levels */ - continue; - } - used[i] = true; + if (last != nums[i]) { + /* No duplicate candidate elements at same level position */ buf[level] = nums[i]; - /* i + 1 limits the selecting range in following levels */ - dfs(nums, size, i + 1, buf, level + 1, used, sets, count, sizes); - used[i] = false; + /* i + 1 limits the selecting range in next levels */ + dfs(nums, size, i + 1, buf, level + 1, sets, count, sizes); } + last = nums[i]; } } /** ** 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** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) +static int** subsetsWithNoDup(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) { qsort(nums, numsSize, sizeof(int), compare); int capacity = 5000; int **sets = malloc(capacity * sizeof(int *)); int *buf = malloc(numsSize * sizeof(int)); - bool *used = malloc(numsSize); - memset(used, false, numsSize); *returnColumnSizes = malloc(capacity * sizeof(int)); *returnSize = 0; - dfs(nums, numsSize, 0, buf, 0, used, sets, returnSize, *returnColumnSizes); + dfs(nums, numsSize, 0, buf, 0, sets, returnSize, *returnColumnSizes); return sets; } diff --git a/0090_subsets_ii/subsets.cc b/0090_subsets_ii/subsets.cc new file mode 100644 index 0000000..d6ee1da --- /dev/null +++ b/0090_subsets_ii/subsets.cc @@ -0,0 +1,29 @@ +#include + +using namespace std; + +class Solution { +public: + vector> subsetsWithDup(vector& nums) { + vector> res; + sort(nums.begin(), nums.end()); + dfs(nums, 0, res); + return res; + } + +private: + 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 in the same level position */ + stack.push_back(nums[i]); + dfs(nums, i + 1, res); + stack.pop_back(); + } + last = nums[i]; + } + } +}; diff --git a/091_decode_ways/Makefile b/0091_decode_ways/Makefile similarity index 100% rename from 091_decode_ways/Makefile rename to 0091_decode_ways/Makefile diff --git a/091_decode_ways/decode_ways.c b/0091_decode_ways/decode_ways.c similarity index 63% rename from 091_decode_ways/decode_ways.c rename to 0091_decode_ways/decode_ways.c index a096361..05fc39d 100644 --- a/091_decode_ways/decode_ways.c +++ b/0091_decode_ways/decode_ways.c @@ -2,29 +2,29 @@ #include #include -static int numDecodings(char* s) { + +static int numDecodings(char* s) +{ int len = strlen(s); if (len == 0) { return 0; } - int dp[len + 1]; - memset(dp, 0, (len + 1) * sizeof(int)); - - dp[0] = 1; - dp[1] = s[0] == '0' ? 0 : 1; + int a = 1; + int b = s[0] == '0' ? 0 : a; + int c = b; + /* DP: How many counts in sequence c = f(a, b) and c counts s[i - 1] */ for (int i = 2; i <= len; i++) { - if (s[i - 1] != '0') { - dp[i] = dp[i - 1]; - } - + c = s[i - 1] == '0' ? 0 : b; int num = (s[i - 2] - '0') * 10 + (s[i - 1] - '0'); if (num >= 10 && num <= 26) { - dp[i] += dp[i - 2]; + c += a; } + a = b; + b = c; } - return dp[len]; + return c; } int main(int argc, char **argv) diff --git a/092_reverse_linked_list_ii/Makefile b/0092_reverse_linked_list_ii/Makefile similarity index 100% rename from 092_reverse_linked_list_ii/Makefile rename to 0092_reverse_linked_list_ii/Makefile diff --git a/092_reverse_linked_list_ii/reverse_list.c b/0092_reverse_linked_list_ii/reverse_list.c similarity index 100% rename from 092_reverse_linked_list_ii/reverse_list.c rename to 0092_reverse_linked_list_ii/reverse_list.c diff --git a/093_restore_ip_addresses/Makefile b/0093_restore_ip_addresses/Makefile similarity index 100% rename from 093_restore_ip_addresses/Makefile rename to 0093_restore_ip_addresses/Makefile diff --git a/093_restore_ip_addresses/ip_addr.c b/0093_restore_ip_addresses/ip_addr.c similarity index 100% rename from 093_restore_ip_addresses/ip_addr.c rename to 0093_restore_ip_addresses/ip_addr.c diff --git a/094_binary_tree_inorder_traversal/Makefile b/0094_binary_tree_inorder_traversal/Makefile similarity index 100% rename from 094_binary_tree_inorder_traversal/Makefile rename to 0094_binary_tree_inorder_traversal/Makefile diff --git a/094_binary_tree_inorder_traversal/bst_inorder_traversal.c b/0094_binary_tree_inorder_traversal/bst_inorder_traversal.c similarity index 100% rename from 094_binary_tree_inorder_traversal/bst_inorder_traversal.c rename to 0094_binary_tree_inorder_traversal/bst_inorder_traversal.c diff --git a/095_unique_binary_search_trees_ii/Makefile b/0095_unique_binary_search_trees_ii/Makefile similarity index 100% rename from 095_unique_binary_search_trees_ii/Makefile rename to 0095_unique_binary_search_trees_ii/Makefile diff --git a/095_unique_binary_search_trees_ii/unique_bst.c b/0095_unique_binary_search_trees_ii/unique_bst.c similarity index 98% rename from 095_unique_binary_search_trees_ii/unique_bst.c rename to 0095_unique_binary_search_trees_ii/unique_bst.c index 41f1478..bde5770 100644 --- a/095_unique_binary_search_trees_ii/unique_bst.c +++ b/0095_unique_binary_search_trees_ii/unique_bst.c @@ -20,7 +20,7 @@ * * i=2 * / \ - * (1,1) (3,3) // 1 possiblity + * (1,1) (3,3) // 1 possibility * * * i=3 diff --git a/096_unique_binary_search_trees/Makefile b/0096_unique_binary_search_trees/Makefile similarity index 100% rename from 096_unique_binary_search_trees/Makefile rename to 0096_unique_binary_search_trees/Makefile diff --git a/096_unique_binary_search_trees/unique_bst.c b/0096_unique_binary_search_trees/unique_bst.c similarity index 100% rename from 096_unique_binary_search_trees/unique_bst.c rename to 0096_unique_binary_search_trees/unique_bst.c diff --git a/0096_unique_binary_search_trees/unique_bst.cc b/0096_unique_binary_search_trees/unique_bst.cc new file mode 100644 index 0000000..5aa3a55 --- /dev/null +++ b/0096_unique_binary_search_trees/unique_bst.cc @@ -0,0 +1,20 @@ +#include + +using namespace std; + +/* + * f(n) = f(0)f(n-1) + f(1)f(n-2) + ... + f(n-2)f(1) + f(n-1)f(0) + */ +class Solution { +public: + int numTrees(int n) { + vector sum(n + 1); + sum[0] = 1; + for (int i = 1; i <= n; i++) { + for (int j = 0; j < i; j++) { + sum[i] += sum[j] * sum[i - j - 1]; + } + } + return sum[n]; + } +} diff --git a/097_interleaving_string/Makefile b/0097_interleaving_string/Makefile similarity index 100% rename from 097_interleaving_string/Makefile rename to 0097_interleaving_string/Makefile diff --git a/097_interleaving_string/interleaving_string.c b/0097_interleaving_string/interleaving_string.c similarity index 100% rename from 097_interleaving_string/interleaving_string.c rename to 0097_interleaving_string/interleaving_string.c diff --git a/098_validate_binary_search_tree/Makefile b/0098_validate_binary_search_tree/Makefile similarity index 100% rename from 098_validate_binary_search_tree/Makefile rename to 0098_validate_binary_search_tree/Makefile diff --git a/098_validate_binary_search_tree/valid_bst.c b/0098_validate_binary_search_tree/valid_bst.c similarity index 51% rename from 098_validate_binary_search_tree/valid_bst.c rename to 0098_validate_binary_search_tree/valid_bst.c index 06e972e..e03289e 100644 --- a/098_validate_binary_search_tree/valid_bst.c +++ b/0098_validate_binary_search_tree/valid_bst.c @@ -3,24 +3,34 @@ #include #include + struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; -static bool dfs(struct TreeNode* node, int min, int max) -{ - if (node == NULL) return true; - if (node->val < min || node->val > max) return false; - if (node->left != NULL && node->val == INT_MIN) return false; - if (node->right != NULL && node->val == INT_MAX) return false; - return dfs(node->left, min, node->val - 1) && dfs(node->right, node->val + 1, max); -} - -static bool isValidBST(struct TreeNode* root) +bool isValidBST(struct TreeNode* root) { - return dfs(root, INT_MIN, INT_MAX); + int top = 0; + int prev = INT_MIN; + bool first = true; + struct TreeNode *stack[1000]; + while (top > 0 || root != NULL) { + if (root != NULL) { + stack[top++] = root; + root = root->left; + } else { + root = stack[--top]; + if (!first && prev >= root->val) { + return false; + } + first = false; + prev = root->val; + root = root->right; + } + } + return true; } int main(int argc, char **argv) diff --git a/0098_validate_binary_search_tree/valid_bst.cc b/0098_validate_binary_search_tree/valid_bst.cc new file mode 100644 index 0000000..c80f236 --- /dev/null +++ b/0098_validate_binary_search_tree/valid_bst.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: + bool isValidBST(TreeNode* root) { + stack stk; + int prev = INT_MIN; + bool first = true; + while (!stk.empty() || root != nullptr) { + if (root != nullptr) { + stk.push(root); + root = root->left; + } else { + root = stk.top(); + stk.pop(); + if (!first && prev >= root->val) { + return false; + } + first = false; + prev = root->val; + root = root->right; + } + } + return true; + } +}; diff --git a/099_recover_binary_search_tree/Makefile b/0099_recover_binary_search_tree/Makefile similarity index 100% rename from 099_recover_binary_search_tree/Makefile rename to 0099_recover_binary_search_tree/Makefile diff --git a/099_recover_binary_search_tree/recover_bst.c b/0099_recover_binary_search_tree/recover_bst.c similarity index 56% rename from 099_recover_binary_search_tree/recover_bst.c rename to 0099_recover_binary_search_tree/recover_bst.c index 8636472..5274c88 100644 --- a/099_recover_binary_search_tree/recover_bst.c +++ b/0099_recover_binary_search_tree/recover_bst.c @@ -2,48 +2,49 @@ #include #include + struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; -static void traverse(struct TreeNode *node, struct TreeNode **prev, - struct TreeNode **p1, struct TreeNode **p2, int *wrong) +static void dfs(struct TreeNode *node, struct TreeNode **prev, + struct TreeNode **p1, struct TreeNode **p2, int *wrong) { - if (node->left != NULL) { - traverse(node->left, prev, p1, p2, wrong); + if (node == NULL || *wrong == 2) { + return; } + dfs(node->left, prev, p1, p2, wrong); + + /* We must use pointer to pointer to previous object for backward recursion */ if (*prev != NULL && node->val < (*prev)->val) { (*wrong)++; if (*wrong == 1) { *p1 = *prev; + /* p2 frist to be recorded here */ *p2 = node; } else if (*wrong == 2) { + /* update p2 location */ *p2 = node; - return; } } *prev = node; - if (node->right != NULL) { - traverse(node->right, prev, p1, p2, wrong); - } + dfs(node->right, prev, p1, p2, wrong); } static void recoverTree(struct TreeNode* root) { - if (root != NULL) { - struct TreeNode *prev = NULL; - struct TreeNode *p1 = NULL; - struct TreeNode *p2 = NULL; - int wrong = 0; - traverse(root, &prev, &p1, &p2, &wrong); - int tmp = p1->val; - p1->val = p2->val; - p2->val = tmp; - } + int wrong = 0; + struct TreeNode *prev = NULL; + struct TreeNode *p1 = NULL; + struct TreeNode *p2 = NULL; + dfs(root, &prev, &p1, &p2, &wrong); + int tmp = p1->val; + p1->val = p2->val; + p2->val = tmp; } int main(int argc, char **argv) diff --git a/0099_recover_binary_search_tree/recover_bst.cc b/0099_recover_binary_search_tree/recover_bst.cc new file mode 100644 index 0000000..7985386 --- /dev/null +++ b/0099_recover_binary_search_tree/recover_bst.cc @@ -0,0 +1,50 @@ +#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: + void recoverTree(TreeNode* root) { + dfs(root); + int tmp = p0_->val; + p0_->val = p1_->val; + p1_->val = tmp; + } + +private: + int wrong_ = 0; + TreeNode *prev_ = nullptr; + TreeNode *p0_ = nullptr; + TreeNode *p1_ = nullptr; + + void dfs(TreeNode* root) { + if (root == nullptr || wrong_ == 2) { + return; + } + + dfs(root->left); + if (prev_ != nullptr && prev_->val > root->val) { + if (++wrong_ == 1) { + p0_ = prev_; + // p1 first to be recorded here + p1_ = root; + } else if (wrong_ == 2) { + // update p1 location + p1_ = root; + } + } + prev_ = root; + dfs(root->right); + } +}; diff --git a/100_same_tree/Makefile b/0100_same_tree/Makefile similarity index 100% rename from 100_same_tree/Makefile rename to 0100_same_tree/Makefile diff --git a/0100_same_tree/same_tree.c b/0100_same_tree/same_tree.c new file mode 100644 index 0000000..205c237 --- /dev/null +++ b/0100_same_tree/same_tree.c @@ -0,0 +1,29 @@ +#include +#include +#include + +struct TreeNode { + int val; + struct TreeNode *left; + struct TreeNode *right; +}; + +static bool isSameTree(struct TreeNode* p, struct TreeNode* q) +{ + if (p == NULL && q == NULL) { + return true; + } + if (p == NULL || q == NULL) { + return false; + } + if (p->val != q->val) { + return false; + } + return isSameTree(p->left, q->left) && isSameTree(p->right, q->right); +} + +int main(void) +{ + printf("%s\n", isSameTree(NULL, NULL) ? "true" : "false"); + return 0; +} diff --git a/0100_same_tree/same_tree.cc b/0100_same_tree/same_tree.cc new file mode 100644 index 0000000..be894b1 --- /dev/null +++ b/0100_same_tree/same_tree.cc @@ -0,0 +1,30 @@ +#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: + bool isSameTree(TreeNode* p, TreeNode* q) { + if (p == nullptr && q == nullptr) { + return true; + } + if (p == nullptr || q == nullptr) { + return false; + } + if (p->val != q->val) { + return false; + } + return isSameTree(p->left, q->left) && isSameTree(p->right, q->right); + } +}; diff --git a/101_symmetric_tree/Makefile b/0101_symmetric_tree/Makefile similarity index 100% rename from 101_symmetric_tree/Makefile rename to 0101_symmetric_tree/Makefile diff --git a/101_symmetric_tree/symmetric_tree.c b/0101_symmetric_tree/symmetric_tree.c similarity index 100% rename from 101_symmetric_tree/symmetric_tree.c rename to 0101_symmetric_tree/symmetric_tree.c diff --git a/0101_symmetric_tree/symmetric_tree.cc b/0101_symmetric_tree/symmetric_tree.cc new file mode 100644 index 0000000..27fd4bb --- /dev/null +++ b/0101_symmetric_tree/symmetric_tree.cc @@ -0,0 +1,38 @@ +#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: + bool isSymmetric(TreeNode* root) { + if (root == nullptr) { + return true; + } + return dfs(root->left, root->right); + } + +private: + bool dfs(TreeNode *l, TreeNode *r) { + if (l == nullptr && r == nullptr) { + return true; + } + if (l == nullptr || r == nullptr) { + return false; + } + if (l->val != r->val) { + return false; + } + return dfs(l->left, r->right) && dfs(l->right, r->left); + } +}; diff --git a/102_binary_tree_level_order_traversal/Makefile b/0102_binary_tree_level_order_traversal/Makefile similarity index 100% rename from 102_binary_tree_level_order_traversal/Makefile rename to 0102_binary_tree_level_order_traversal/Makefile diff --git a/0102_binary_tree_level_order_traversal/bst_bfs.c b/0102_binary_tree_level_order_traversal/bst_bfs.c new file mode 100644 index 0000000..9275ffe --- /dev/null +++ b/0102_binary_tree_level_order_traversal/bst_bfs.c @@ -0,0 +1,185 @@ +#include +#include +#include + + +#define BST_MAX_LEVEL 800 + +#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_first_entry(ptr, type, field) list_entry((ptr)->next, type, field) +#define list_last_entry(ptr, type, field) list_entry((ptr)->prev, type, field) + +struct TreeNode { + int val; + struct TreeNode *left; + struct TreeNode *right; +}; + +struct list_head { + struct list_head *next, *prev; +}; + +struct queue_node { + struct TreeNode *node; + struct list_head link; +}; + +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; +} + +static struct queue_node *node_new(struct TreeNode *node, struct list_head *free_list) +{ + struct queue_node *qn; + if (list_empty(free_list)) { + qn = malloc(sizeof(*qn)); + } else { + qn = list_first_entry(free_list, struct queue_node, link); + list_del(&qn->link); + } + qn->node = node; + return qn; +} + +static void node_free(struct queue_node *qn, struct list_head *free_list) +{ + list_del(&qn->link); + list_add(&qn->link, 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(). + **/ +static int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes) +{ + if (root == NULL) { + *returnSize = 0; + return NULL; + } + + struct list_head free_list; + struct list_head q; + INIT_LIST_HEAD(&free_list); + INIT_LIST_HEAD(&q); + + int **results = malloc(BST_MAX_LEVEL * sizeof(int *)); + *returnColumnSizes = malloc(BST_MAX_LEVEL * sizeof(int)); + memset(*returnColumnSizes, 0, BST_MAX_LEVEL * sizeof(int)); + + /* Add root node */ + struct queue_node *new = node_new(root, &free_list); + list_add_tail(&new->link, &q); + + int i, level = 0; + (*returnColumnSizes)[level]++; + while (!list_empty(&q)) { + int size = (*returnColumnSizes)[level]; + results[level] = malloc(size * sizeof(int)); + for (i = 0; i < size; i++) { + struct queue_node *qn = list_first_entry(&q, struct queue_node, link); + results[level][i] = qn->node->val; + + if (qn->node->left != NULL) { + new = node_new(qn->node->left, &free_list); + list_add_tail(&new->link, &q); + (*returnColumnSizes)[level + 1]++; + } + if (qn->node->right != NULL) { + new = node_new(qn->node->right, &free_list); + list_add_tail(&new->link, &q); + (*returnColumnSizes)[level + 1]++; + } + + node_free(qn, &free_list); + } + level++; + } + + *returnSize = level; + return results; +} + +int main(void) +{ + struct TreeNode root; + root.val = 3; + + struct TreeNode node1[2]; + node1[0].val = 9; + node1[1].val = 20; + + struct TreeNode node2[4]; + node2[2].val = 15; + node2[3].val = 7; + + root.left = &node1[0]; + root.right = &node1[1]; + + node1[0].left = NULL; + node1[0].right = NULL; + node1[1].left = &node2[2]; + node1[1].right = &node2[3]; + + node2[0].left = NULL; + node2[0].right = NULL; + node2[1].left = NULL; + node2[1].right = NULL; + node2[2].left = NULL; + node2[2].right = NULL; + node2[3].left = NULL; + node2[3].right = NULL; + + int i, j, count = 0, *col_sizes; + int **lists = levelOrder(&root, &count, &col_sizes); + for (i = 0; i < count; i++) { + for (j = 0; j < col_sizes[i]; j++) { + printf("%d ", lists[i][j]); + } + printf("\n"); + } + + return 0; +} diff --git a/0102_binary_tree_level_order_traversal/bst_bfs.cc b/0102_binary_tree_level_order_traversal/bst_bfs.cc new file mode 100644 index 0000000..bf83b55 --- /dev/null +++ b/0102_binary_tree_level_order_traversal/bst_bfs.cc @@ -0,0 +1,45 @@ +#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> levelOrder(TreeNode* root) { + vector> res; + if (root == nullptr) { + return res; + } + + queue q; + q.push(root); + while (!q.empty()) { + vector level; + int size = q.size(); + for (int i = 0; i < size; i++) { + TreeNode *node = q.front(); + q.pop(); + level.push_back(node->val); + if (node->left != nullptr) { + q.push(node->left); + } + if (node->right != nullptr) { + q.push(node->right); + } + } + res.push_back(level); + } + + return res; + } +}; diff --git a/103_binary_tree_zigzag_level_order_traversal/Makefile b/0103_binary_tree_zigzag_level_order_traversal/Makefile similarity index 100% rename from 103_binary_tree_zigzag_level_order_traversal/Makefile rename to 0103_binary_tree_zigzag_level_order_traversal/Makefile diff --git a/103_binary_tree_zigzag_level_order_traversal/bst_zigzag.c b/0103_binary_tree_zigzag_level_order_traversal/bst_zigzag.c similarity index 57% rename from 103_binary_tree_zigzag_level_order_traversal/bst_zigzag.c rename to 0103_binary_tree_zigzag_level_order_traversal/bst_zigzag.c index 3e7c28d..08b8924 100644 --- a/103_binary_tree_zigzag_level_order_traversal/bst_zigzag.c +++ b/0103_binary_tree_zigzag_level_order_traversal/bst_zigzag.c @@ -13,18 +13,6 @@ #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_reverse(p, head) \ - for (p = (head)->prev; p != (head); p = p->prev) - -#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_safe_reverse(p, n, head) \ - for (p = (head)->prev, n = p->prev; p != (head); p = n, n = p->prev) - struct TreeNode { int val; struct TreeNode *left; @@ -35,6 +23,11 @@ struct list_head { struct list_head *next, *prev; }; +struct queue_node { + struct TreeNode *node; + struct list_head link; +}; + static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list->prev = list; @@ -75,66 +68,29 @@ static inline void list_del(struct list_head *entry) entry->next = entry->prev = NULL; } -struct bfs_node { - struct TreeNode *node; - struct list_head link; -}; - -static struct bfs_node *node_new(struct list_head *free_list, struct TreeNode *node) +static struct queue_node *node_new(struct TreeNode *node, struct list_head *free_list) { - struct bfs_node *new; + struct queue_node *qn; if (list_empty(free_list)) { - new = malloc(sizeof(*new)); + qn = malloc(sizeof(*qn)); } else { - new = list_first_entry(free_list, struct bfs_node, link); - list_del(&new->link); + qn = list_first_entry(free_list, struct queue_node, link); + list_del(&qn->link); } - new->node = node; - return new; + qn->node = node; + return qn; } -static void queue(struct list_head *parents, struct list_head *children, int reverse, - struct list_head *free_list, int **results, int *col_sizes, int level) +static void node_free(struct queue_node *qn, struct list_head *free_list) { - struct list_head *p, *n; - struct bfs_node *new, *parent; - - list_for_each(p, parents) { - parent = list_entry(p, struct bfs_node, link); - if (parent->node->left != NULL) { - new = node_new(free_list, parent->node->left); - list_add_tail(&new->link, children); - } - if (parent->node->right != NULL) { - new = node_new(free_list, parent->node->right); - list_add_tail(&new->link, children); - } - col_sizes[level]++; - } - - int i = 0; - results[level] = malloc(col_sizes[level] * sizeof(int)); - if (reverse) { - list_for_each_safe_reverse(p, n, parents) { - parent = list_entry(p, struct bfs_node, link); - results[level][i++] = parent->node->val; - list_del(p); - list_add(p, free_list); - } - } else { - list_for_each_safe(p, n, parents) { - parent = list_entry(p, struct bfs_node, link); - results[level][i++] = parent->node->val; - list_del(p); - list_add(p, free_list); - } - } + list_del(&qn->link); + list_add(&qn->link, 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 *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** zigzagLevelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes) { @@ -144,25 +100,43 @@ static int** zigzagLevelOrder(struct TreeNode* root, int* returnSize, int** retu } struct list_head free_list; - struct list_head q0; - struct list_head q1; + struct list_head q; INIT_LIST_HEAD(&free_list); - INIT_LIST_HEAD(&q0); - INIT_LIST_HEAD(&q1); + INIT_LIST_HEAD(&q); int **results = malloc(BST_MAX_LEVEL * sizeof(int *)); *returnColumnSizes = malloc(BST_MAX_LEVEL * sizeof(int)); memset(*returnColumnSizes, 0, BST_MAX_LEVEL * sizeof(int)); - int level = 0; - struct bfs_node *new = node_new(&free_list, root); - list_add_tail(&new->link, &q0); - - while (!list_empty(&q0) || !list_empty(&q1)) { - if (level & 0x1) { - queue(&q1, &q0, 1, &free_list, results, *returnColumnSizes, level); - } else { - queue(&q0, &q1, 0, &free_list, results, *returnColumnSizes, level); + /* Add root node */ + struct queue_node *new = node_new(root, &free_list); + list_add_tail(&new->link, &q); + + int i, level = 0; + (*returnColumnSizes)[level]++; + while (!list_empty(&q)) { + int size = (*returnColumnSizes)[level]; + results[level] = malloc(size * sizeof(int)); + for (i = 0; i < size; i++) { + struct queue_node *qn = list_first_entry(&q, struct queue_node, link); + if (level & 0x1) { + results[level][size - i - 1] = qn->node->val; + } else { + results[level][i] = qn->node->val; + } + + if (qn->node->left != NULL) { + new = node_new(qn->node->left, &free_list); + list_add_tail(&new->link, &q); + (*returnColumnSizes)[level + 1]++; + } + if (qn->node->right != NULL) { + new = node_new(qn->node->right, &free_list); + list_add_tail(&new->link, &q); + (*returnColumnSizes)[level + 1]++; + } + + node_free(qn, &free_list); } level++; } diff --git a/0103_binary_tree_zigzag_level_order_traversal/bst_zigzag.cc b/0103_binary_tree_zigzag_level_order_traversal/bst_zigzag.cc new file mode 100644 index 0000000..026205b --- /dev/null +++ b/0103_binary_tree_zigzag_level_order_traversal/bst_zigzag.cc @@ -0,0 +1,50 @@ +#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> levelOrder(TreeNode* root) { + vector> res; + if (root == nullptr) { + return res; + } + + bool reversed = false; + queue q; + q.push(root); + while (!q.empty()) { + vector level; + int size = q.size(); + for (int i = 0; i < size; i++) { + TreeNode *node = q.front(); + q.pop(); + level.push_back(node->val); + if (node->left != nullptr) { + q.push(node->left); + } + if (node->right != nullptr) { + q.push(node->right); + } + } + if (reversed) { + reverse(level.begin(), level.end()); + } + res.push_back(level); + reversed = !reversed; + } + + return res; + } +}; diff --git a/104_maximum_depth_of_binary_tree/Makefile b/0104_maximum_depth_of_binary_tree/Makefile similarity index 100% rename from 104_maximum_depth_of_binary_tree/Makefile rename to 0104_maximum_depth_of_binary_tree/Makefile diff --git a/104_maximum_depth_of_binary_tree/bst_depth.c b/0104_maximum_depth_of_binary_tree/bst_depth.c similarity index 100% rename from 104_maximum_depth_of_binary_tree/bst_depth.c rename to 0104_maximum_depth_of_binary_tree/bst_depth.c diff --git a/0104_maximum_depth_of_binary_tree/bst_depth.cc b/0104_maximum_depth_of_binary_tree/bst_depth.cc new file mode 100644 index 0000000..fc69b01 --- /dev/null +++ b/0104_maximum_depth_of_binary_tree/bst_depth.cc @@ -0,0 +1,24 @@ +#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 maxDepth(TreeNode* root) { + if (root == nullptr) { + return 0; + } + return 1 + max(maxDepth(root->left), maxDepth(root->right)); + } +}; diff --git a/105_construct_binary_tree_from_preorder_and_inorder_traversal/Makefile b/0105_construct_binary_tree_from_preorder_and_inorder_traversal/Makefile similarity index 100% rename from 105_construct_binary_tree_from_preorder_and_inorder_traversal/Makefile rename to 0105_construct_binary_tree_from_preorder_and_inorder_traversal/Makefile diff --git a/105_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 similarity index 59% rename from 105_construct_binary_tree_from_preorder_and_inorder_traversal/binary_tree_build.c rename to 0105_construct_binary_tree_from_preorder_and_inorder_traversal/binary_tree_build.c index 87bd48c..53d4916 100644 --- a/105_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; } @@ -73,17 +69,8 @@ static int find(int num, int size, struct hlist_head *heads) return -1; } -static struct TreeNode *node_new(int val) -{ - struct TreeNode *tn = malloc(sizeof(*tn)); - tn->val = val; - tn->left = NULL; - tn->right = NULL; - return tn; -} - 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; @@ -96,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, j; - struct hlist_head *in_heads = malloc(inorderSize * sizeof(*in_heads)); + int i; + 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/0105_construct_binary_tree_from_preorder_and_inorder_traversal/binary_tree_build.cc b/0105_construct_binary_tree_from_preorder_and_inorder_traversal/binary_tree_build.cc new file mode 100644 index 0000000..c3e9af6 --- /dev/null +++ b/0105_construct_binary_tree_from_preorder_and_inorder_traversal/binary_tree_build.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: + TreeNode* buildTree(vector& preorder, vector& inorder) { + for (int i = 0; i < inorder.size(); i++) { + map_[inorder[i]] = i; + } + int size = inorder.size(); + return dfs(preorder, 0, size - 1, inorder, 0, size - 1); + } + +private: + unordered_map map_; + TreeNode* dfs(vector& preorder, int pre_lo, int pre_hi, vector& inorder, int in_lo, int in_hi) { + if (pre_lo > pre_hi || in_lo > in_hi) { + return nullptr; + } + int value = preorder[pre_lo]; + TreeNode *root = new TreeNode(value); + int index = map_[value]; + root->left = dfs(preorder, pre_lo + 1, pre_lo + (index - in_lo), inorder, in_lo, index - 1); + root->right = dfs(preorder, pre_hi - (in_hi - index) + 1, pre_hi, inorder, index + 1, in_hi); + return root; + } +}; diff --git a/106_construct_binary_tree_from_inorder_and_postorder_traversal/Makefile b/0106_construct_binary_tree_from_inorder_and_postorder_traversal/Makefile similarity index 100% rename from 106_construct_binary_tree_from_inorder_and_postorder_traversal/Makefile rename to 0106_construct_binary_tree_from_inorder_and_postorder_traversal/Makefile 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 new file mode 100644 index 0000000..5adb6ab --- /dev/null +++ b/0106_construct_binary_tree_from_inorder_and_postorder_traversal/binary_tree_build.c @@ -0,0 +1,134 @@ +#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_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 TreeNode { + int val; + struct TreeNode *left; + struct TreeNode *right; +}; + +struct order_node { + struct list_head link; + int val; + int index; +}; + +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 int find(int num, int size, struct list_head *heads) +{ + struct order_node *on; + int hash = (num < 0 ? -num : num) % size; + list_for_each_entry(on, &heads[hash], link) { + if (num == on->val) { + return on->index; + } + } + return -1; +} + +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; + 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 list_head *in_heads, int size) +{ + if (in_lo > in_hi || post_lo > post_hi) { + return NULL; + } + struct TreeNode *tn = malloc(sizeof(*tn)); + tn->val = postorder[post_hi]; + int index = find(postorder[post_hi], size, in_heads); + tn->left = dfs(inorder, in_lo, index - 1, postorder, post_lo, post_lo + (index - 1 - in_lo), in_heads, size); + tn->right = dfs(inorder, index + 1, in_hi, postorder, post_hi - (in_hi - index), post_hi - 1, in_heads, size); + return tn; +} + +struct TreeNode *buildTree(int *inorder, int inorderSize, int *postorder, int postorderSize) +{ + int i; + struct list_head *in_heads = malloc(inorderSize * sizeof(*in_heads)); + for (i = 0; i < inorderSize; i++) { + INIT_LIST_HEAD(&in_heads[i]); + } + for (i = 0; i < inorderSize; i++) { + node_add(inorder[i], i, inorderSize, in_heads); + } + + return dfs(inorder, 0, inorderSize - 1, postorder, 0, postorderSize - 1, in_heads, inorderSize); +} + +static void dump(struct TreeNode *node) +{ + if (node == NULL) { + printf("# "); + return; + } + printf("%d ", node->val); + dump(node->left); + dump(node->right); +} + +int main(void) +{ + //int postorder[] = { 1,2,3 }; + //int postorder[] = { 2,1,3 }; + //int postorder[] = { 1,3,2 }; + //int postorder[] = { 2,3,1 }; + int postorder[] = { 3,2,1 }; + int inorder[] = { 1,2,3 }; + int post_size = sizeof(postorder) / sizeof(*postorder); + int in_size = sizeof(inorder) / sizeof(*inorder); + struct TreeNode *root = buildTree(inorder, in_size, postorder, post_size); + dump(root); + printf("\n"); + return 0; +} diff --git a/0106_construct_binary_tree_from_inorder_and_postorder_traversal/binary_tree_build.cc b/0106_construct_binary_tree_from_inorder_and_postorder_traversal/binary_tree_build.cc new file mode 100644 index 0000000..b947275 --- /dev/null +++ b/0106_construct_binary_tree_from_inorder_and_postorder_traversal/binary_tree_build.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: + TreeNode* buildTree(vector& inorder, vector& postorder) { + for (int i = 0; i < inorder.size(); i++) { + map_[inorder[i]] = i; + } + int size = inorder.size(); + return dfs(inorder, 0, size - 1, postorder, 0, size - 1); + } + +private: + unordered_map map_; + TreeNode* dfs(vector& inorder, int in_lo, int in_hi, vector& postorder, int post_lo, int post_hi) { + if (in_lo > in_hi || post_lo > post_hi) { + return nullptr; + } + int value = postorder[post_hi]; + TreeNode *root = new TreeNode(value); + int index = map_[value]; + root->left = dfs(inorder, in_lo, index - 1, postorder, post_lo, post_lo + (index - in_lo - 1)); + root->right = dfs(inorder, index + 1, in_hi, postorder, post_hi - (in_hi - index), post_hi - 1); + return root; + } +}; diff --git a/107_binary_tree_level_order_traversal_ii/Makefile b/0107_binary_tree_level_order_traversal_ii/Makefile similarity index 100% rename from 107_binary_tree_level_order_traversal_ii/Makefile rename to 0107_binary_tree_level_order_traversal_ii/Makefile diff --git a/107_binary_tree_level_order_traversal_ii/bst_bfs.c b/0107_binary_tree_level_order_traversal_ii/bst_bfs.c similarity index 84% rename from 107_binary_tree_level_order_traversal_ii/bst_bfs.c rename to 0107_binary_tree_level_order_traversal_ii/bst_bfs.c index 564ae71..2464fbf 100644 --- a/107_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/0107_binary_tree_level_order_traversal_ii/bst_bfs.cc b/0107_binary_tree_level_order_traversal_ii/bst_bfs.cc new file mode 100644 index 0000000..fbd3c0a --- /dev/null +++ b/0107_binary_tree_level_order_traversal_ii/bst_bfs.cc @@ -0,0 +1,46 @@ +#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> levelOrderBottom(TreeNode* root) { + vector> res; + if (root == nullptr) { + return res; + } + + queue q; + q.push(root); + while (!q.empty()) { + int size = q.size(); + vector level; + for (int i = 0; i < size; i++) { + TreeNode *node = q.front(); + q.pop(); + level.push_back(node->val); + if (node->left != nullptr) { + q.push(node->left); + } + if (node->right != nullptr) { + q.push(node->right); + } + } + res.push_back(level); + } + + reverse(res.begin(), res.end()); + return res; + } +}; diff --git a/108_convert_sorted_array_to_binary_search_tree/Makefile b/0108_convert_sorted_array_to_binary_search_tree/Makefile similarity index 100% rename from 108_convert_sorted_array_to_binary_search_tree/Makefile rename to 0108_convert_sorted_array_to_binary_search_tree/Makefile diff --git a/108_convert_sorted_array_to_binary_search_tree/bst_convert.c b/0108_convert_sorted_array_to_binary_search_tree/bst_convert.c similarity index 81% rename from 108_convert_sorted_array_to_binary_search_tree/bst_convert.c rename to 0108_convert_sorted_array_to_binary_search_tree/bst_convert.c index b38e13b..1399058 100644 --- a/108_convert_sorted_array_to_binary_search_tree/bst_convert.c +++ b/0108_convert_sorted_array_to_binary_search_tree/bst_convert.c @@ -10,19 +10,19 @@ struct TreeNode { static struct TreeNode *partition(int *nums, 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 ? partition(nums, lo, mid - 1) : NULL; - node->right = mid < hi ? partition(nums, mid + 1, hi) : NULL; + node->left = partition(nums, lo, mid - 1); + node->right = partition(nums, mid + 1, hi); return node; } static struct TreeNode* sortedArrayToBST(int* nums, int numsSize) { - if (numsSize == 0) { - return NULL; - } return partition(nums, 0, numsSize - 1); } diff --git a/0108_convert_sorted_array_to_binary_search_tree/bst_convert.cc b/0108_convert_sorted_array_to_binary_search_tree/bst_convert.cc new file mode 100644 index 0000000..2a9bc4f --- /dev/null +++ b/0108_convert_sorted_array_to_binary_search_tree/bst_convert.cc @@ -0,0 +1,33 @@ +#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: + TreeNode* sortedArrayToBST(vector& nums) { + return partition(nums, 0, nums.size() - 1); + } + +private: + TreeNode *partition(vector& nums, int lo, int hi) { + if (lo > hi) { + return nullptr; + } + int mid = lo + (hi - lo) / 2; + TreeNode *root = new TreeNode(nums[mid]); + root->left = partition(nums, lo, mid - 1); + root->right = partition(nums, mid + 1, hi); + return root; + } +}; diff --git a/109_convert_sorted_list_to_binary_search_tree/Makefile b/0109_convert_sorted_list_to_binary_search_tree/Makefile similarity index 100% rename from 109_convert_sorted_list_to_binary_search_tree/Makefile rename to 0109_convert_sorted_list_to_binary_search_tree/Makefile 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 new file mode 100644 index 0000000..88434f0 --- /dev/null +++ b/0109_convert_sorted_list_to_binary_search_tree/bst_convert.c @@ -0,0 +1,45 @@ +#include +#include + + +struct ListNode { + int val; + struct ListNode *next; +}; + +struct TreeNode { + int val; + struct TreeNode *left; + struct TreeNode *right; +}; + +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->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) +{ + struct ListNode *p; + int len = 0; + for (p = head; p != NULL; p = p->next) { + len++; + } + return dfs(&head, 0, len - 1); +} + +int main(int argc, char **argv) +{ + sortedListToBST(NULL); + return 0; +} 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/110_balanced_binary_tree/Makefile b/0110_balanced_binary_tree/Makefile similarity index 100% rename from 110_balanced_binary_tree/Makefile rename to 0110_balanced_binary_tree/Makefile diff --git a/110_balanced_binary_tree/balanced_bst.c b/0110_balanced_binary_tree/balanced_bst.c similarity index 100% rename from 110_balanced_binary_tree/balanced_bst.c rename to 0110_balanced_binary_tree/balanced_bst.c diff --git a/0110_balanced_binary_tree/balanced_bst.cc b/0110_balanced_binary_tree/balanced_bst.cc new file mode 100644 index 0000000..b36765b --- /dev/null +++ b/0110_balanced_binary_tree/balanced_bst.cc @@ -0,0 +1,36 @@ +#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: + bool isBalanced(TreeNode* root) { + bool balance = true; + depth(root, balance); + return balance; + } + +private: + int depth(TreeNode *root, bool& balance) { + if (!balance || root == nullptr) { + return 0; + } + int ld = depth(root->left, balance) + 1; + int rd = depth(root->right, balance) + 1; + if (balance) { + balance = abs(ld - rd) <= 1; + } + return max(ld, rd); + } +}; diff --git a/111_minimum_depth_of_binary_tree/Makefile b/0111_minimum_depth_of_binary_tree/Makefile similarity index 100% rename from 111_minimum_depth_of_binary_tree/Makefile rename to 0111_minimum_depth_of_binary_tree/Makefile diff --git a/111_minimum_depth_of_binary_tree/bst_depth.c b/0111_minimum_depth_of_binary_tree/bst_depth.c similarity index 100% rename from 111_minimum_depth_of_binary_tree/bst_depth.c rename to 0111_minimum_depth_of_binary_tree/bst_depth.c diff --git a/0111_minimum_depth_of_binary_tree/bst_depth.cc b/0111_minimum_depth_of_binary_tree/bst_depth.cc new file mode 100644 index 0000000..2d0a0f0 --- /dev/null +++ b/0111_minimum_depth_of_binary_tree/bst_depth.cc @@ -0,0 +1,26 @@ +#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 minDepth(TreeNode* root) { + if (root == nullptr) { + return 0; + } + int ld = minDepth(root->left) + 1; + int rd = minDepth(root->right) + 1; + return ld < rd ? (ld > 1 ? ld : rd) : (rd > 1 ? rd : ld); + } +}; diff --git a/112_path_sum/Makefile b/0112_path_sum/Makefile similarity index 100% rename from 112_path_sum/Makefile rename to 0112_path_sum/Makefile diff --git a/112_path_sum/path_sum.c b/0112_path_sum/path_sum.c similarity index 95% rename from 112_path_sum/path_sum.c rename to 0112_path_sum/path_sum.c index 6cc3e6b..612f482 100644 --- a/112_path_sum/path_sum.c +++ b/0112_path_sum/path_sum.c @@ -2,6 +2,7 @@ #include #include + struct TreeNode { int val; struct TreeNode *left; @@ -11,8 +12,10 @@ struct TreeNode { static bool hasPathSum(struct TreeNode *root, int sum) { if (root == NULL) { + /* Here is non leaf */ return false; } else if (root->left == NULL && root->right == NULL && root->val == sum) { + /* Here must be leaf */ return true; } else { return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val); diff --git a/0112_path_sum/path_sum.cc b/0112_path_sum/path_sum.cc new file mode 100644 index 0000000..5bc36ca --- /dev/null +++ b/0112_path_sum/path_sum.cc @@ -0,0 +1,29 @@ +#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: + bool hasPathSum(TreeNode* root, int sum) { + if (root == nullptr) { + // Here is non leaf + return false; + } else if (root->left == nullptr && root->right == nullptr && root->val == sum) { + // Here must be leaf + return true; + } else { + return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val); + } + } +}; diff --git a/113_path_sum_ii/Makefile b/0113_path_sum_ii/Makefile similarity index 100% rename from 113_path_sum_ii/Makefile rename to 0113_path_sum_ii/Makefile diff --git a/113_path_sum_ii/path_sum.c b/0113_path_sum_ii/path_sum.c similarity index 77% rename from 113_path_sum_ii/path_sum.c rename to 0113_path_sum_ii/path_sum.c index 43071cc..cb52c2f 100644 --- a/113_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/114_flatten_binary_tree_to_linked_list/Makefile b/0114_flatten_binary_tree_to_linked_list/Makefile similarity index 100% rename from 114_flatten_binary_tree_to_linked_list/Makefile rename to 0114_flatten_binary_tree_to_linked_list/Makefile diff --git a/114_flatten_binary_tree_to_linked_list/flatten.c b/0114_flatten_binary_tree_to_linked_list/flatten.c similarity index 100% rename from 114_flatten_binary_tree_to_linked_list/flatten.c rename to 0114_flatten_binary_tree_to_linked_list/flatten.c diff --git a/115_distinct_subsequences/Makefile b/0115_distinct_subsequences/Makefile similarity index 100% rename from 115_distinct_subsequences/Makefile rename to 0115_distinct_subsequences/Makefile diff --git a/115_distinct_subsequences/distinct_subseq.c b/0115_distinct_subsequences/distinct_subseq.c similarity index 100% rename from 115_distinct_subsequences/distinct_subseq.c rename to 0115_distinct_subsequences/distinct_subseq.c diff --git a/116_populating_next_right_pointers_in_each_node/Makefile b/0116_populating_next_right_pointers_in_each_node/Makefile similarity index 100% rename from 116_populating_next_right_pointers_in_each_node/Makefile rename to 0116_populating_next_right_pointers_in_each_node/Makefile diff --git a/116_populating_next_right_pointers_in_each_node/connect.c b/0116_populating_next_right_pointers_in_each_node/connect.c similarity index 81% rename from 116_populating_next_right_pointers_in_each_node/connect.c rename to 0116_populating_next_right_pointers_in_each_node/connect.c index 728a0be..16fbfe3 100644 --- a/116_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/117_populating_next_right_pointers_in_each_node_ii/Makefile b/0117_populating_next_right_pointers_in_each_node_ii/Makefile similarity index 100% rename from 117_populating_next_right_pointers_in_each_node_ii/Makefile rename to 0117_populating_next_right_pointers_in_each_node_ii/Makefile diff --git a/117_populating_next_right_pointers_in_each_node_ii/connect.c b/0117_populating_next_right_pointers_in_each_node_ii/connect.c similarity index 54% rename from 117_populating_next_right_pointers_in_each_node_ii/connect.c rename to 0117_populating_next_right_pointers_in_each_node_ii/connect.c index 2cd5086..f5fb11d 100644 --- a/117_populating_next_right_pointers_in_each_node_ii/connect.c +++ b/0117_populating_next_right_pointers_in_each_node_ii/connect.c @@ -1,12 +1,6 @@ #include #include -struct TreeLinkNode { - int val; - struct TreeLinkNode *left; - struct TreeLinkNode *right; - struct TreeLinkNode *next; -}; #define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - (size_t)&(((type *)0)->member))) @@ -17,16 +11,22 @@ struct TreeLinkNode { #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 val; + struct Node *left; + struct Node *right; + struct Node *next; +}; + +struct queue_node { + struct Node *node; + struct list_head link; +}; + static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list->prev = list; @@ -67,87 +67,72 @@ static inline void list_del(struct list_head *entry) entry->next = entry->prev = NULL; } -struct bfs_node { - struct TreeLinkNode *node; - struct list_head link; -}; - -static struct bfs_node *node_fetch(struct list_head *free_list, struct TreeLinkNode *node) +static struct queue_node *node_new(struct Node *node, struct list_head *free_list) { - struct bfs_node *bn = list_first_entry(free_list, struct bfs_node, link); - list_del(&bn->link); - bn->node = node; - return bn; + struct queue_node *qn; + if (list_empty(free_list)) { + qn = malloc(sizeof(*qn)); + } else { + qn = list_first_entry(free_list, struct queue_node, link); + list_del(&qn->link); + } + qn->node = node; + return qn; } -static void queue(struct list_head *parents, struct list_head *children, struct list_head *free_list) +static void node_free(struct queue_node *qn, struct list_head *free_list) { - struct list_head *p, *n; - struct TreeLinkNode *prev = NULL; - list_for_each_safe(p, n, parents) { - struct bfs_node *new; - struct bfs_node *parent = list_entry(p, struct bfs_node, link); - struct TreeLinkNode *lch = parent->node->left; - struct TreeLinkNode *rch = parent->node->right; - if (lch != NULL) { - if (prev != NULL) { - prev->next = lch; - } - prev = lch; - new = node_fetch(free_list, lch); - list_add_tail(&new->link, children); - } - if (rch != NULL) { - if (prev != NULL) { - prev->next = rch; - } - prev = rch; - new = node_fetch(free_list, rch); - list_add_tail(&new->link, children); - } - - /* return */ - list_del(p); - list_add(p, free_list); - } + list_del(&qn->link); + list_add_tail(&qn->link, free_list); } -static void connect(struct TreeLinkNode *root) +struct Node *connect(struct Node *root) { if (root == NULL) { - return; + return root; } struct list_head free_list; - struct list_head q0; - struct list_head q1; - struct bfs_node nodes[4096]; + struct list_head q; INIT_LIST_HEAD(&free_list); - INIT_LIST_HEAD(&q0); - INIT_LIST_HEAD(&q1); + INIT_LIST_HEAD(&q); - int i; - for (i = 0; i < 4096; i++) { - list_add(&nodes[i].link, &free_list); - } + int i, level_size = 1; + struct queue_node *new = node_new(root, &free_list); + list_add_tail(&new->link, &q); + + while (!list_empty(&q)) { + struct Node *prev = NULL; + int size = level_size; + for (i = 0; i < size; i++) { + struct queue_node *qn = list_first_entry(&q, struct queue_node, link); + if (prev != NULL) { + prev->next = qn->node; + } + prev = qn->node; - int level = 0; - struct bfs_node *new = node_fetch(&free_list, root); - list_add_tail(&new->link, &q0); + if (qn->node->left != NULL) { + new = node_new(qn->node->left, &free_list); + list_add_tail(&new->link, &q); + level_size++; + } + if (qn->node->right != NULL) { + new = node_new(qn->node->right, &free_list); + list_add_tail(&new->link, &q); + level_size++; + } - while (!list_empty(&q0) || !list_empty(&q1)) { - if (level & 0x1) { - queue(&q1, &q0, &free_list); - } else { - queue(&q0, &q1, &free_list); + node_free(qn, &free_list); } - level++; } + + 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]; +#if 0 root.val = 5; n1[0].val = 4; n1[1].val = 8; @@ -188,6 +173,32 @@ int main(int argc, char **argv) n3[7].left = NULL; n3[7].right = NULL; n3[7].next = NULL; +#else + root.val = 1; + n1[0].val = 2; + n1[1].val = 3; + n2[0].val = 4; + n2[1].val = 5; + n2[3].val = 7; + + root.left = &n1[0]; + root.right = &n1[1]; + n1[0].left = &n2[0]; + n1[0].right = &n2[1]; + n1[0].next = NULL; + n1[1].left = NULL; + n1[1].right = &n2[3]; + n1[1].next = NULL; + n2[0].left = NULL; + n2[0].right = NULL; + n2[0].next = NULL; + n2[1].left = NULL; + n2[1].right = NULL; + n2[1].next = NULL; + n2[3].left = NULL; + n2[3].right = NULL; + n2[3].next = NULL; +#endif connect(&root); return 0; diff --git a/0117_populating_next_right_pointers_in_each_node_ii/connect.cc b/0117_populating_next_right_pointers_in_each_node_ii/connect.cc new file mode 100644 index 0000000..8408a8a --- /dev/null +++ b/0117_populating_next_right_pointers_in_each_node_ii/connect.cc @@ -0,0 +1,53 @@ +#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; + } + + queue q; + q.push(root); + while (!q.empty()) { + int size = q.size(); + Node *prev = nullptr; + for (int i = 0; i < size; i++) { + Node *node = q.front(); + q.pop(); + if (prev != nullptr) { + prev->next = node; + } + prev = node; + if (node->left != nullptr) { + q.push(node->left); + } + if (node->right != nullptr) { + q.push(node->right); + } + } + } + + return root; + } +}; diff --git a/118_pascal_triangle/Makefile b/0118_pascal_triangle/Makefile similarity index 100% rename from 118_pascal_triangle/Makefile rename to 0118_pascal_triangle/Makefile diff --git a/118_pascal_triangle/pascal_triangle.c b/0118_pascal_triangle/pascal_triangle.c similarity index 54% rename from 118_pascal_triangle/pascal_triangle.c rename to 0118_pascal_triangle/pascal_triangle.c index 99de1c1..7dee4c4 100644 --- a/118_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/119_pascal_triangle_ii/Makefile b/0119_pascal_triangle_ii/Makefile similarity index 100% rename from 119_pascal_triangle_ii/Makefile rename to 0119_pascal_triangle_ii/Makefile diff --git a/119_pascal_triangle_ii/pascal_triangle.c b/0119_pascal_triangle_ii/pascal_triangle.c similarity index 100% rename from 119_pascal_triangle_ii/pascal_triangle.c rename to 0119_pascal_triangle_ii/pascal_triangle.c diff --git a/120_triangle/Makefile b/0120_triangle/Makefile similarity index 100% rename from 120_triangle/Makefile rename to 0120_triangle/Makefile diff --git a/120_triangle/triangle.c b/0120_triangle/triangle.c similarity index 65% rename from 120_triangle/triangle.c rename to 0120_triangle/triangle.c index 2221137..bcf9875 100644 --- a/120_triangle/triangle.c +++ b/0120_triangle/triangle.c @@ -3,35 +3,35 @@ #include #include + 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); - passes[row][col] = true; + /* Set pass marks in backtracing as the paths are overlapped */ + passed[row][col] = true; return sums[row][col]; } } -static int minimumTotal(int** triangle, int triangleRowSize, int *triangleColSizes) +int minimumTotal(int** triangle, int triangleSize, int *triangleColSizes) { int i; - bool **passes = malloc(triangleRowSize * sizeof(bool *)); - for (i = 0; i < triangleRowSize; i++) { - passes[i] = malloc(triangleColSizes[i]); - memset(passes[i], false, triangleColSizes[i]); - } - int **sums = malloc(triangleRowSize * sizeof(int *)); - for (i = 0; i < triangleRowSize; i++) { + int **sums = malloc(triangleSize * sizeof(int *)); + bool **passed = malloc(triangleSize * sizeof(bool *)); + for (i = 0; i < triangleSize; i++) { + passed[i] = malloc(triangleColSizes[i]); + memset(passed[i], false, triangleColSizes[i]); sums[i] = malloc(triangleColSizes[i] * sizeof(int)); } - return dfs(triangle, triangleRowSize, 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/121_best_time_to_buy_and_sell_stock/Makefile b/0121_best_time_to_buy_and_sell_stock/Makefile similarity index 100% rename from 121_best_time_to_buy_and_sell_stock/Makefile rename to 0121_best_time_to_buy_and_sell_stock/Makefile diff --git a/121_best_time_to_buy_and_sell_stock/stock.c b/0121_best_time_to_buy_and_sell_stock/stock.c similarity index 100% rename from 121_best_time_to_buy_and_sell_stock/stock.c rename to 0121_best_time_to_buy_and_sell_stock/stock.c diff --git a/0121_best_time_to_buy_and_sell_stock/stock.cc b/0121_best_time_to_buy_and_sell_stock/stock.cc new file mode 100644 index 0000000..428a6c7 --- /dev/null +++ b/0121_best_time_to_buy_and_sell_stock/stock.cc @@ -0,0 +1,24 @@ +#include + +using namespace std; + +class Solution { +public: + int maxProfit(vector& prices) { + if (prices.size() == 0) { + return 0; + } + + int diff = 0; + int minimum = prices[0]; + for (int i = 1; i < prices.size(); i++) { + if (prices[i] < minimum) { + minimum = prices[i]; + } else { + diff = prices[i] - minimum > diff ? prices[i] - minimum : diff; + } + } + + return diff; + } +}; diff --git a/122_best_time_to_buy_and_sell_stock_ii/Makefile b/0122_best_time_to_buy_and_sell_stock_ii/Makefile similarity index 100% rename from 122_best_time_to_buy_and_sell_stock_ii/Makefile rename to 0122_best_time_to_buy_and_sell_stock_ii/Makefile diff --git a/122_best_time_to_buy_and_sell_stock_ii/stock.c b/0122_best_time_to_buy_and_sell_stock_ii/stock.c similarity index 100% rename from 122_best_time_to_buy_and_sell_stock_ii/stock.c rename to 0122_best_time_to_buy_and_sell_stock_ii/stock.c diff --git a/0122_best_time_to_buy_and_sell_stock_ii/stock.cc b/0122_best_time_to_buy_and_sell_stock_ii/stock.cc new file mode 100644 index 0000000..eea9433 --- /dev/null +++ b/0122_best_time_to_buy_and_sell_stock_ii/stock.cc @@ -0,0 +1,17 @@ +#include + +using namespace std; + +class Solution { +public: + int maxProfit(vector& prices) { + int diff, sum = 0; + for (int i = 1; i < prices.size(); i++) { + diff = prices[i] - prices[i - 1]; + if (diff > 0) { + sum += diff; + } + } + return sum; + } +}; diff --git a/123_best_time_to_buy_and_sell_stock_iii/Makefile b/0123_best_time_to_buy_and_sell_stock_iii/Makefile similarity index 100% rename from 123_best_time_to_buy_and_sell_stock_iii/Makefile rename to 0123_best_time_to_buy_and_sell_stock_iii/Makefile diff --git a/123_best_time_to_buy_and_sell_stock_iii/stock.c b/0123_best_time_to_buy_and_sell_stock_iii/stock.c similarity index 98% rename from 123_best_time_to_buy_and_sell_stock_iii/stock.c rename to 0123_best_time_to_buy_and_sell_stock_iii/stock.c index c0e38ef..55172db 100644 --- a/123_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/124_binary_tree_maximum_path_sum/Makefile b/0124_binary_tree_maximum_path_sum/Makefile similarity index 100% rename from 124_binary_tree_maximum_path_sum/Makefile rename to 0124_binary_tree_maximum_path_sum/Makefile diff --git a/124_binary_tree_maximum_path_sum/bst_max_path.c b/0124_binary_tree_maximum_path_sum/bst_max_path.c similarity index 90% rename from 124_binary_tree_maximum_path_sum/bst_max_path.c rename to 0124_binary_tree_maximum_path_sum/bst_max_path.c index e3ecad1..ff35b9a 100644 --- a/124_binary_tree_maximum_path_sum/bst_max_path.c +++ b/0124_binary_tree_maximum_path_sum/bst_max_path.c @@ -20,10 +20,10 @@ static int dfs(struct TreeNode *root, int *max) } /* In case of negative node value */ - int l = maximum(dfs(root->left, max), 0); - int r = maximum(dfs(root->right, max), 0); + int subl = maximum(dfs(root->left, max), 0); + int subr = maximum(dfs(root->right, max), 0); - int sum = root->val + l + r; + int sum = root->val + subl + subr; if (sum > *max) { *max = sum; } @@ -31,7 +31,7 @@ static int dfs(struct TreeNode *root, int *max) /* The return value does not equal the sum value * since we need to return path through the root node */ - return root->val + maximum(l, r); + return root->val + maximum(subl, subr); } static int maxPathSum(struct TreeNode* root) diff --git a/0124_binary_tree_maximum_path_sum/bst_max_path.cc b/0124_binary_tree_maximum_path_sum/bst_max_path.cc new file mode 100644 index 0000000..ab1ef58 --- /dev/null +++ b/0124_binary_tree_maximum_path_sum/bst_max_path.cc @@ -0,0 +1,36 @@ +#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 maxPathSum(TreeNode* root) { + dfs(root); + return max_sum; + } + +private: + int max_sum = INT_MIN; + int dfs(TreeNode *root) { + if (root == nullptr) { + return 0; + } + + int subl = max(0, dfs(root->left)); + int subr = max(0, dfs(root->right)); + int sum = root->val + subl + subr; + max_sum = max(sum, max_sum); + return root->val + max(subl, subr); + } +}; diff --git a/125_valid_palindrome/Makefile b/0125_valid_palindrome/Makefile similarity index 100% rename from 125_valid_palindrome/Makefile rename to 0125_valid_palindrome/Makefile diff --git a/125_valid_palindrome/valid_palindrome.c b/0125_valid_palindrome/valid_palindrome.c similarity index 100% rename from 125_valid_palindrome/valid_palindrome.c rename to 0125_valid_palindrome/valid_palindrome.c diff --git a/126_word_ladder_ii/Makefile b/0126_word_ladder_ii/Makefile similarity index 100% rename from 126_word_ladder_ii/Makefile rename to 0126_word_ladder_ii/Makefile diff --git a/126_word_ladder_ii/word_ladder.c b/0126_word_ladder_ii/word_ladder.c similarity index 51% rename from 126_word_ladder_ii/word_ladder.c rename to 0126_word_ladder_ii/word_ladder.c index a4cd2f7..9efc70f 100644 --- a/126_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,52 +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 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; -struct hlist_head { - struct hlist_node *first; -}; - -struct hlist_node { - struct hlist_node *next, **pprev; -}; - -static inline void INIT_HLIST_HEAD(struct hlist_head *h) { - h->first = NULL; -} - -static inline int hlist_empty(struct hlist_head *h) { - return !h->first; -} - -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) -{ - if (h->first != NULL) { - h->first->pprev = &n->next; - } - n->next = h->first; - n->pprev = &h->first; - h->first = 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 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; @@ -95,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 hlist_node 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.. @@ -121,12 +81,11 @@ static int BKDRHash(char* str, int size) return hash % size; } -static struct word_node *find(char *word, struct hlist_head *hhead, int size, int step) +static struct word_node *find(char *word, struct list_head *dict, int size, int step) { - struct hlist_node *p; + struct word_node *node; int hash = BKDRHash(word, size); - hlist_for_each(p, &hhead[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; @@ -136,101 +95,95 @@ static struct word_node *find(char *word, struct hlist_head *hhead, 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 hlist_head *hhead = malloc(hashsize * sizeof(*hhead)); + struct list_head *dict = malloc(hashsize * sizeof(*dict)); for (i = 0; i < hashsize; i++) { - INIT_HLIST_HEAD(hhead + 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); - hlist_add_head(&node->node, &hhead[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, hhead, 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, hhead, 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; } } } @@ -238,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/127_word_ladder/Makefile b/0127_word_ladder/Makefile similarity index 100% rename from 127_word_ladder/Makefile rename to 0127_word_ladder/Makefile diff --git a/127_word_ladder/word_ladder.c b/0127_word_ladder/word_ladder.c similarity index 70% rename from 127_word_ladder/word_ladder.c rename to 0127_word_ladder/word_ladder.c index c025ce4..f057487 100644 --- a/127_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,43 +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 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; - -struct hlist_head { - struct hlist_node *first; -}; - -struct hlist_node { - struct hlist_node *next, **pprev; -}; - -static inline void INIT_HLIST_HEAD(struct hlist_head *h) { - h->first = NULL; -} - -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) -{ - if (h->first != NULL) { - h->first->pprev = &n->next; - } - n->next = h->first; - n->pprev = &h->first; - h->first = 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 list_head { struct list_head *next, *prev; @@ -94,7 +63,7 @@ static inline void list_del(struct list_head *entry) struct word_node { int step; char *word; - struct hlist_node node; + struct list_head node; struct list_head link; }; @@ -108,12 +77,11 @@ static int BKDRHash(char* str, int size) return hash % size; } -static struct word_node *find(char *word, struct hlist_head *hhead, int size) +static struct word_node *find(char *word, struct list_head *dict, int size) { - struct hlist_node *p; + struct word_node *node; int hash = BKDRHash(word, size); - hlist_for_each(p, &hhead[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; } @@ -128,18 +96,25 @@ static int ladderLength(char* beginWord, char* endWord, char** wordList, int wor struct list_head queue; struct word_node *node; - struct hlist_head *hhead = malloc(wordListSize * sizeof(*hhead)); + struct list_head *dict = malloc(wordListSize * sizeof(*dict)); for (i = 0; i < wordListSize; i++) { - INIT_HLIST_HEAD(hhead + 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); - hlist_add_head(&node->node, &hhead[hash]); + list_add(&node->node, &dict[hash]); + if (!strcmp(endWord, wordList[i])) { + found = true; + } + } + if (!found) { + return 0; } /* FIFO */ @@ -157,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, hhead, wordListSize); + node = find(word, dict, wordListSize); if (node != NULL) { + /* enqueue */ list_add_tail(&node->link, &queue); node->step = first->step + 1; } @@ -169,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/128_longest_consecutive_sequence/Makefile b/0128_longest_consecutive_sequence/Makefile similarity index 100% rename from 128_longest_consecutive_sequence/Makefile rename to 0128_longest_consecutive_sequence/Makefile diff --git a/0128_longest_consecutive_sequence/consec_seq.c b/0128_longest_consecutive_sequence/consec_seq.c new file mode 100644 index 0000000..d42b664 --- /dev/null +++ b/0128_longest_consecutive_sequence/consec_seq.c @@ -0,0 +1,122 @@ +#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_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 seq_node { + int num; + struct list_head link; +}; + +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; +} + +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; + list_for_each_entry(node, &heads[hash], link) { + if (node->num == num) { + return node; + } + } + return NULL; +} + +int longestConsecutive(int* nums, int numsSize) +{ + int i, hash, length = 0; + struct seq_node *node; + struct list_head *heads = malloc(numsSize * sizeof(*heads)); + + for (i = 0; i < numsSize; i++) { + INIT_LIST_HEAD(&heads[i]); + } + + for (i = 0; i < numsSize; i++) { + if (!find(nums[i], numsSize, heads)) { + hash = nums[i] < 0 ? -nums[i] % numsSize : nums[i] % numsSize; + node = malloc(sizeof(*node)); + node->num = nums[i]; + list_add(&node->link, &heads[hash]); + } + } + + for (i = 0; i < numsSize; i++) { + /* 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++; + list_del(&node->link); + } + length = len > length ? len : length; + } + } + + return length; +} + +int main(int argc, char **argv) +{ + int i, size = argc - 1; + int *nums = malloc(size * sizeof(int)); + for (i = 0; i < size; i++) { + nums[i] = atoi(argv[i + 1]); + } + printf("%d\n", longestConsecutive(nums, size)); + return 0; +} 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/129_sum_root_to_leaf_numbers/Makefile b/0129_sum_root_to_leaf_numbers/Makefile similarity index 100% rename from 129_sum_root_to_leaf_numbers/Makefile rename to 0129_sum_root_to_leaf_numbers/Makefile diff --git a/129_sum_root_to_leaf_numbers/sum_tree.c b/0129_sum_root_to_leaf_numbers/sum_tree.c similarity index 88% rename from 129_sum_root_to_leaf_numbers/sum_tree.c rename to 0129_sum_root_to_leaf_numbers/sum_tree.c index 686b3d8..8580e8b 100644 --- a/129_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/130_surrounded_regions/Makefile b/0130_surrounded_regions/Makefile similarity index 100% rename from 130_surrounded_regions/Makefile rename to 0130_surrounded_regions/Makefile diff --git a/130_surrounded_regions/surrounded_regions.c b/0130_surrounded_regions/surrounded_regions.c similarity index 78% rename from 130_surrounded_regions/surrounded_regions.c rename to 0130_surrounded_regions/surrounded_regions.c index 304b4c7..701f5ed 100644 --- a/130_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/131_palindrome_patitioning/Makefile b/0131_palindrome_patitioning/Makefile similarity index 100% rename from 131_palindrome_patitioning/Makefile rename to 0131_palindrome_patitioning/Makefile diff --git a/131_palindrome_patitioning/palindrome_partition.c b/0131_palindrome_patitioning/palindrome_partition.c similarity index 93% rename from 131_palindrome_patitioning/palindrome_partition.c rename to 0131_palindrome_patitioning/palindrome_partition.c index cc83084..f871f19 100644 --- a/131_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/132_palindrome_patitioning_ii/Makefile b/0132_palindrome_patitioning_ii/Makefile similarity index 100% rename from 132_palindrome_patitioning_ii/Makefile rename to 0132_palindrome_patitioning_ii/Makefile diff --git a/132_palindrome_patitioning_ii/palindrome_partition.c b/0132_palindrome_patitioning_ii/palindrome_partition.c similarity index 100% rename from 132_palindrome_patitioning_ii/palindrome_partition.c rename to 0132_palindrome_patitioning_ii/palindrome_partition.c diff --git a/133_clone_graph/Makefile b/0133_clone_graph/Makefile similarity index 100% rename from 133_clone_graph/Makefile rename to 0133_clone_graph/Makefile diff --git a/133_clone_graph/clone_graph.c b/0133_clone_graph/clone_graph.c similarity index 53% rename from 133_clone_graph/clone_graph.c rename to 0133_clone_graph/clone_graph.c index e6ef47c..1c18389 100644 --- a/133_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/134_gas_station/Makefile b/0134_gas_station/Makefile similarity index 100% rename from 134_gas_station/Makefile rename to 0134_gas_station/Makefile diff --git a/134_gas_station/gas_station.c b/0134_gas_station/gas_station.c similarity index 100% rename from 134_gas_station/gas_station.c rename to 0134_gas_station/gas_station.c diff --git a/135_candy/Makefile b/0135_candy/Makefile similarity index 100% rename from 135_candy/Makefile rename to 0135_candy/Makefile diff --git a/135_candy/candy.c b/0135_candy/candy.c similarity index 88% rename from 135_candy/candy.c rename to 0135_candy/candy.c index 20721bd..063797d 100644 --- a/135_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/136_single_number/Makefile b/0136_single_number/Makefile similarity index 100% rename from 136_single_number/Makefile rename to 0136_single_number/Makefile diff --git a/136_single_number/single_number.c b/0136_single_number/single_number.c similarity index 100% rename from 136_single_number/single_number.c rename to 0136_single_number/single_number.c diff --git a/0136_single_number/single_number.cc b/0136_single_number/single_number.cc new file mode 100644 index 0000000..a0652f8 --- /dev/null +++ b/0136_single_number/single_number.cc @@ -0,0 +1,14 @@ +#include + +using namespace std; + +class Solution { +public: + int singleNumber(vector& nums) { + int res = nums[0]; + for (int i = 1; i < nums.size(); i++) { + res ^= nums[i]; + } + return res; + } +}; diff --git a/137_single_number_ii/Makefile b/0137_single_number_ii/Makefile similarity index 100% rename from 137_single_number_ii/Makefile rename to 0137_single_number_ii/Makefile diff --git a/137_single_number_ii/single_number.c b/0137_single_number_ii/single_number.c similarity index 94% rename from 137_single_number_ii/single_number.c rename to 0137_single_number_ii/single_number.c index bf5beae..b02f66f 100644 --- a/137_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/138_copy_list_with_random_pointer/Makefile b/0138_copy_list_with_random_pointer/Makefile similarity index 100% rename from 138_copy_list_with_random_pointer/Makefile rename to 0138_copy_list_with_random_pointer/Makefile diff --git a/138_copy_list_with_random_pointer/copy_list.c b/0138_copy_list_with_random_pointer/copy_list.c similarity index 64% rename from 138_copy_list_with_random_pointer/copy_list.c rename to 0138_copy_list_with_random_pointer/copy_list.c index 5fe458f..39c762d 100644 --- a/138_copy_list_with_random_pointer/copy_list.c +++ b/0138_copy_list_with_random_pointer/copy_list.c @@ -9,35 +9,33 @@ struct Node { static struct Node *copyRandomList(struct Node *head) { - if (head == NULL) { - return NULL; - } - - /* copy and redirect next pointer */ - struct Node *p, *new; - for (p = head; p != NULL; p = p->next->next) { - new = malloc(sizeof(*new)); - new->val = p->val; - new->next = p->next; - p->next = new; + struct Node *p, *q; + /* insert interleavingly */ + for (p = head; p != NULL; p = q->next) { + q = malloc(sizeof(*q)); + q->val = p->val; + q->next = p->next; + p->next = q; } /* clone random pointer */ - for (p = head; p != NULL; p = p->next->next) { - new = p->next; - new->random = p->random != NULL ? p->random->next : NULL; + for (p = head; p != NULL; p = q->next) { + q = p->next; + q->random = p->random != NULL ? p->random->next : NULL; } struct Node dummy; struct Node *prev = &dummy; - for (p = head; p != NULL; p = p->next) { - new = p->next; - p->next = new->next; - /* correct the actual next pointer of the new list */ - prev->next = new; - prev = new; - new->next = NULL; + prev->next = head; + /* separate q list */ + for (p = head; p != NULL; p = q->next) { + q = p->next; + /* restore p->next */ + p->next = q->next; + prev->next = q; + prev = q; } + /* q->next = NULL */ return dummy.next; } diff --git a/0138_copy_list_with_random_pointer/copy_list.cc b/0138_copy_list_with_random_pointer/copy_list.cc new file mode 100644 index 0000000..90d0c8e --- /dev/null +++ b/0138_copy_list_with_random_pointer/copy_list.cc @@ -0,0 +1,52 @@ +#include + +using namespace std; + +/* +// Definition for a Node. +class Node { +public: + int val; + Node* next; + Node* random; + + Node(int _val) { + val = _val; + next = nullptr; + random = nullptr; + } +}; +*/ + +class Solution { +public: + Node* copyRandomList(Node* head) { + Node *p, *q; + // Insert interleavingly + for (p = head; p != nullptr; p = q->next) { + q = Node(p->val); + q->next = p->next; + p->next = q; + } + + // Clone random pointers + for (p = head; p != nullptr; p = q->next) { + q = p->next; + q->random = p->random != nullptr ? p->random->next : nullptr; + } + + // Separate q list + Node dummy; + Node *prev = &dummy; + prev->next = head; + for (p = head; p != nullptr; p = q->next) { + q = p->next; + p->next = q->next; // restore p->next + prev->next = q; + prev = q; + } + /* q->next == nullptr */ + + return dummy.next; + } +}; diff --git a/139_word_break/Makefile b/0139_word_break/Makefile similarity index 100% rename from 139_word_break/Makefile rename to 0139_word_break/Makefile diff --git a/0139_word_break/word_break.c b/0139_word_break/word_break.c new file mode 100644 index 0000000..145d99d --- /dev/null +++ b/0139_word_break/word_break.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include + + +static int dfs(char *s, char **words, int *lens, int size, bool *ends, int index) +{ + int i, j; + if (*s == '\0') { + return true; + } else if (!ends[index]) { + return false; + } else { + 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 ends[index]; + } +} + +bool wordBreak(char * s, char ** wordDict, int wordDictSize) +{ + if (wordDictSize == 0) { + return false; + } + + int i, len = strlen(s); + int *lens = malloc(wordDictSize * sizeof(int)); + for (i = 0; i < wordDictSize; i++) { + lens[i] = strlen(wordDict[i]); + } + + bool *ends = malloc(len); + memset(ends, true, len); + return dfs(s, wordDict, lens, wordDictSize, ends, 0); +} + +int main(int argc, char **argv) +{ + if (argc < 3) { + fprintf(stderr, "Usage: ./test word dictionary...\n"); + exit(-1); + } + + printf("%s\n", wordBreak(argv[1], argv + 2, argc - 2) ? "true" : "false"); + return 0; +} diff --git a/140_word_break_ii/Makefile b/0140_word_break_ii/Makefile similarity index 100% rename from 140_word_break_ii/Makefile rename to 0140_word_break_ii/Makefile diff --git a/0140_word_break_ii/word_break.c b/0140_word_break_ii/word_break.c new file mode 100644 index 0000000..588bc1e --- /dev/null +++ b/0140_word_break_ii/word_break.c @@ -0,0 +1,160 @@ +#include +#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_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; +} + +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 void new_word_add(struct list_head *head, char *word) +{ + struct word_node *wn = malloc(sizeof(*wn)); + wn->word = word; + list_add_tail(&wn->link, head); +} + +static struct solution *dfs(char *s, char **words, int *lens, int size, + struct solution **sols, int index) +{ + int i, j; + if (*s == '\0') { + return NULL; + } else if (sols[index] != NULL) { + return sols[index]; + } else { + 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); + } + sol->count++; + } + } else { + /* leaf node */ + INIT_LIST_HEAD(&sol->heads[0]); + new_word_add(&sol->heads[sol->count++], words[i]); + } + } + } + return sol; + } +} + +/** + * 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; + return NULL; + } + + int i, total = 0; + int len = strlen(s); + int *lens = malloc(wordDictSize * sizeof(int)); + + /* Add into hash list */ + for (i = 0; i < wordDictSize; i++) { + lens[i] = strlen(wordDict[i]); + total += lens[i]; + } + + 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(sol->count * sizeof(char *)); + for (i = 0; i < sol->count; i++) { + results[i] = malloc(total + 100); + char *p = results[i]; + struct word_node *wn; + list_for_each_entry(wn, &sol->heads[i], link) { + char *q = wn->word; + while ((*p++ = *q++) != '\0') {} + *(p - 1) = ' '; + } + *(p - 1) = '\0'; + } + + *returnSize = sol->count; + return results; +} + +int main(int argc, char **argv) +{ + if (argc < 3) { + fprintf(stderr, "Usage: ./test word dictionary...\n"); + exit(-1); + } + + int i, count = 0; + char **list = wordBreak(argv[1], argv + 2, argc - 2, &count); + for (i = 0; i < count; i++) { + printf("%s\n", list[i]); + } + return 0; +} diff --git a/141_linked_list_cycle/Makefile b/0141_linked_list_cycle/Makefile similarity index 100% rename from 141_linked_list_cycle/Makefile rename to 0141_linked_list_cycle/Makefile diff --git a/141_linked_list_cycle/list_cycle.c b/0141_linked_list_cycle/list_cycle.c similarity index 70% rename from 141_linked_list_cycle/list_cycle.c rename to 0141_linked_list_cycle/list_cycle.c index 1b16d87..d1a283c 100644 --- a/141_linked_list_cycle/list_cycle.c +++ b/0141_linked_list_cycle/list_cycle.c @@ -9,17 +9,14 @@ struct ListNode { static bool hasCycle(struct ListNode *head) { - if (head == NULL || head->next == NULL) { - return false; - } - - bool first = true; - struct ListNode *p0, *p1; - for (p0 = head, p1 = head; p1 != NULL && p1->next != NULL; p0 = p0->next, p1 = p1->next->next) { - if (p0 == p1 && !first) { + struct ListNode *fast = head; + struct ListNode *slow = head; + while (fast != NULL && fast->next != NULL) { + slow = slow->next; + fast = fast->next->next; + if (fast == slow) { return true; } - first = false; } return false; diff --git a/0141_linked_list_cycle/list_cycle.cc b/0141_linked_list_cycle/list_cycle.cc new file mode 100644 index 0000000..323d5c8 --- /dev/null +++ b/0141_linked_list_cycle/list_cycle.cc @@ -0,0 +1,27 @@ +#include + +using namespace std; + +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode(int x) : val(x), next(nullptr) {} + * }; + */ +class Solution { +public: + bool hasCycle(ListNode *head) { + struct ListNode *fast = head; + struct ListNode *slow = head; + while (fast != nullptr && fast->next != nullptr) { + slow = slow->next; + fast = fast->next->next; + if (fast == slow) { + return true; + } + } + return false; + } +}; diff --git a/142_linked_list_cycle_ii/Makefile b/0142_linked_list_cycle_ii/Makefile similarity index 100% rename from 142_linked_list_cycle_ii/Makefile rename to 0142_linked_list_cycle_ii/Makefile diff --git a/142_linked_list_cycle_ii/list_cycle.c b/0142_linked_list_cycle_ii/list_cycle.c similarity index 62% rename from 142_linked_list_cycle_ii/list_cycle.c rename to 0142_linked_list_cycle_ii/list_cycle.c index d8f55bc..9840230 100644 --- a/142_linked_list_cycle_ii/list_cycle.c +++ b/0142_linked_list_cycle_ii/list_cycle.c @@ -9,22 +9,19 @@ struct ListNode { static struct ListNode *detectCycle(struct ListNode *head) { - if (head == NULL || head->next == NULL) { - return false; - } - - bool first = true; - struct ListNode *p0, *p1; - for (p0 = head, p1 = head; p1 != NULL && p1->next != NULL; p0 = p0->next, p1 = p1->next->next) { - if (p0 == p1 && !first) { - p0 = head; - while (p0 != p1) { - p0 = p0->next; - p1 = p1->next; + struct ListNode *fast = head; + struct ListNode *slow = head; + while (fast != NULL && fast->next != NULL) { + slow = slow->next; + fast = fast->next->next; + if (fast == slow) { + fast = head; + while (fast != slow) { + fast = fast->next; + slow = slow->next; } - return p0; + return fast; } - first = false; } return NULL; diff --git a/0142_linked_list_cycle_ii/list_cycle.cc b/0142_linked_list_cycle_ii/list_cycle.cc new file mode 100644 index 0000000..6b404b1 --- /dev/null +++ b/0142_linked_list_cycle_ii/list_cycle.cc @@ -0,0 +1,32 @@ +#include + +using namespace std; + +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode(int x) : val(x), next(nullptr) {} + * }; + */ +class Solution { +public: + ListNode* detectCycle(ListNode *head) { + ListNode *fast = head; + ListNode *slow = head; + while (fast != nullptr && fast->next != nullptr) { + slow = slow->next; + fast = fast->next->next; + if (fast == slow) { + fast = head; + while (fast != slow) { + fast = fast->next; + slow = slow->next; + } + return fast; + } + } + return nullptr; + } +}; diff --git a/143_reorder_list/Makefile b/0143_reorder_list/Makefile similarity index 100% rename from 143_reorder_list/Makefile rename to 0143_reorder_list/Makefile diff --git a/143_reorder_list/reorder_list.c b/0143_reorder_list/reorder_list.c similarity index 100% rename from 143_reorder_list/reorder_list.c rename to 0143_reorder_list/reorder_list.c diff --git a/144_binary_tree_preorder_traversal/Makefile b/0144_binary_tree_preorder_traversal/Makefile similarity index 100% rename from 144_binary_tree_preorder_traversal/Makefile rename to 0144_binary_tree_preorder_traversal/Makefile diff --git a/144_binary_tree_preorder_traversal/bst_preorder.c b/0144_binary_tree_preorder_traversal/bst_preorder.c similarity index 74% rename from 144_binary_tree_preorder_traversal/bst_preorder.c rename to 0144_binary_tree_preorder_traversal/bst_preorder.c index a639003..a5372fa 100644 --- a/144_binary_tree_preorder_traversal/bst_preorder.c +++ b/0144_binary_tree_preorder_traversal/bst_preorder.c @@ -21,24 +21,21 @@ static int* preorderTraversal(struct TreeNode* root, int* returnSize) int *results = malloc(cap * sizeof(int)); struct TreeNode **stack = malloc(cap / 16 * sizeof(*stack)); struct TreeNode **top = stack; - struct TreeNode *node = root; - /* node != NULL condition is just for the first iteration and + /* root != NULL condition is just for the first iteration and * never push NULL into the stack */ - while (node != NULL || top != stack) { - if (node == NULL) { - /* pop up */ - node = *--top; + while (root != NULL || top != stack) { + if (root != NULL) { + results[count++] = root->val; + /* store the parent node */ + *top++ = root; + root = root->left; + } else { + /* pop up the parent node */ + root = *--top; + root = root->right; } - - results[count++] = node->val; - - if (node->right != NULL) { - *top++ = node->right; - } - - node = node->left; } *returnSize = count; diff --git a/0144_binary_tree_preorder_traversal/bst_preorder.cc b/0144_binary_tree_preorder_traversal/bst_preorder.cc new file mode 100644 index 0000000..1304a65 --- /dev/null +++ b/0144_binary_tree_preorder_traversal/bst_preorder.cc @@ -0,0 +1,34 @@ +#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 preorderTraversal(TreeNode* root) { + vector res; + stack stk; + while (!stk.empty() || root != nullptr) { + if (root != nullptr) { + res.push_back(root->val); + stk.push(root); + root = root->left; + } else { + root = stk.top(); + stk.pop(); + root = root->right; + } + } + return res; + } +}; diff --git a/145_binary_tree_postorder_traversal/Makefile b/0145_binary_tree_postorder_traversal/Makefile similarity index 100% rename from 145_binary_tree_postorder_traversal/Makefile rename to 0145_binary_tree_postorder_traversal/Makefile diff --git a/145_binary_tree_postorder_traversal/bst_postorder.c b/0145_binary_tree_postorder_traversal/bst_postorder.c similarity index 57% rename from 145_binary_tree_postorder_traversal/bst_postorder.c rename to 0145_binary_tree_postorder_traversal/bst_postorder.c index e54d3a8..47f49d8 100644 --- a/145_binary_tree_postorder_traversal/bst_postorder.c +++ b/0145_binary_tree_postorder_traversal/bst_postorder.c @@ -12,50 +12,43 @@ struct node_backlog { struct TreeNode *right; }; -static int counting(struct TreeNode* node) -{ - if (node == NULL) { - return 0; - } - return 1 + counting(node->left) + counting(node->right); -} - /** ** Return an array of size *returnSize. ** Note: The returned array must be malloced, assume caller calls free(). **/ static int* postorderTraversal(struct TreeNode* root, int* returnSize) { - if (root == NULL) { - return NULL; - } - - *returnSize = counting(root); - int count = 0; - int *results = malloc(*returnSize * sizeof(int)); - struct node_backlog *stack = malloc(*returnSize * sizeof(*stack)); + int *results = malloc(100 * sizeof(int)); + struct node_backlog *stack = malloc(100 * sizeof(*stack)); struct node_backlog *top = stack; - struct TreeNode *node = root; - while (node != NULL || top != stack) { - if (node == NULL) { + /* root != NULL condition is just for the first iteration and + * never push NULL into the stack + */ + while (root != NULL || top != stack) { + if (root != NULL) { + /* push both parent and its right child */ + top->parent = root; + top->right = root->right; + top++; + root = root->left; + } else { if ((top - 1)->right != NULL) { - node = (top - 1)->right; + /* switch to right child but not pop up the parent */ + root = (top - 1)->right; + /* avoid infinite loop */ (top - 1)->right = NULL; } else { - node = (--top)->parent; - results[count++] = node->val; - node = NULL; - continue; + root = (--top)->parent; + results[count++] = root->val; + /* we need to backtrace */ + root = NULL; } } - top->parent = node; - top->right = node->right; - top++; - node = node->left; } + *returnSize = count; return results; } diff --git a/0145_binary_tree_postorder_traversal/bst_postorder.cc b/0145_binary_tree_postorder_traversal/bst_postorder.cc new file mode 100644 index 0000000..a73d170 --- /dev/null +++ b/0145_binary_tree_postorder_traversal/bst_postorder.cc @@ -0,0 +1,40 @@ +#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 postorderTraversal(TreeNode* root) { + vector res; + stack> stk; + while (!stk.empty() || root != nullptr) { + if (root != nullptr) { + stk.push(make_pair(root, root->right)); + root = root->left; + } else { + if (stk.top().second != nullptr) { + // Into right + root = stk.top().second; + stk.top().second = nullptr; + } else { + // True backtracing + res.push_back(stk.top().first->val); + stk.pop(); + root = nullptr; + } + } + } + return res; + } +}; diff --git a/146_lru_cache/Makefile b/0146_lru_cache/Makefile similarity index 100% rename from 146_lru_cache/Makefile rename to 0146_lru_cache/Makefile diff --git a/0146_lru_cache/lru_cache.c b/0146_lru_cache/lru_cache.c new file mode 100644 index 0000000..205896c --- /dev/null +++ b/0146_lru_cache/lru_cache.c @@ -0,0 +1,233 @@ +#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_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_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_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; +}; + +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) +{ + 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; +} + +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) +{ + __list_del(entry); + list_add_tail(entry, head); +} + +LRUCache *lRUCacheCreate(int capacity) +{ + int i; + LRUCache *obj = malloc(sizeof(*obj) + capacity * sizeof(struct list_head)); + obj->count = 0; + obj->capacity = capacity; + INIT_LIST_HEAD(&obj->dhead); + for (i = 0; i < capacity; i++) { + INIT_LIST_HEAD(&obj->hheads[i]); + } + return obj; +} + +void lRUCacheFree(LRUCache *obj) +{ + LRUNode *lru, *n; + list_for_each_entry_safe(lru, n, &obj->dhead, dlink) { + list_del(&lru->dlink); + free(lru); + } + free(obj); +} + +int lRUCacheGet(LRUCache *obj, int key) +{ + LRUNode *lru; + int hash = key % obj->capacity; + list_for_each_entry(lru, &obj->hheads[hash], hlink) { + if (lru->key == key) { + /* Move it to header */ + list_move(&lru->dlink, &obj->dhead); + return lru->value; + } + } + return -1; +} + +void lRUCachePut(LRUCache *obj, int key, int value) +{ + LRUNode *lru; + int hash = key % obj->capacity; + list_for_each_entry(lru, &obj->hheads[hash], hlink) { + if (lru->key == key) { + list_move(&lru->dlink, &obj->dhead); + lru->value = value; + return; + } + } + + if (obj->count == obj->capacity) { + lru = list_last_entry(&obj->dhead, LRUNode, dlink); + list_del(&lru->dlink); + list_del(&lru->hlink); + } else { + lru = malloc(sizeof(LRUNode)); + obj->count++; + } + lru->key = key; + list_add(&lru->dlink, &obj->dhead); + list_add(&lru->hlink, &obj->hheads[hash]); + lru->value = value; +} + +void lRUCacheDump(LRUCache *obj) +{ + if (obj == NULL) return; + + int i; + LRUNode *lru; + printf(">>> Total %d nodes: \n", obj->count); + for (i = 0; i < obj->count; i++) { + printf("hash:%d:", i); + 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); + } + } + printf("\n"); + } + + printf(">>> Double list dump\n"); + list_for_each_entry(lru, &obj->dhead, dlink) { + printf("(%d %d)\n", lru->key, lru->value); + } +} + +int main(void) +{ + LRUCache *obj; + obj = lRUCacheCreate(2); + printf("put 1, 1\n"); + lRUCachePut(obj, 1, 1); + printf("put 2, 2\n"); + lRUCachePut(obj, 2, 2); + printf("get 1, %d\n", lRUCacheGet(obj, 1)); + printf("put 3, 3\n"); + lRUCachePut(obj, 3, 3); + printf("get 2, %d\n", lRUCacheGet(obj, 2)); + printf("put 4, 4\n"); + lRUCachePut(obj, 4, 4); + printf("get 1, %d\n", lRUCacheGet(obj, 1)); + printf("get 3, %d\n", lRUCacheGet(obj, 3)); + printf("get 4, %d\n", lRUCacheGet(obj, 4)); +//#if 1 +// obj = lRUCacheCreate(2); +// lRUCacheDump(obj); +// printf("get 2, %d\n", lRUCacheGet(obj, 2)); +// printf("put 2, 6\n"); +// lRUCachePut(obj, 2, 6); +// lRUCacheDump(obj); +// printf("get 1, %d\n", lRUCacheGet(obj, 1)); +// printf("put 1, 5\n"); +// lRUCachePut(obj, 1, 5); +// lRUCacheDump(obj); +// printf("put 1, 2\n"); +// lRUCachePut(obj, 1, 2); +// lRUCacheDump(obj); +// printf("get 1, %d\n", lRUCacheGet(obj, 1)); +// printf("get 2, %d\n", lRUCacheGet(obj, 2)); +// lRUCacheFree(obj); +//#else +// obj = lRUCacheCreate(2); +// printf("put 2, 1\n"); +// lRUCachePut(obj, 2, 1); +// printf("put 1, 1\n"); +// lRUCachePut(obj, 1, 1); +// lRUCacheDump(obj); +// printf("get 2, %d\n", lRUCacheGet(obj, 2)); +// lRUCacheDump(obj); +// printf("put 4, 1\n"); +// lRUCachePut(obj, 4, 1); +// lRUCacheDump(obj); +// printf("get 1, %d\n", lRUCacheGet(obj, 1)); +// printf("get 2, %d\n", lRUCacheGet(obj, 2)); +// lRUCacheFree(obj); +//#endif + + return 0; +} diff --git a/0146_lru_cache/lru_cache.cc b/0146_lru_cache/lru_cache.cc new file mode 100644 index 0000000..74cb60c --- /dev/null +++ b/0146_lru_cache/lru_cache.cc @@ -0,0 +1,54 @@ +#include + +using namespace std; + +/** + * Your LRUCache object will be instantiated and called as such: + * LRUCache* obj = new LRUCache(capacity); + * int param_1 = obj->get(key); + * obj->put(key,value); + */ +class LRUCache { +public: + LRUCache(int capacity) { + cap_ = capacity; + } + + int get(int key) { + if (ht_.count(key) == 0) { + return -1; + } + + int value = (*ht_[key]).second; + if (li_.front().first != key) { + li_.erase(ht_[key]); + li_.push_front(make_pair(key, value)); + ht_[key] = li_.begin(); // iterator failure + } + + return value; + } + + void put(int key, int value) { + if (cap_ <= 0) { + return; + } + + if (ht_.count(key) == 0) { + li_.erase(ht_[key]); + } else { + if (li_.size() == cap_) { + auto lru = li_.back(); + li_.pop_back(); + ht_.erase(lru.first); + } + } + li_.push_front(make_pair(key, value)); + ht_[key] = li_.begin(); // iterator failure + } + +private: + int cap_; + list> li_; + unordered_map>::iterator> ht_; +}; diff --git a/147_insertion_sort_list/Makefile b/0147_insertion_sort_list/Makefile similarity index 100% rename from 147_insertion_sort_list/Makefile rename to 0147_insertion_sort_list/Makefile diff --git a/147_insertion_sort_list/insert_sort_list.c b/0147_insertion_sort_list/insert_sort_list.c similarity index 100% rename from 147_insertion_sort_list/insert_sort_list.c rename to 0147_insertion_sort_list/insert_sort_list.c diff --git a/148_sort_list/Makefile b/0148_sort_list/Makefile similarity index 100% rename from 148_sort_list/Makefile rename to 0148_sort_list/Makefile diff --git a/148_sort_list/sort_list.c b/0148_sort_list/sort_list.c similarity index 100% rename from 148_sort_list/sort_list.c rename to 0148_sort_list/sort_list.c diff --git a/149_max_points_on_a_line/Makefile b/0149_max_points_on_a_line/Makefile similarity index 100% rename from 149_max_points_on_a_line/Makefile rename to 0149_max_points_on_a_line/Makefile diff --git a/149_max_points_on_a_line/points_on_line.c b/0149_max_points_on_a_line/points_on_line.c similarity index 73% rename from 149_max_points_on_a_line/points_on_line.c rename to 0149_max_points_on_a_line/points_on_line.c index 96c0122..c0ad22f 100644 --- a/149_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/150_evaluate_reverse_polish_notation/Makefile b/0150_evaluate_reverse_polish_notation/Makefile similarity index 100% rename from 150_evaluate_reverse_polish_notation/Makefile rename to 0150_evaluate_reverse_polish_notation/Makefile diff --git a/150_evaluate_reverse_polish_notation/eval_rpn.c b/0150_evaluate_reverse_polish_notation/eval_rpn.c similarity index 100% rename from 150_evaluate_reverse_polish_notation/eval_rpn.c rename to 0150_evaluate_reverse_polish_notation/eval_rpn.c diff --git a/151_reverse_words_in_a_string/Makefile b/0151_reverse_words_in_a_string/Makefile similarity index 100% rename from 151_reverse_words_in_a_string/Makefile rename to 0151_reverse_words_in_a_string/Makefile diff --git a/151_reverse_words_in_a_string/reverse.c b/0151_reverse_words_in_a_string/reverse.c similarity index 100% rename from 151_reverse_words_in_a_string/reverse.c rename to 0151_reverse_words_in_a_string/reverse.c diff --git a/152_maximum_product_subarray/Makefile b/0152_maximum_product_subarray/Makefile similarity index 100% rename from 152_maximum_product_subarray/Makefile rename to 0152_maximum_product_subarray/Makefile diff --git a/152_maximum_product_subarray/subarray.c b/0152_maximum_product_subarray/subarray.c similarity index 99% rename from 152_maximum_product_subarray/subarray.c rename to 0152_maximum_product_subarray/subarray.c index cabe83d..3af1389 100644 --- a/152_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/153_find_minimum_in_rotated_sorted_array/Makefile b/0153_find_minimum_in_rotated_sorted_array/Makefile similarity index 100% rename from 153_find_minimum_in_rotated_sorted_array/Makefile rename to 0153_find_minimum_in_rotated_sorted_array/Makefile diff --git a/153_find_minimum_in_rotated_sorted_array/minimum.c b/0153_find_minimum_in_rotated_sorted_array/minimum.c similarity index 74% rename from 153_find_minimum_in_rotated_sorted_array/minimum.c rename to 0153_find_minimum_in_rotated_sorted_array/minimum.c index 1073f1f..677d426 100644 --- a/153_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/154_find_minimum_in_rotated_sorted_array_ii/Makefile b/0154_find_minimum_in_rotated_sorted_array_ii/Makefile similarity index 100% rename from 154_find_minimum_in_rotated_sorted_array_ii/Makefile rename to 0154_find_minimum_in_rotated_sorted_array_ii/Makefile diff --git a/154_find_minimum_in_rotated_sorted_array_ii/minimum.c b/0154_find_minimum_in_rotated_sorted_array_ii/minimum.c similarity index 54% rename from 154_find_minimum_in_rotated_sorted_array_ii/minimum.c rename to 0154_find_minimum_in_rotated_sorted_array_ii/minimum.c index a1ec893..6e11f26 100644 --- a/154_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/155_min_stack/Makefile b/0155_min_stack/Makefile similarity index 100% rename from 155_min_stack/Makefile rename to 0155_min_stack/Makefile diff --git a/155_min_stack/stack.c b/0155_min_stack/stack.c similarity index 100% rename from 155_min_stack/stack.c rename to 0155_min_stack/stack.c diff --git a/160_intersection_of_two_linked_list/Makefile b/0160_intersection_of_two_linked_list/Makefile similarity index 100% rename from 160_intersection_of_two_linked_list/Makefile rename to 0160_intersection_of_two_linked_list/Makefile diff --git a/160_intersection_of_two_linked_list/intersection.c b/0160_intersection_of_two_linked_list/intersection.c similarity index 68% rename from 160_intersection_of_two_linked_list/intersection.c rename to 0160_intersection_of_two_linked_list/intersection.c index d33de4f..def9953 100644 --- a/160_intersection_of_two_linked_list/intersection.c +++ b/0160_intersection_of_two_linked_list/intersection.c @@ -9,23 +9,27 @@ struct ListNode { static struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) { + if (headA == NULL || headB == NULL) { + return NULL; + } + struct ListNode *p; for (p = headA; p->next != NULL; p = p->next) {} p->next = headB; - bool first = true; - struct ListNode *p0, *p1; - for (p0 = headA, p1 = headA; p1 != NULL && p1->next != NULL; p0 = p0->next, p1 = p1->next->next) { - if (p0 == p1 && !first) { - p0 = headA; - while (p0 != p1) { - p0 = p0->next; - p1 = p1->next; + struct ListNode *slow = headA, *fast = headA; + while (fast != NULL && fast->next != NULL) { + slow = slow->next; + fast = fast->next->next; + if (slow == fast) { + slow = headA; + while (slow != fast) { + slow = slow->next; + fast = fast->next; } p->next = NULL; - return p0; + return slow; } - first = false; } p->next = NULL; diff --git a/0160_intersection_of_two_linked_list/intersection.cc b/0160_intersection_of_two_linked_list/intersection.cc new file mode 100644 index 0000000..0d4c957 --- /dev/null +++ b/0160_intersection_of_two_linked_list/intersection.cc @@ -0,0 +1,44 @@ +#include + +using namespace std; + +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode(int x) : val(x), next(NULL) {} + * }; + */ +class Solution { +public: + ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { + int lenA = getListLength(headA); + int lenB = getListLength(headB); + if (lenA > lenB) { + for (int i = 0; i < lenA - lenB; i++) { + headA = headA->next; + } + } else { + for (int i = 0; i < lenB - lenA; i++) { + headB = headB->next; + } + } + + while (headA != nullptr && headB != nullptr && headA != headB) { + headA = headA->next; + headB = headB->next; + } + + return headA; + } +private: + int getListLength(ListNode *h) { + int len = 0; + while (h != nullptr) { + len++; + h = h->next; + } + return len; + } +}; diff --git a/162_find_peak_element/Makefile b/0162_find_peak_element/Makefile similarity index 100% rename from 162_find_peak_element/Makefile rename to 0162_find_peak_element/Makefile diff --git a/162_find_peak_element/peak.c b/0162_find_peak_element/peak.c similarity index 66% rename from 162_find_peak_element/peak.c rename to 0162_find_peak_element/peak.c index bb1d2f5..c936ae5 100644 --- a/162_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/164_maximum_gap/Makefile b/0164_maximum_gap/Makefile similarity index 100% rename from 164_maximum_gap/Makefile rename to 0164_maximum_gap/Makefile diff --git a/164_maximum_gap/max_gap.c b/0164_maximum_gap/max_gap.c similarity index 100% rename from 164_maximum_gap/max_gap.c rename to 0164_maximum_gap/max_gap.c diff --git a/0164_maximum_gap/max_gap.cc b/0164_maximum_gap/max_gap.cc new file mode 100644 index 0000000..f802915 --- /dev/null +++ b/0164_maximum_gap/max_gap.cc @@ -0,0 +1,38 @@ +#include + +using namespace std; + +class Solution { +public: + int maximumGap(vector& nums) { + if (nums.size() < 2) { + return 0; + } + + int min_elem = *min_element(nums.begin(), nums.end()); + int max_elem = *max_element(nums.begin(), nums.end()); + double bucket_size = 1.0 * (max_elem - min_elem) / (nums.size() - 1); + if (bucket_size == 0) { + return 0; + } + + int bucket_cnt = (max_elem - min_elem) / bucket_size + 1; + vector min_bucket(bucket_cnt, INT_MAX); + vector max_bucket(bucket_cnt, INT_MIN); + for (int i = 0; i < nums.size(); i++) { + int id = (nums[i] - min_elem) / bucket_size; + min_bucket[id] = min(nums[i], min_bucket[id]); + max_bucket[id] = max(nums[i], max_bucket[id]); + } + + int max_gap = 0; + int last_max = max_bucket[0]; + for (int i = 1; i < bucket_cnt; i++) { + if (min_bucket[i] != INT_MAX) { + max_gap = max(min_bucket[i] - last_max, max_gap); + last_max = max_bucket[i]; + } + } + return max_gap; + } +}; diff --git a/165_compare_version_numbers/Makefile b/0165_compare_version_numbers/Makefile similarity index 100% rename from 165_compare_version_numbers/Makefile rename to 0165_compare_version_numbers/Makefile diff --git a/165_compare_version_numbers/version.c b/0165_compare_version_numbers/version.c similarity index 100% rename from 165_compare_version_numbers/version.c rename to 0165_compare_version_numbers/version.c diff --git a/166_fraction_to_recurring_decimal/Makefile b/0166_fraction_to_recurring_decimal/Makefile similarity index 100% rename from 166_fraction_to_recurring_decimal/Makefile rename to 0166_fraction_to_recurring_decimal/Makefile diff --git a/166_fraction_to_recurring_decimal/fraction.c b/0166_fraction_to_recurring_decimal/fraction.c similarity index 70% rename from 166_fraction_to_recurring_decimal/fraction.c rename to 0166_fraction_to_recurring_decimal/fraction.c index fbb1db5..f1c90ff 100644 --- a/166_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/167_two_sum_ii/Makefile b/0167_two_sum_ii/Makefile similarity index 100% rename from 167_two_sum_ii/Makefile rename to 0167_two_sum_ii/Makefile diff --git a/167_two_sum_ii/two_sum.c b/0167_two_sum_ii/two_sum.c similarity index 76% rename from 167_two_sum_ii/two_sum.c rename to 0167_two_sum_ii/two_sum.c index 38eb52d..7478668 100644 --- a/167_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]; - if (diff < numbers[j]) { - while (i < --j && numbers[j + 1] == numbers[j]) {} - } else if (diff > numbers[j]) { - while (++i < j && numbers[i - 1] == numbers[i]) {} + int sum = numbers[i] + numbers[j]; + if (sum < target) { + i++; + } 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 new file mode 100644 index 0000000..c8c1610 --- /dev/null +++ b/0167_two_sum_ii/two_sum.cc @@ -0,0 +1,25 @@ +#include + +using namespace std; + +class Solution { +public: + vector twoSum(vector& numbers, int target) { + vector res; + int i = 0; + int j = numbers.size() - 1; + while (i < j) { + int sum = numbers[i] + numbers[j]; + if (sum < target) { + i++; + } else if (sum > target) { + j--; + } else { + res.push_back(i + 1); + res.push_back(j + 1); + break; + } + } + return res; + } +}; diff --git a/168_excel_sheet_column_title/Makefile b/0168_excel_sheet_column_title/Makefile similarity index 100% rename from 168_excel_sheet_column_title/Makefile rename to 0168_excel_sheet_column_title/Makefile diff --git a/168_excel_sheet_column_title/sheet_column.c b/0168_excel_sheet_column_title/sheet_column.c similarity index 100% rename from 168_excel_sheet_column_title/sheet_column.c rename to 0168_excel_sheet_column_title/sheet_column.c diff --git a/169_majority_element/Makefile b/0169_majority_element/Makefile similarity index 100% rename from 169_majority_element/Makefile rename to 0169_majority_element/Makefile diff --git a/169_majority_element/majority.c b/0169_majority_element/majority.c similarity index 100% rename from 169_majority_element/majority.c rename to 0169_majority_element/majority.c diff --git a/0169_majority_element/majority.cc b/0169_majority_element/majority.cc new file mode 100644 index 0000000..88b333a --- /dev/null +++ b/0169_majority_element/majority.cc @@ -0,0 +1,21 @@ +#include + +using namespace std; + +class Solution { +public: + int majorityElement(vector& nums) { + int major, count = 0; + for (int i = 0; i < nums.size(); i++) { + if (count == 0) { + major = nums[i]; + count++; + } else if (nums[i] != major) { + count--; + } else { + count++; + } + } + return major; + } +}; diff --git a/171_excel_sheet_column_number/Makefile b/0171_excel_sheet_column_number/Makefile similarity index 100% rename from 171_excel_sheet_column_number/Makefile rename to 0171_excel_sheet_column_number/Makefile diff --git a/171_excel_sheet_column_number/sheet_column.c b/0171_excel_sheet_column_number/sheet_column.c similarity index 100% rename from 171_excel_sheet_column_number/sheet_column.c rename to 0171_excel_sheet_column_number/sheet_column.c diff --git a/172_factorial_trailing_zeros/Makefile b/0172_factorial_trailing_zeros/Makefile similarity index 100% rename from 172_factorial_trailing_zeros/Makefile rename to 0172_factorial_trailing_zeros/Makefile diff --git a/172_factorial_trailing_zeros/zeroes.c b/0172_factorial_trailing_zeros/zeroes.c similarity index 100% rename from 172_factorial_trailing_zeros/zeroes.c rename to 0172_factorial_trailing_zeros/zeroes.c diff --git a/0172_factorial_trailing_zeros/zeroes.cc b/0172_factorial_trailing_zeros/zeroes.cc new file mode 100644 index 0000000..94599e6 --- /dev/null +++ b/0172_factorial_trailing_zeros/zeroes.cc @@ -0,0 +1,10 @@ +#include + +using namespace std; + +class Solution { +public: + int trailingZeroes(int n) { + return n == 0 ? 0 : n / 5 + trailingZeroes(n / 5); + } +}; diff --git a/173_binary_search_tree_iterator/Makefile b/0173_binary_search_tree_iterator/Makefile similarity index 100% rename from 173_binary_search_tree_iterator/Makefile rename to 0173_binary_search_tree_iterator/Makefile diff --git a/173_binary_search_tree_iterator/bst_iter.c b/0173_binary_search_tree_iterator/bst_iter.c similarity index 100% rename from 173_binary_search_tree_iterator/bst_iter.c rename to 0173_binary_search_tree_iterator/bst_iter.c diff --git a/174_dungeon_game/Makefile b/0174_dungeon_game/Makefile similarity index 100% rename from 174_dungeon_game/Makefile rename to 0174_dungeon_game/Makefile diff --git a/174_dungeon_game/dungeon.c b/0174_dungeon_game/dungeon.c similarity index 100% rename from 174_dungeon_game/dungeon.c rename to 0174_dungeon_game/dungeon.c diff --git a/179_largest_number/Makefile b/0179_largest_number/Makefile similarity index 100% rename from 179_largest_number/Makefile rename to 0179_largest_number/Makefile diff --git a/179_largest_number/largest_number.c b/0179_largest_number/largest_number.c similarity index 94% rename from 179_largest_number/largest_number.c rename to 0179_largest_number/largest_number.c index 6eb31f3..3dba0a8 100644 --- a/179_largest_number/largest_number.c +++ b/0179_largest_number/largest_number.c @@ -8,10 +8,8 @@ struct object { static int compare(const void *o1, const void *o2) { - char p1[32]; - char p2[32]; - p1[0] = '\0'; - p2[0] = '\0'; + char p1[32] = { '\0' }; + char p2[32] = { '\0' }; strcat(p1, ((struct object *) o1)->buf); strcat(p1, ((struct object *) o2)->buf); strcat(p2, ((struct object *) o2)->buf); diff --git a/0179_largest_number/largest_number.cc b/0179_largest_number/largest_number.cc new file mode 100644 index 0000000..7b8a5aa --- /dev/null +++ b/0179_largest_number/largest_number.cc @@ -0,0 +1,26 @@ +#include + +using namespace std; + +class Solution { +public: + string largestNumber(vector& nums) { + vector strs; + for (const auto i : nums) { + strs.push_back(to_string(i)); + } + + auto cmp = [](string s1, string s2) { return s1 + s2 > s2 + s1; }; + sort(strs.begin(), strs.end(), cmp); + + if (strs[0] == "0") { + return "0"; + } + + string res; + for (const auto& s : strs) { + res += s; + } + return res; + } +}; diff --git a/188_best_time_to_buy_and_sell_stock_iv/Makefile b/0188_best_time_to_buy_and_sell_stock_iv/Makefile similarity index 100% rename from 188_best_time_to_buy_and_sell_stock_iv/Makefile rename to 0188_best_time_to_buy_and_sell_stock_iv/Makefile diff --git a/188_best_time_to_buy_and_sell_stock_iv/stock.c b/0188_best_time_to_buy_and_sell_stock_iv/stock.c similarity index 100% rename from 188_best_time_to_buy_and_sell_stock_iv/stock.c rename to 0188_best_time_to_buy_and_sell_stock_iv/stock.c diff --git a/189_rotate_array/Makefile b/0189_rotate_array/Makefile similarity index 100% rename from 189_rotate_array/Makefile rename to 0189_rotate_array/Makefile diff --git a/189_rotate_array/rotate_array.c b/0189_rotate_array/rotate_array.c similarity index 100% rename from 189_rotate_array/rotate_array.c rename to 0189_rotate_array/rotate_array.c diff --git a/0189_rotate_array/rotate_array.cc b/0189_rotate_array/rotate_array.cc new file mode 100644 index 0000000..8fc0d3c --- /dev/null +++ b/0189_rotate_array/rotate_array.cc @@ -0,0 +1,13 @@ +#include + +using namespace std; + +class Solution { +public: + void rotate(vector& nums, int k) { + k %= nums.size(); + reverse(nums.begin(), nums.end() - k); + reverse(nums.end() - k, nums.end()); + reverse(nums.begin(), nums.end()); + } +}; diff --git a/190_reverse_bits/Makefile b/0190_reverse_bits/Makefile similarity index 100% rename from 190_reverse_bits/Makefile rename to 0190_reverse_bits/Makefile diff --git a/0190_reverse_bits/reverse_bits.c b/0190_reverse_bits/reverse_bits.c new file mode 100644 index 0000000..8ba7cff --- /dev/null +++ b/0190_reverse_bits/reverse_bits.c @@ -0,0 +1,29 @@ +#include +#include +#include + +static uint32_t reverseBits(uint32_t n) +{ + 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) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test n\n"); + exit(-1); + } + + printf("%u\n", reverseBits(atoi(argv[1]))); + return 0; +} diff --git a/191_number_of_one_bits/Makefile b/0191_number_of_one_bits/Makefile similarity index 100% rename from 191_number_of_one_bits/Makefile rename to 0191_number_of_one_bits/Makefile diff --git a/191_number_of_one_bits/hamming_weight.c b/0191_number_of_one_bits/hamming_weight.c similarity index 100% rename from 191_number_of_one_bits/hamming_weight.c rename to 0191_number_of_one_bits/hamming_weight.c diff --git a/198_house_robber/Makefile b/0198_house_robber/Makefile similarity index 100% rename from 198_house_robber/Makefile rename to 0198_house_robber/Makefile diff --git a/198_house_robber/robber.c b/0198_house_robber/robber.c similarity index 69% rename from 198_house_robber/robber.c rename to 0198_house_robber/robber.c index 35d7f22..82fa8ad 100644 --- a/198_house_robber/robber.c +++ b/0198_house_robber/robber.c @@ -9,19 +9,17 @@ static inline int max(int a, int b) static int rob(int* nums, int numsSize) { - if (numsSize == 0) { - return 0; - } - int i; - int taken = nums[0]; + int taken = 0; int untaken = 0; /* Record max profits of nums[0...i] respectively */ - for (i = 1; i < numsSize; i++) { - int tmp_taken = taken; - int tmp_untaken = untaken; + for (i = 0; i < numsSize; i++) { + int last_taken = taken; + /* Taken or untaken nums[i] */ + /* last taken + nums[i] */ taken = untaken + nums[i]; - untaken = max(tmp_taken, tmp_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 new file mode 100644 index 0000000..010c571 --- /dev/null +++ b/0198_house_robber/robber.cc @@ -0,0 +1,19 @@ +#include + +using namespace std; + +class Solution { +public: + int rob(vector& nums) { + int taken = 0; + int untaken = 0; + for (int i = 0; i < nums.size(); i++) { + int last_taken = taken; + /* last untaken + nums[i]*/ + taken = untaken + nums[i]; + /* max(last untaken, last taken) */ + untaken = max(untaken, last_taken); + } + return max(taken, untaken); + } +}; diff --git a/199_binary_tree_right_side_view/Makefile b/0199_binary_tree_right_side_view/Makefile similarity index 100% rename from 199_binary_tree_right_side_view/Makefile rename to 0199_binary_tree_right_side_view/Makefile diff --git a/199_binary_tree_right_side_view/bst_right.c b/0199_binary_tree_right_side_view/bst_right.c similarity index 56% rename from 199_binary_tree_right_side_view/bst_right.c rename to 0199_binary_tree_right_side_view/bst_right.c index 4993d08..2be03cd 100644 --- a/199_binary_tree_right_side_view/bst_right.c +++ b/0199_binary_tree_right_side_view/bst_right.c @@ -2,6 +2,7 @@ #include #include + #define BST_MAX_LEVEL 800 #define container_of(ptr, type, member) \ @@ -13,12 +14,6 @@ #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)->prev; p != (head); p = p->prev) - -#define list_for_each_safe(p, n, head) \ - for (p = (head)->prev, n = p->prev; p != (head); p = n, n = p->prev) - struct TreeNode { int val; struct TreeNode *left; @@ -29,6 +24,11 @@ struct list_head { struct list_head *next, *prev; }; +struct queue_node { + struct TreeNode *node; + struct list_head link; +}; + static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list->prev = list; @@ -69,58 +69,28 @@ static inline void list_del(struct list_head *entry) entry->next = entry->prev = NULL; } -struct bfs_node { - struct TreeNode *node; - struct list_head link; -}; - -static struct bfs_node *node_new(struct list_head *free_list, struct TreeNode *node) +static struct queue_node *node_new(struct TreeNode *node, struct list_head *free_list) { /* Reusage in free node pool */ - struct bfs_node *new; + struct queue_node *qn; if (list_empty(free_list)) { - new = malloc(sizeof(*new)); + qn = malloc(sizeof(*qn)); } else { - new = list_first_entry(free_list, struct bfs_node, link); - list_del(&new->link); + qn = list_first_entry(free_list, struct queue_node, link); + list_del(&qn->link); } - new->node = node; - return new; + qn->node = node; + return qn; } -static void bfs(struct list_head *parents, struct list_head *children, - struct list_head *free_list, int *results, int *count) +static void node_free(struct queue_node *qn, struct list_head *free_list) { - struct list_head *p, *n; - list_for_each(p, parents) { - struct bfs_node *new; - struct bfs_node *parent = list_entry(p, struct bfs_node, link); - if (parent->node->right != NULL) { - new = node_new(free_list, parent->node->right); - list_add(&new->link, children); - } - if (parent->node->left != NULL) { - new = node_new(free_list, parent->node->left); - list_add(&new->link, children); - } - } - - int first = 1; - list_for_each_safe(p, n, parents) { - struct bfs_node *parent = list_entry(p, struct bfs_node, link); - if (first) { - first = 0; - results[(*count)++] = parent->node->val; - } - list_del(p); - list_add(p, free_list); - } + list_del(&qn->link); + list_add(&qn->link, free_list); } /** - ** Return an array of arrays of size *returnSize. - ** The sizes of the arrays are returned as *columnSizes array. - ** Note: Both returned array and *columnSizes 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) { @@ -129,29 +99,41 @@ static int* rightSideView(struct TreeNode* root, int* returnSize) return NULL; } - struct list_head q0; - struct list_head q1; + struct list_head q; struct list_head free_list; - INIT_LIST_HEAD(&q0); - INIT_LIST_HEAD(&q1); + INIT_LIST_HEAD(&q); INIT_LIST_HEAD(&free_list); - int level = 0; + int i, level = 0, level_size = 1; *returnSize = 0; int *results = malloc(BST_MAX_LEVEL * sizeof(int)); - struct bfs_node *new = node_new(&free_list, root); - list_add_tail(&new->link, &q0); - - /* Interleaving parent and children FIFO queues */ - while (!list_empty(&q0) || !list_empty(&q1)) { - if (level & 0x1) { - bfs(&q1, &q0, &free_list, results, returnSize); - } else { - bfs(&q0, &q1, &free_list, results, returnSize); + + /* Add root node */ + struct queue_node *new = node_new(root, &free_list); + list_add_tail(&new->link, &q); + + while (!list_empty(&q)) { + int size = level_size; + level_size = 0; + for (i = 0; i < size; i++) { + struct queue_node *qn = list_first_entry(&q, struct queue_node, link); + results[level] = qn->node->val; + if (qn->node->left != NULL) { + new = node_new(qn->node->left, &free_list); + list_add_tail(&new->link, &q); + level_size++; + } + if (qn->node->right != NULL) { + new = node_new(qn->node->right, &free_list); + list_add_tail(&new->link, &q); + level_size++; + } + node_free(qn, &free_list); } level++; } + *returnSize = level; return results; } diff --git a/0199_binary_tree_right_side_view/bst_right.cc b/0199_binary_tree_right_side_view/bst_right.cc new file mode 100644 index 0000000..20490cb --- /dev/null +++ b/0199_binary_tree_right_side_view/bst_right.cc @@ -0,0 +1,44 @@ +#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 rightSideView(TreeNode* root) { + vector res; + if (root == nullptr) { + return res; + } + + queue q; + q.push(root); + while (!q.empty()) { + int rightest; + int size = q.size(); + for (int i = 0; i < size; i++) { + TreeNode *node = q.front(); + q.pop(); + rightest = node->val; + if (node->left != nullptr) { + q.push(node->left); + } + if (node->right != nullptr) { + q.push(node->right); + } + } + res.push_back(rightest); + } + return res; + } +}; diff --git a/200_number_of_islands/Makefile b/0200_number_of_islands/Makefile similarity index 100% rename from 200_number_of_islands/Makefile rename to 0200_number_of_islands/Makefile diff --git a/200_number_of_islands/islands.c b/0200_number_of_islands/islands.c similarity index 100% rename from 200_number_of_islands/islands.c rename to 0200_number_of_islands/islands.c diff --git a/201_bitwise_and_of_numbers_range/Makefile b/0201_bitwise_and_of_numbers_range/Makefile similarity index 100% rename from 201_bitwise_and_of_numbers_range/Makefile rename to 0201_bitwise_and_of_numbers_range/Makefile diff --git a/201_bitwise_and_of_numbers_range/and.c b/0201_bitwise_and_of_numbers_range/and.c similarity index 100% rename from 201_bitwise_and_of_numbers_range/and.c rename to 0201_bitwise_and_of_numbers_range/and.c diff --git a/202_happy_number/Makefile b/0202_happy_number/Makefile similarity index 100% rename from 202_happy_number/Makefile rename to 0202_happy_number/Makefile diff --git a/202_happy_number/happy_number.c b/0202_happy_number/happy_number.c similarity index 100% rename from 202_happy_number/happy_number.c rename to 0202_happy_number/happy_number.c diff --git a/203_remove_linked_list_element/Makefile b/0203_remove_linked_list_element/Makefile similarity index 100% rename from 203_remove_linked_list_element/Makefile rename to 0203_remove_linked_list_element/Makefile diff --git a/203_remove_linked_list_element/rm_elem.c b/0203_remove_linked_list_element/rm_elem.c similarity index 100% rename from 203_remove_linked_list_element/rm_elem.c rename to 0203_remove_linked_list_element/rm_elem.c diff --git a/204_count_primes/Makefile b/0204_count_primes/Makefile similarity index 100% rename from 204_count_primes/Makefile rename to 0204_count_primes/Makefile diff --git a/204_count_primes/count_primes.c b/0204_count_primes/count_primes.c similarity index 88% rename from 204_count_primes/count_primes.c rename to 0204_count_primes/count_primes.c index f64c6e6..69b4bef 100644 --- a/204_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/205_isomorphic_strings/Makefile b/0205_isomorphic_strings/Makefile similarity index 100% rename from 205_isomorphic_strings/Makefile rename to 0205_isomorphic_strings/Makefile diff --git a/205_isomorphic_strings/isomorphic_strings.c b/0205_isomorphic_strings/isomorphic_strings.c similarity index 100% rename from 205_isomorphic_strings/isomorphic_strings.c rename to 0205_isomorphic_strings/isomorphic_strings.c 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/206_reverse_linked_list/Makefile b/0206_reverse_linked_list/Makefile similarity index 100% rename from 206_reverse_linked_list/Makefile rename to 0206_reverse_linked_list/Makefile diff --git a/206_reverse_linked_list/reverse_list.c b/0206_reverse_linked_list/reverse_list.c similarity index 87% rename from 206_reverse_linked_list/reverse_list.c rename to 0206_reverse_linked_list/reverse_list.c index c45ccc5..22c65bd 100644 --- a/206_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/207_course_schedule/Makefile b/0207_course_schedule/Makefile similarity index 100% rename from 207_course_schedule/Makefile rename to 0207_course_schedule/Makefile diff --git a/207_course_schedule/course_schedule.c b/0207_course_schedule/course_schedule.c similarity index 63% rename from 207_course_schedule/course_schedule.c rename to 0207_course_schedule/course_schedule.c index 7a7c325..cfd1727 100644 --- a/207_course_schedule/course_schedule.c +++ b/0207_course_schedule/course_schedule.c @@ -3,51 +3,49 @@ #include #include + struct graph_node { int req_num; int reqs[15]; + bool touched; + bool taken; }; -static bool dfs(struct graph_node *courses, int id, bool *takens, bool *touched) +static bool dfs(struct graph_node *courses, int id) { int i; - if (touched[id]) { + if (courses[id].touched) { return true; - } else if (takens[id]) { + } else if (courses[id].taken) { return false; } else { - takens[id] = true; + courses[id].taken = true; for (i = 0; i < courses[id].req_num; i++) { - if (!dfs(courses, courses[id].reqs[i], takens, touched)) { + if (!dfs(courses, courses[id].reqs[i])) { return false; } } - /* marked as available and no need to traverse next time */ - touched[id] = true; - takens[id] = false; + /* If paths overlapped, mark in backtracing for no need to traverse next time */ + courses[id].touched = true; + courses[id].taken = false; return true; } } -static bool canFinish(int numCourses, int** prerequisites, int prerequisitesRowSize, int prerequisitesColSize) +static bool canFinish(int numCourses, int** prerequisites, int prerequisitesSize, int *prerequisitesColSize) { int i; - bool *takens = malloc(numCourses); - bool *touched = malloc(numCourses); struct graph_node *courses = malloc(numCourses * sizeof(*courses)); memset(courses, 0, numCourses * sizeof(*courses)); - memset(takens, false, numCourses * sizeof(bool)); - memset(touched, false, numCourses * sizeof(bool)); - - for (i = 0; i < prerequisitesRowSize; i++) { + for (i = 0; i < prerequisitesSize; i++) { int id = prerequisites[i][0]; int req = prerequisites[i][1]; courses[id].reqs[courses[id].req_num++] = req; } for (i = 0; i < numCourses; i++) { - if (!dfs(courses, i, takens, touched)) { + if (!dfs(courses, i)) { return false; } } @@ -59,24 +57,31 @@ int main(void) { int i, course_num = 6, pair_num = 6; int **pairs = malloc(pair_num * sizeof(int *)); + int *col_sizes = malloc(pair_num * sizeof(int)); pairs[0] = malloc(2 * sizeof(int)); pairs[0][0] = 1; pairs[0][1] = 0; + col_sizes[0] = 2; pairs[1] = malloc(2 * sizeof(int)); pairs[1][0] = 2; pairs[1][1] = 1; + col_sizes[1] = 2; pairs[2] = malloc(2 * sizeof(int)); pairs[2][0] = 3; pairs[2][1] = 2; + col_sizes[2] = 2; pairs[3] = malloc(2 * sizeof(int)); pairs[3][0] = 1; pairs[3][1] = 3; + col_sizes[3] = 2; pairs[4] = malloc(2 * sizeof(int)); pairs[4][0] = 4; pairs[4][1] = 0; + col_sizes[4] = 2; pairs[5] = malloc(2 * sizeof(int)); pairs[5][0] = 0; pairs[5][1] = 5; - printf("%s\n", canFinish(course_num, pairs, pair_num, 2) ? "true" : "false"); + col_sizes[5] = 2; + printf("%s\n", canFinish(course_num, pairs, pair_num, col_sizes) ? "true" : "false"); return 0; } 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/208_implement_trie/Makefile b/0208_implement_trie/Makefile similarity index 100% rename from 208_implement_trie/Makefile rename to 0208_implement_trie/Makefile diff --git a/208_implement_trie/trie.c b/0208_implement_trie/trie.c similarity index 100% rename from 208_implement_trie/trie.c rename to 0208_implement_trie/trie.c diff --git a/209_minimum_size_subarray_sum/Makefile b/0209_minimum_size_subarray_sum/Makefile similarity index 100% rename from 209_minimum_size_subarray_sum/Makefile rename to 0209_minimum_size_subarray_sum/Makefile diff --git a/209_minimum_size_subarray_sum/mini_size.c b/0209_minimum_size_subarray_sum/mini_size.c similarity index 100% rename from 209_minimum_size_subarray_sum/mini_size.c rename to 0209_minimum_size_subarray_sum/mini_size.c diff --git a/210_course_schedule_ii/Makefile b/0210_course_schedule_ii/Makefile similarity index 100% rename from 210_course_schedule_ii/Makefile rename to 0210_course_schedule_ii/Makefile diff --git a/210_course_schedule_ii/course_schedule.c b/0210_course_schedule_ii/course_schedule.c similarity index 67% rename from 210_course_schedule_ii/course_schedule.c rename to 0210_course_schedule_ii/course_schedule.c index 5ecd140..d2d33b4 100644 --- a/210_course_schedule_ii/course_schedule.c +++ b/0210_course_schedule_ii/course_schedule.c @@ -3,29 +3,33 @@ #include #include + struct graph_node { int req_num; int reqs[15]; + bool touched; + bool taken; }; -static bool dfs(struct graph_node *courses, int id, bool *takens, bool *touched, int *order, int *count) +static bool dfs(struct graph_node *courses, int id, int *order, int *count) { int i; - if (touched[id]) { + if (courses[id].touched) { return true; - } else if (takens[id]) { + } else if (courses[id].taken) { return false; } else { - takens[id] = true; + courses[id].taken = true; for (i = 0; i < courses[id].req_num; i++) { - if (!dfs(courses, courses[id].reqs[i], takens, touched, order, count)) { + if (!dfs(courses, courses[id].reqs[i], order, count)) { return false; } } - /* marked as available and no need to traverse next time */ + /* Record path in backtrace before DFS return */ order[(*count)++] = id; - touched[id] = true; - takens[id] = false; + /* If paths overlapped, mark in backtracing for no need to traverse next time */ + courses[id].touched = true; + courses[id].taken = false; return true; } } @@ -34,19 +38,14 @@ static bool dfs(struct graph_node *courses, int id, bool *takens, bool *touched, * Return an array of size *returnSize. * Note: The returned array must be malloced, assume caller calls free(). */ -static int *findOrder(int numCourses, int** prerequisites, int prerequisitesRowSize, int prerequisitesColSize, int *returnSize) +static int *findOrder(int numCourses, int** prerequisites, int prerequisitesSize, int *prerequisitesColSize, int *returnSize) { int i; int *order = malloc(numCourses * sizeof(int)); - bool *takens = malloc(numCourses); - bool *touched = malloc(numCourses); struct graph_node *courses = malloc(numCourses * sizeof(*courses)); memset(courses, 0, numCourses * sizeof(*courses)); - memset(takens, false, numCourses * sizeof(bool)); - memset(touched, false, numCourses * sizeof(bool)); - - for (i = 0; i < prerequisitesRowSize; i++) { + for (i = 0; i < prerequisitesSize; i++) { int id = prerequisites[i][0]; int req = prerequisites[i][1]; courses[id].reqs[courses[id].req_num++] = req; @@ -54,7 +53,7 @@ static int *findOrder(int numCourses, int** prerequisites, int prerequisitesRowS *returnSize = 0; for (i = 0; i < numCourses; i++) { - if (!dfs(courses, i, takens, touched, order, returnSize)) { + if (!dfs(courses, i, order, returnSize)) { *returnSize = 0; return order; } @@ -67,6 +66,7 @@ int main(void) { int i, course_num = 3, pair_num = 1; int **pairs = malloc(pair_num * sizeof(int *)); + int *col_sizes = malloc(pair_num * sizeof(int)); pairs[0] = malloc(2 * sizeof(int)); pairs[0][0] = 1; pairs[0][1] = 0; @@ -84,7 +84,7 @@ int main(void) //pairs[4][1] = 5; int count = 0; - int *ids = findOrder(course_num, pairs, pair_num, 2, &count); + int *ids = findOrder(course_num, pairs, pair_num, col_sizes, &count); for (i = 0; i < count; i++) { printf("%d ", ids[i]); } diff --git a/211_add_and_search_word/Makefile b/0211_add_and_search_word/Makefile similarity index 100% rename from 211_add_and_search_word/Makefile rename to 0211_add_and_search_word/Makefile diff --git a/211_add_and_search_word/word_dict.c b/0211_add_and_search_word/word_dict.c similarity index 100% rename from 211_add_and_search_word/word_dict.c rename to 0211_add_and_search_word/word_dict.c diff --git a/212_word_search_ii/Makefile b/0212_word_search_ii/Makefile similarity index 100% rename from 212_word_search_ii/Makefile rename to 0212_word_search_ii/Makefile diff --git a/212_word_search_ii/word_search.c b/0212_word_search_ii/word_search.c similarity index 100% rename from 212_word_search_ii/word_search.c rename to 0212_word_search_ii/word_search.c diff --git a/213_house_robber_ii/Makefile b/0213_house_robber_ii/Makefile similarity index 100% rename from 213_house_robber_ii/Makefile rename to 0213_house_robber_ii/Makefile diff --git a/213_house_robber_ii/robber.c b/0213_house_robber_ii/robber.c similarity index 75% rename from 213_house_robber_ii/robber.c rename to 0213_house_robber_ii/robber.c index 21ae639..ed54519 100644 --- a/213_house_robber_ii/robber.c +++ b/0213_house_robber_ii/robber.c @@ -10,14 +10,14 @@ static inline int max(int a, int b) static int _rob(int* nums, int numsSize) { int i; - int taken = nums[0]; + int taken = 0; int untaken = 0; /* Record max profits of nums[0...i] respectively */ - for (i = 1; i < numsSize; i++) { + for (i = 0; i < numsSize; i++) { int tmp_taken = taken; - int tmp_untaken = untaken; - taken = tmp_untaken + nums[i]; - untaken = max(tmp_taken, tmp_untaken); + /* Taken or untaken nums[i] */ + taken = untaken + nums[i]; + untaken = max(tmp_taken, untaken); } return max(taken, untaken); @@ -25,9 +25,7 @@ static int _rob(int* nums, int numsSize) static int rob(int* nums, int numsSize) { - if (numsSize == 0) { - return 0; - } else if (numsSize == 1) { + if (numsSize == 1) { return nums[0]; } else { /* The first and the last element are adjacent */ diff --git a/0213_house_robber_ii/robber.cc b/0213_house_robber_ii/robber.cc new file mode 100644 index 0000000..0ace8ab --- /dev/null +++ b/0213_house_robber_ii/robber.cc @@ -0,0 +1,27 @@ +#include + +using namespace std; + +class Solution { +public: + int rob(vector& nums) { + if (nums.size() == 1) { + return nums[0]; + } else { + return max(rob_(nums.begin() + 1, nums.end()), rob_(nums.begin(), nums.end() - 1)); + } + } + +private: + int rob_(vector::iterator begin, vector::iterator end) { + int taken = 0; + int untaken = 0; + vector::iterator i; + for (i = begin; i != end; i++) { + int tmp_taken = taken; + taken = untaken + *i; + untaken = max(untaken, tmp_taken); + } + return max(taken, untaken); + } +}; diff --git a/214_shortest_palindrome/Makefile b/0214_shortest_palindrome/Makefile similarity index 100% rename from 214_shortest_palindrome/Makefile rename to 0214_shortest_palindrome/Makefile diff --git a/214_shortest_palindrome/shortest_palindrome.c b/0214_shortest_palindrome/shortest_palindrome.c similarity index 100% rename from 214_shortest_palindrome/shortest_palindrome.c rename to 0214_shortest_palindrome/shortest_palindrome.c diff --git a/215_kth_largest_element_in_an_array/Makefile b/0215_kth_largest_element_in_an_array/Makefile similarity index 100% rename from 215_kth_largest_element_in_an_array/Makefile rename to 0215_kth_largest_element_in_an_array/Makefile diff --git a/0215_kth_largest_element_in_an_array/kth_elem.c b/0215_kth_largest_element_in_an_array/kth_elem.c new file mode 100644 index 0000000..dd049b5 --- /dev/null +++ b/0215_kth_largest_element_in_an_array/kth_elem.c @@ -0,0 +1,122 @@ +#include +#include + + +static void show(int *nums, int lo, int hi) +{ + int i; + for (i = lo; i <= hi; i++) { + printf("%d ", nums[i]); + } + printf("\n"); +} + +static inline void swap(int *a, int *b) +{ + int t = *a; + *a = *b; + *b = t; +} + +static void 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; + } + + int i = lo - 1; + int j = hi; + int pivot = nums[hi]; + + while (i < j) { + /* For case of large amounts of consecutive duplicate elements, we + * shall make the partition in the middle of the array as far as + * possible. If the partition is located in the head or tail, the + * performance might well be very bad for it. + * + * Note: Do NOT use nums[++i] <= pivot or nums[--j] >= pivot as the + * loop condition because it leads to redundant operations in each + * recusive iteration when there are many duplicate elements. + */ + while (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) +{ +#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[0]; +#endif +} + + +int main(int argc, char **argv) +{ + if (argc < 3) { + fprintf(stderr, "Usage: ./test k n1 n2...\n"); + exit(-1); + } + + int i, count = argc - 2; + int *nums = malloc(count * sizeof(int)); + for (i = 0; i < count; i++) { + nums[i] = atoi(argv[i + 2]); + } + printf("%d\n", findKthLargest(nums, count, atoi(argv[1]))); + return 0; +} diff --git a/0215_kth_largest_element_in_an_array/kth_elem.cc b/0215_kth_largest_element_in_an_array/kth_elem.cc new file mode 100644 index 0000000..135114e --- /dev/null +++ b/0215_kth_largest_element_in_an_array/kth_elem.cc @@ -0,0 +1,19 @@ +#include + +using namespace std; + +class Solution { +public: + int findKthLargest(vector& nums, int k) { + priority_queue, greater> queue; + for (const auto i : nums) { + if (queue.size() < k) { + queue.push(i); + } else if (i > queue.top()) { + queue.pop(); + queue.push(i); + } + } + return queue.top(); + } +}; diff --git a/216_combination_sum_iii/Makefile b/0216_combination_sum_iii/Makefile similarity index 100% rename from 216_combination_sum_iii/Makefile rename to 0216_combination_sum_iii/Makefile diff --git a/216_combination_sum_iii/combination_sum.c b/0216_combination_sum_iii/combination_sum.c similarity index 100% rename from 216_combination_sum_iii/combination_sum.c rename to 0216_combination_sum_iii/combination_sum.c 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/221_maximal_square/Makefile b/0221_maximal_square/Makefile similarity index 100% rename from 221_maximal_square/Makefile rename to 0221_maximal_square/Makefile diff --git a/221_maximal_square/maximal_square.c b/0221_maximal_square/maximal_square.c similarity index 100% rename from 221_maximal_square/maximal_square.c rename to 0221_maximal_square/maximal_square.c diff --git a/224_basic_calculator/Makefile b/0224_basic_calculator/Makefile similarity index 100% rename from 224_basic_calculator/Makefile rename to 0224_basic_calculator/Makefile diff --git a/0224_basic_calculator/calculator.c b/0224_basic_calculator/calculator.c new file mode 100644 index 0000000..5c39e16 --- /dev/null +++ b/0224_basic_calculator/calculator.c @@ -0,0 +1,73 @@ +#include +#include +#include + + +static int dfs(char **input) +{ + int i, res = 0; + int num = 0; + int stk[700], pos = 0; + char sign = '+'; + char *s = *input; + + while (*s != '\0') { + 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 (!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; + } + /* update the sign and reset the number */ + sign = c; + num = 0; + } + + /* return from the dfs */ + if (c == ')') + break; + } + + /* update position */ + *input = s; + + while (pos > 0) { + res += stk[--pos]; + } + + return res; +} + +static int calculator(char *s) +{ + return dfs(&s); +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test string\n"); + exit(-1); + } + printf("%d\n", calculator(argv[1])); + return 0; +} diff --git a/226_invert_binary_tree/Makefile b/0226_invert_binary_tree/Makefile similarity index 100% rename from 226_invert_binary_tree/Makefile rename to 0226_invert_binary_tree/Makefile diff --git a/226_invert_binary_tree/invert_binary_tree.c b/0226_invert_binary_tree/invert_binary_tree.c similarity index 85% rename from 226_invert_binary_tree/invert_binary_tree.c rename to 0226_invert_binary_tree/invert_binary_tree.c index 36b0cad..7efae0d 100644 --- a/226_invert_binary_tree/invert_binary_tree.c +++ b/0226_invert_binary_tree/invert_binary_tree.c @@ -10,13 +10,14 @@ struct TreeNode { static struct TreeNode *invertTree(struct TreeNode* root) { - if (root != NULL) { - struct TreeNode *node = root->left; - root->left = root->right; - root->right = node; - invertTree(root->left); - invertTree(root->right); + if (root == NULL) { + return NULL; } + + struct TreeNode *l = invertTree(root->left); + struct TreeNode *r = invertTree(root->right); + root->left = r; + root->right = l; return root; } diff --git a/0226_invert_binary_tree/invert_binary_tree.cc b/0226_invert_binary_tree/invert_binary_tree.cc new file mode 100644 index 0000000..cc9bdb7 --- /dev/null +++ b/0226_invert_binary_tree/invert_binary_tree.cc @@ -0,0 +1,29 @@ +#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: + TreeNode* invertTree(TreeNode* root) { + if (root == nullptr) { + return nullptr; + } + + TreeNode* l = invertTree(root->left); + TreeNode* r = invertTree(root->right); + root->left = r; + root->right = l; + return root; + } +}; diff --git a/227_basic_calculator_ii/Makefile b/0227_basic_calculator_ii/Makefile similarity index 100% rename from 227_basic_calculator_ii/Makefile rename to 0227_basic_calculator_ii/Makefile diff --git a/227_basic_calculator_ii/calculator.c b/0227_basic_calculator_ii/calculator.c similarity index 100% rename from 227_basic_calculator_ii/calculator.c rename to 0227_basic_calculator_ii/calculator.c diff --git a/229_majority_element_ii/Makefile b/0229_majority_element_ii/Makefile similarity index 100% rename from 229_majority_element_ii/Makefile rename to 0229_majority_element_ii/Makefile diff --git a/229_majority_element_ii/majority.c b/0229_majority_element_ii/majority.c similarity index 100% rename from 229_majority_element_ii/majority.c rename to 0229_majority_element_ii/majority.c diff --git a/230_kth_smallest_element_in_a_bst/Makefile b/0230_kth_smallest_element_in_a_bst/Makefile similarity index 100% rename from 230_kth_smallest_element_in_a_bst/Makefile rename to 0230_kth_smallest_element_in_a_bst/Makefile diff --git a/230_kth_smallest_element_in_a_bst/kth_bst.c b/0230_kth_smallest_element_in_a_bst/kth_bst.c similarity index 100% rename from 230_kth_smallest_element_in_a_bst/kth_bst.c rename to 0230_kth_smallest_element_in_a_bst/kth_bst.c diff --git a/0230_kth_smallest_element_in_a_bst/kth_bst.cc b/0230_kth_smallest_element_in_a_bst/kth_bst.cc new file mode 100644 index 0000000..854808a --- /dev/null +++ b/0230_kth_smallest_element_in_a_bst/kth_bst.cc @@ -0,0 +1,38 @@ +#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 kthSmallest(TreeNode* root, int k) { + stack stk; + while (!stk.empty() || root != nullptr) { + if (root != nullptr) { + /* Store the parent node */ + stk.push(root); + root = root->left; + } else { + /* Pop up the parent node */ + root = stk.top(); + if (--k == 0) { + break; + } + stk.pop(); + root = root->right; + } + } + + return root->val; + } +}; diff --git a/235_lowest_common_ancestor_of_a_binary_search_tree/Makefile b/0235_lowest_common_ancestor_of_a_binary_search_tree/Makefile similarity index 100% rename from 235_lowest_common_ancestor_of_a_binary_search_tree/Makefile rename to 0235_lowest_common_ancestor_of_a_binary_search_tree/Makefile diff --git a/235_lowest_common_ancestor_of_a_binary_search_tree/bst_lca.c b/0235_lowest_common_ancestor_of_a_binary_search_tree/bst_lca.c similarity index 92% rename from 235_lowest_common_ancestor_of_a_binary_search_tree/bst_lca.c rename to 0235_lowest_common_ancestor_of_a_binary_search_tree/bst_lca.c index 502863a..aecdf1c 100644 --- a/235_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/236_lowest_common_ancestor_of_a_binary_tree/Makefile b/0236_lowest_common_ancestor_of_a_binary_tree/Makefile similarity index 100% rename from 236_lowest_common_ancestor_of_a_binary_tree/Makefile rename to 0236_lowest_common_ancestor_of_a_binary_tree/Makefile diff --git a/236_lowest_common_ancestor_of_a_binary_tree/bst_lca.c b/0236_lowest_common_ancestor_of_a_binary_tree/bst_lca.c similarity index 77% rename from 236_lowest_common_ancestor_of_a_binary_tree/bst_lca.c rename to 0236_lowest_common_ancestor_of_a_binary_tree/bst_lca.c index 2b83bef..4eefea8 100644 --- a/236_lowest_common_ancestor_of_a_binary_tree/bst_lca.c +++ b/0236_lowest_common_ancestor_of_a_binary_tree/bst_lca.c @@ -2,33 +2,28 @@ #include #include + struct TreeNode { int val; struct TreeNode *left; 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 */ return root; } + /* l is the LCA in the left branch but not root->left */ struct TreeNode *l = lowestCommonAncestor(root->left, p, q); - if (l != NULL && l != p && l != q) { - /* both p and q in left subtree: l->left != NULL && l->right != NULL */ - return l; - } - + /* r is the LCA in the right branch but not root->right */ struct TreeNode *r = lowestCommonAncestor(root->right, p, q); - if (r != NULL && r != p && r != q) { - /* both p and q in right subtree: r->left != NULL && r->right != NULL */ - return r; - } - if (l != NULL && r != NULL) { return root; } else { + /* if not return root node, the return value is fixed */ return l != NULL ? l : r; } } 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/239_sliding_window_maximum/Makefile b/0239_sliding_window_maximum/Makefile similarity index 100% rename from 239_sliding_window_maximum/Makefile rename to 0239_sliding_window_maximum/Makefile diff --git a/239_sliding_window_maximum/slide_window.c b/0239_sliding_window_maximum/slide_window.c similarity index 70% rename from 239_sliding_window_maximum/slide_window.c rename to 0239_sliding_window_maximum/slide_window.c index 5f5011b..8fa5cbf 100644 --- a/239_sliding_window_maximum/slide_window.c +++ b/0239_sliding_window_maximum/slide_window.c @@ -7,27 +7,30 @@ */ int* maxSlidingWindow(int* nums, int numsSize, int k, int* returnSize) { - int i, head = 0, tail = 0; + int i, left = 0, right = 0; int count = 0; int *indexes = malloc(numsSize * sizeof(int)); int *results = malloc((numsSize - k + 1) * sizeof(int)); for (i = 0; i < numsSize; i++) { /* keep the elements in slide window monotonous decreasing */ - while (tail > head && nums[i] >= nums[indexes[tail - 1]]) { + while (right > left && nums[i] >= nums[indexes[right - 1]]) { /* squeeze out the previous smaller ones */ - tail--; + right--; } - /* Pipe: first in last out */ - indexes[tail++] = i; - if (indexes[head] <= i - k) { - head++; - } + /* In order to measure the moving size of the sliding window, we + * need to store the index instead of element into the window. + */ + indexes[right++] = i; - /* k - 1 is the end of the first sliding window */ + /* let k = 1 to verify the corner case */ if (i >= k - 1) { - results[count++] = nums[indexes[head]]; + results[count++] = nums[indexes[left]]; + } + + if (i - indexes[left] + 1 >= k) { + left++; } } diff --git a/0239_sliding_window_maximum/slide_window.cc b/0239_sliding_window_maximum/slide_window.cc new file mode 100644 index 0000000..ceac2b6 --- /dev/null +++ b/0239_sliding_window_maximum/slide_window.cc @@ -0,0 +1,31 @@ +#include + +using namespace std; + +class Solution { +public: + vector maxSlidingWindow(vector& nums, int k) { + vector res; + // In order to measure the moving size of the sliding window, we + // need to store the index instead of element into the window. + vector indexes(nums.size()); + int left = 0, right = 0; + for (int i = 0; i < nums.size(); i++) { + while (right > left && nums[i] >= nums[indexes[right - 1]]) { + right--; + } + indexes[right++] = i; + + // The last position of sliding window + if (i >= k - 1) { + res.push_back(nums[indexes[left]]); + } + + // The length of sliding window + if (i - indexes[left] + 1 >= k) { + left++; + } + } + return res; + } +}; diff --git a/023_merge_k_sorted_lists/merge_lists.c b/023_merge_k_sorted_lists/merge_lists.c deleted file mode 100644 index 3b29dd6..0000000 --- a/023_merge_k_sorted_lists/merge_lists.c +++ /dev/null @@ -1,191 +0,0 @@ -#include -#include -#include - -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; - *a = *b; - *b = tmp; -} - -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) -{ - int i; - for (i = 0; i < queue->size; i++) { - printf("%d ", queue->nodes[i]->val); - } - printf("\n"); -} - -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); - } -} - -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; - } - } -} - -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; - } - } -} - -static void heap_build(struct PriorityQueue *queue) -{ - int i; - for (i = queue->size / 2 - 1; i > 0; i--) { - percolate_down1(queue->nodes, queue->size, i); - } -} - -static void put(struct PriorityQueue *queue, struct ListNode *node) -{ - queue->nodes[queue->size++] = node; - percolate_up(queue->nodes, queue->size - 1); -} - -static struct ListNode *get(struct PriorityQueue *queue) -{ - 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; -} - -static struct PriorityQueue *init(int size) -{ - struct PriorityQueue *queue = malloc(sizeof(*queue)); - queue->nodes = malloc(size * sizeof(*queue->nodes)); - queue->size = 0; - return queue; -} - -static struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) -{ - if (listsSize == 0) { - return NULL; - } - - if (listsSize == 1) { - return lists[0]; - } - - int i; - struct ListNode dummy; - struct ListNode *prev; - struct PriorityQueue *queue = init(listsSize); - - dummy.next = NULL; - prev = &dummy; - - for (i = 0; i < listsSize; i++) { - if (lists[i] != NULL) { - put(queue, lists[i]); - } - } - heap_build(queue); - - while (queue->size > 0) { - struct ListNode *n = get(queue); - prev->next = n; - prev = n; - if (n->next != NULL) { - put(queue, n->next); - } - n->next = NULL; - } - - return dummy.next; -} - -int main(void) -{ - int i, size; - struct ListNode *p, *prev, *sorted, dummy1, dummy2, **lists; - - dummy1.next = NULL; - prev = &dummy1; - for (i = 0; i < 3; i++) { - p = malloc(sizeof(*p)); - p->val = i * 2; - p->next = NULL; - prev->next = p; - prev = p; - } - for (p = dummy1.next; p != NULL; p = p->next) { - printf("%d ", p->val); - } - putchar('\n'); - - dummy2.next = NULL; - prev = &dummy2; - for (i = 0; i < 5; i++) { - p = malloc(sizeof(*p)); - p->val = i * 2 + 1; - p->next = NULL; - prev->next = p; - prev = p; - } - for (p = dummy2.next; p != NULL; p = p->next) { - printf("%d ", p->val); - } - putchar('\n'); - - size = 2; - lists = malloc(size * sizeof(struct ListNode *)); - lists[0] = NULL;//dummy1.next; - lists[1] = NULL;//dummy2.next; - sorted = mergeKLists(lists, size); - for (p = sorted; p != NULL; p = p->next) { - printf("%d ", p->val); - } - putchar('\n'); - - return 0; -} diff --git a/028_implement_strstr/strstr.cc b/028_implement_strstr/strstr.cc deleted file mode 100644 index 08808ff..0000000 --- a/028_implement_strstr/strstr.cc +++ /dev/null @@ -1,10 +0,0 @@ -#include - -using namespace std; - -class Solution { -public: - int strStr(string haystack, string needle) { - return haystack.find(needle); - } -}; diff --git a/0297_serialize_and_deserialize_binary_tree/Makefile b/0297_serialize_and_deserialize_binary_tree/Makefile new file mode 100644 index 0000000..cc0d8b0 --- /dev/null +++ b/0297_serialize_and_deserialize_binary_tree/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test tree_serdes.c diff --git a/0297_serialize_and_deserialize_binary_tree/tree_serdes.c b/0297_serialize_and_deserialize_binary_tree/tree_serdes.c new file mode 100644 index 0000000..e1e3f12 --- /dev/null +++ b/0297_serialize_and_deserialize_binary_tree/tree_serdes.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include + + +struct TreeNode { + int val; + struct TreeNode *left; + struct TreeNode *right; +}; + +static int count = 0; +static int SYM_NULL = INT_MIN; + +static void ser(struct TreeNode *root, char **str, int *len) { + if (root == NULL) { + memcpy(str + *len, &SYM_NULL, sizeof(int)); + (*len) += sizeof(int); + } else { + memcpy(str + *len, &root->val, sizeof(int)); + (*len) += sizeof(int); + ser(root->left, str, len); + ser(root->right, str, len); + } + count++; +} + +static struct TreeNode *des(char **str) +{ + if (count == 0) { + return NULL; + } + count--; + + int value; + memcpy(&value, *str, sizeof(int)); + (*str) += sizeof(int); + if (value == SYM_NULL) { + return NULL; + } + struct TreeNode *node = malloc(sizeof(struct TreeNode)); + node->val = value; + node->left = des(str); + node->right = des(str); + return node; +} + +/** Encodes a tree to a single string. */ +char* serialize(struct TreeNode* root) { + int len = 0; + char *str = malloc(40000); + memset(str, '\0', 40000); + ser(root, &str, &len); + return str; +} + +/** Decodes your encoded data to tree. */ +struct TreeNode* deserialize(char* data) { + return des(&data); +} + +int main(void) +{ + struct TreeNode root; + root.val = 3; + + struct TreeNode node1[2]; + node1[0].val = 9; + node1[1].val = 20; + + struct TreeNode node2[4]; + node2[2].val = 15; + node2[3].val = 7; + + root.left = &node1[0]; + root.right = &node1[1]; + + node1[0].left = NULL; + node1[0].right = NULL; + node1[1].left = &node2[2]; + node1[1].right = &node2[3]; + + node2[0].left = NULL; + node2[0].right = NULL; + node2[1].left = NULL; + node2[1].right = NULL; + node2[2].left = NULL; + node2[2].right = NULL; + node2[3].left = NULL; + node2[3].right = NULL; + + /* Your functions will be called as such */ + char* data = serialize(&root); + printf("%s\n", data); + deserialize(data); + + return 0; +} diff --git a/0297_serialize_and_deserialize_binary_tree/tree_serdes.cc b/0297_serialize_and_deserialize_binary_tree/tree_serdes.cc new file mode 100644 index 0000000..08b9898 --- /dev/null +++ b/0297_serialize_and_deserialize_binary_tree/tree_serdes.cc @@ -0,0 +1,73 @@ +#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 Codec { +public: + + // Encodes a tree to a single string. + string serialize(TreeNode* root) { + string res; + ser(root, res); + return res; + } + + // Decodes your encoded data to tree. + TreeNode* deserialize(string data) { + int len = data.length(); + return des(data.c_str(), &len); + } + +private: + void ser(TreeNode* root, string& res) { + if (root == nullptr) { + res.push_back((char) 0x80); + res.push_back((char) 0x00); + res.push_back((char) 0x00); + res.push_back((char) 0x00); + return; + } + + ser(root->left, res); + ser(root->right, res); + + for (int i = sizeof(int) - 1; i >= 0; i--) { + res.push_back(((char *)&root->val)[i]); + } + } + + TreeNode* des(const char *data, int *len) { + if (*len == 0) { + return nullptr; + } + + int value; + const char *s = data + *len - 1; + for (int i = 0; i < sizeof(int); i++) { + ((char *)&value)[i] = *s--; + } + if (value == INT_MIN) { + (*len) -= sizeof(int); + return nullptr; + } + (*len) -= sizeof(int); + + TreeNode *root = new TreeNode(value); + root->right = des(data, len); + root->left = des(data, len); + return root; + } +}; + +// Your Codec object will be instantiated and called as such: +// Codec ser, deser; +// TreeNode* ans = deser.deserialize(ser.serialize(root)); 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/Makefile b/0322_coin_change/Makefile new file mode 100644 index 0000000..a766ed4 --- /dev/null +++ b/0322_coin_change/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test coin_change.c diff --git a/0322_coin_change/coin_change.c b/0322_coin_change/coin_change.c new file mode 100644 index 0000000..9eb270c --- /dev/null +++ b/0322_coin_change/coin_change.c @@ -0,0 +1,44 @@ +#include +#include + + +int coinChange(int* coins, int coinsSize, int amount) +{ + int i, j; + int *dp = malloc((amount + 1) * sizeof(int)); + + /* 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]]; + dp[i] = tmp < dp[i] ? tmp : dp[i]; + } + } + } + + return dp[amount] == amount + 1 ? -1 : dp[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", coinChange(coins, size, amount)); + + return 0; +} diff --git a/0322_coin_change/coin_change.cc b/0322_coin_change/coin_change.cc new file mode 100644 index 0000000..31ddb51 --- /dev/null +++ b/0322_coin_change/coin_change.cc @@ -0,0 +1,47 @@ +#include + +using namespace std; + +class Solution { +public: + int coinChange(vector& coins, int amount) { +#if 1 + vector dp(amount + 1, amount + 1); + dp[0] = 0; + for (int i = 1; i <= amount; i++) { + for (int coin : coins) { + if (i - coin >= 0) { + dp[i] = min(dp[i], 1 + dp[i - coin]); + } + } + } + return dp[amount] == amount + 1 ? -1 : dp[amount]; +#else + // BFS solution is slow... + queue q; + unordered_set visited; + int step = 0; + q.push(amount); + while (!q.empty()) { + int size = q.size(); + for (int i = 0; i < size; i++) { + if (q.front() == 0) { + return step; + } + for (int coin : coins) { + int n = q.front() - coin; + if (n >= 0) { + if (visited.count(n) == 0) { + visited.insert(n); + q.push(n); + } + } + } + q.pop(); + } + step++; + } + return -1; +#endif + } +}; diff --git a/0337_house_robber_iii/robber.cc b/0337_house_robber_iii/robber.cc new file mode 100644 index 0000000..b25e2cc --- /dev/null +++ b/0337_house_robber_iii/robber.cc @@ -0,0 +1,31 @@ +#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: + int rob(TreeNode* root) { + auto res = dfs(root); + return max(res.first, res.second); + } + + pair dfs(TreeNode *root) { + if (root == nullptr) { + return make_pair(0, 0); + } + auto subl = dfs(root->left); + auto subr = dfs(root->right); + int taken = root->val + subl.second + subr.second; + int untaken = max(subl.first, subl.second) + max(subr.first, subr.second); + return make_pair(taken, untaken); + } +}; 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/0416_partition_equal_subset_sum/partition.cc b/0416_partition_equal_subset_sum/partition.cc new file mode 100644 index 0000000..79e8edf --- /dev/null +++ b/0416_partition_equal_subset_sum/partition.cc @@ -0,0 +1,28 @@ +#include + +using namespace std; + +class Solution { +public: + bool canPartition(vector& nums) { + int sum = 0; + for (int n : nums) { + sum += n; + } + if (sum % 2 != 0) { + return false; + } + + vector dp(sum / 2 + 1, false); + dp[0] = true; + for (int i = 0; i < nums.size(); i++) { + for (int j = sum / 2 ; j >= 0; j--) { + if (j >= nums[i]) { + dp[j] = dp[j] || dp[j - nums[i]]; + } + } + } + + return dp[sum / 2]; + } +}; diff --git a/042_trapping_rain_water/trap_water.c b/042_trapping_rain_water/trap_water.c deleted file mode 100644 index 343b8b3..0000000 --- a/042_trapping_rain_water/trap_water.c +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include - - -static inline int max(int a, int b) -{ - return a > b ? a : b; -} - -static inline int min(int a, int b) -{ - return a < b ? a : b; -} - -static int trap(int* height, int heightSize) -{ - if (heightSize < 1) { - return 0; - } - - int i; - int *lh = malloc(heightSize * sizeof(int)); - int *rh = malloc(heightSize * sizeof(int)); - - /* restore the max height in the left side of [i] (included) */ - lh[0] = height[0]; - for (i = 1; i < heightSize; i++) { - lh[i] = max(height[i], lh[i - 1]); - } - - /* restore the max height in the right side of [i] (included) */ - rh[heightSize - 1] = height[heightSize - 1]; - for (i = heightSize - 2; i >= 0; i--) { - rh[i] = max(height[i], rh[i + 1]); - } - - int capacity = 0; - for (i = 0; i < heightSize; i++) { - capacity += min(lh[i], rh[i]) - height[i]; - } - - return capacity; -} - -int main(int argc, char **argv) -{ - int i, count = argc - 1; - int *nums = malloc(count * sizeof(int)); - for (i = 0; i < count; i++) { - nums[i] = atoi(argv[i + 1]); - } - printf("%d\n", trap(nums, count)); - return 0; -} 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/043_multiply_strings/multiply_strings.c b/043_multiply_strings/multiply_strings.c deleted file mode 100644 index 469014f..0000000 --- a/043_multiply_strings/multiply_strings.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include - -static void reverse(char *s, int len) -{ - int low = 0; - int high = len - 1; - while (low < high) { - char c = s[low]; - s[low] = s[high]; - s[high] = c; - low++; - high--; - } -} - -static char* multiply(char* num1, char* num2) -{ - if (*num1 == '\0') { - return num1; - } - if (*num2 == '\0') { - return num2; - } - - int i, j; - char *result = malloc(110 + 110); - memset(result, '0', 220); - int len1 = strlen(num1); - int len2 = strlen(num2); - reverse(num1, len1); - reverse(num2, len2); - for (i = 0; i < len1; i++) { - int carry = 0; - for (j = 0; j < len2; j++) { - carry += (num1[i] - '0') * (num2[j] - '0') + (result[i + j] - '0'); - result[i + j] = carry % 10 + '0'; - carry /= 10; - } - if (carry != 0) { - result[len2 + i] = carry + '0'; - } - } - int len = 220; - while (--len >= 0) { - if (result[len] > '0') { - result[++len] = '\0'; - break; - } - } - if (len == -1) { - len = 1; - result[len] = '\0'; - } - reverse(result, len); - return result; -} - -int main(int argc, char **argv) -{ - if (argc != 3) { - fprintf(stderr, "Usage: ./test m1 m2\n"); - exit(-1); - } - printf("%s\n", multiply(argv[1], argv[2])); - return 0; -} diff --git a/044_wildcard_matching/wildcard_matching.c b/044_wildcard_matching/wildcard_matching.c deleted file mode 100644 index c543e93..0000000 --- a/044_wildcard_matching/wildcard_matching.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include - -static bool isMatch(char* s, char* p) -{ - char *last_s = NULL; - char *last_p = NULL; - while(*s != '\0') { - if (*p=='*'){ - //skip the "*", and mark a flag - p++; - //edge case - if (*p=='\0') return true; - //use last_s and last_p to store where the "*" match starts. - last_s = s; - last_p = p; - } else if (*p=='?' || *s == *p) { - s++; - p++; - } else if (last_s != NULL) { - // check "last_s" to know whether meet "*" before - // if meet "*" previously, and the *s != *p - // reset the p, using '*' to match this situation - p = last_p; - s = ++last_s; - } else { - // *p is not wildcard char, - // doesn't match *s, - // there are no '*' wildcard matched before - return false; - } - } - //edge case: "s" is done, but "p" still have chars. - while (*p == '*') { - p++; - } - return *p == '\0'; -} - -int main(int argc, char **argv) -{ - if (argc != 3) { - fprintf(stderr, "Usage: ./test string pattern\n"); - exit(-1); - } - - printf("%s\n", isMatch(argv[1], argv[2]) ? "true" : "false"); - return 0; -} diff --git a/045_jump_game_ii/jump_game.c b/045_jump_game_ii/jump_game.c deleted file mode 100644 index b6d2ed3..0000000 --- a/045_jump_game_ii/jump_game.c +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include - -static inline int max(int a, int b) -{ - return a > b ? a : b; -} - -static int jump(int* nums, int numsSize) -{ - int i, lo = 0, hi = 0; - int steps = 0; - while (hi < numsSize - 1) { - int right = 0; - /* [lo, hi] is the next location range, find the farest jump */ - for (i = lo; i <= hi; i++) { - /* Assume right > hi for the purpose of the problem */ - right = max(i + nums[i], right); - } - lo = hi + 1; - hi = right; - steps++; - } - return steps; -} - -int main(int argc, char **argv) -{ - int i, count = argc - 1; - int *nums = malloc(count * sizeof(int)); - for (i = 0; i < count; i++) { - nums[i] = atoi(argv[i + 1]); - } - printf("%d\n", jump(nums, count)); - return 0; -} diff --git a/0460_lfu_cache/Makefile b/0460_lfu_cache/Makefile new file mode 100644 index 0000000..d324ed9 --- /dev/null +++ b/0460_lfu_cache/Makefile @@ -0,0 +1,3 @@ +all: + gcc -O1 -o test lfu_cache.c + #g++ -O1 -std=c++11 -o test lfu_cache.cc diff --git a/0460_lfu_cache/lfu_cache.c b/0460_lfu_cache/lfu_cache.c new file mode 100644 index 0000000..fdcfb77 --- /dev/null +++ b/0460_lfu_cache/lfu_cache.c @@ -0,0 +1,465 @@ +#include +#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_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_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_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; +}; + +typedef struct FreqAVLNode { + int freq; + int height; + struct FreqAVLNode *children[2]; + struct FreqAVLNode *parent; + struct list_head dhead; /* freq_list head */ +} FreqAVLNode; + +typedef struct { + FreqAVLNode *root; + FreqAVLNode *min_freq_node; +} FreqAVLTree; + +typedef struct LFUNode { + int key; + int val; + int freq; + FreqAVLNode *node; /* freq tree node */ + struct list_head dlink; /* freq_list */ + struct list_head key_link; /* key_map */ +} LFUNode; + +typedef struct { + int size; + int capacity; + FreqAVLTree *tree; + struct list_head hheads[0]; +} LFUCache; + +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; +} + +static inline int height(FreqAVLNode *node) +{ + return node != NULL ? node->height : 0; +} + +static inline void avl_update_height(FreqAVLNode *node) +{ + int ld = height(node->children[0]); + int rd = height(node->children[1]); + node->height = 1 + (ld > rd ? ld : rd); +} + +static void avl_node_replace(FreqAVLTree *tree, FreqAVLNode *old, FreqAVLNode *new) +{ + if (new != NULL) { + new->parent = old->parent; + } + + FreqAVLNode *parent = old->parent; + if (parent == NULL) { + tree->root = new; + } else { + if (parent->children[0] == old) { + parent->children[0] = new; + } else { + parent->children[1] = new; + } + avl_update_height(parent); + } +} + +static FreqAVLNode *avl_node_rotate(FreqAVLTree *tree, FreqAVLNode *node, int side) +{ + /* The child of this node will take its place: + for a left rotation, it is the right child, and vice versa. */ + FreqAVLNode *new = node->children[1 - side]; + + /* Make new the root, rearrange pointers */ + avl_node_replace(tree, node, new); + node->children[1 - side] = new->children[side]; + new->children[side] = node; + + /* Update parent references */ + node->parent = new; + if (node->children[1 - side] != NULL) { + node->children[1 - side]->parent = node; + } + + /* Update heights of the affected nodes */ + avl_update_height(new); + avl_update_height(node); + + return new; +} + +static FreqAVLNode *avl_node_balance(FreqAVLTree *tree, FreqAVLNode *node) +{ + FreqAVLNode *left = node->children[0]; + FreqAVLNode *right = node->children[1]; + + int diff = height(left) - height(right); + if (diff <= -2) { + /* Biased toward the right side */ + if (height(right->children[0]) > height(right->children[1])) { + /* double rotation: at node->right->left */ + avl_node_rotate(tree, right, 1); + } + /* single rotation: at node->right->right */ + node = avl_node_rotate(tree, node, 0); + } else if (diff >= 2) { + /* Biased toward the left side */ + if (height(left->children[0]) < height(left->children[1])) { + /* double rotation: at node->left->right */ + avl_node_rotate(tree, left, 0); + } + /* single rotation: at node->left->left */ + node = avl_node_rotate(tree, node, 1); + } + + avl_update_height(node); + return node; +} + +static void avl_tree_balance(FreqAVLTree *tree, FreqAVLNode *node) +{ + while (node != NULL) { + node = avl_node_balance(tree, node); + node = node->parent; + } +} + +static FreqAVLNode *avl_tree_insert(FreqAVLTree *tree, int freq) +{ + /* Walk down the tree until we reach a NULL pointer */ + FreqAVLNode *parent = NULL; + FreqAVLNode **rover = &tree->root; + while (*rover != NULL) { + parent = *rover; + if (freq < (*rover)->freq) { + rover = &((*rover)->children[0]); + } else if (freq > (*rover)->freq) { + rover = &((*rover)->children[1]); + } else { + return *rover; + } + } + + /* Create a new node and insert into parent's children link */ + FreqAVLNode *node = malloc(sizeof(*node)); + INIT_LIST_HEAD(&node->dhead); + node->children[0] = NULL; + node->children[1] = NULL; + node->parent = parent; + node->freq = freq; + node->height = 1; + + /* Insert at parent's children link (assign the children pointer value) */ + *rover = node; + /* Rebalance the tree */ + avl_tree_balance(tree, parent); + return node; +} + +static FreqAVLNode *avl_node_closest_get(FreqAVLTree *tree, FreqAVLNode *node) +{ + FreqAVLNode *left = node->children[0]; + FreqAVLNode *right = node->children[1]; + if (left == NULL && right == NULL) { + /* return NULL if leaf node */ + return NULL; + } + + /* Search down the tree, back towards the center. */ + int side = height(left) > height(right) ? 0 : 1; + FreqAVLNode *closest = node->children[side]; + while (closest->children[1 - side] != NULL) { + closest = closest->children[1 - side]; + } + + /* Unlink the closest node, and hook in its remaining child + * (if it has one) to replace it. */ + avl_node_replace(tree, closest, closest->children[side]); + + /* Update the subtree height for the closest node's old parent. */ + avl_update_height(closest->parent); + return closest; +} + +static void avl_node_erase(FreqAVLTree *tree, FreqAVLNode *node) +{ + /* The node to be erased must be swapped with an "adjacent" node, ie. + * one which has the closest key to this one. Find the node to swap with. */ + FreqAVLNode *startpoint; + FreqAVLNode *swap_node = avl_node_closest_get(tree, node); + if (swap_node == NULL) { + /* This is a leaf node and has no children, therefore + * it can be immediately erased. */ + avl_node_replace(tree, node, NULL); + /* Start rebalancing from the parent of the original node */ + startpoint = node->parent; + } else { + /* We will start rebalancing from the old parent of the swap node. + * Sometimes, the old parent is the node we are removing, + * in which case we must start rebalancing from the swap node. */ + if (swap_node->parent == node) { + startpoint = swap_node; + } else { + startpoint = swap_node->parent; + } + + /* Copy references */ + int i; + for (i = 0; i < 2; i++) { + swap_node->children[i] = node->children[i]; + if (swap_node->children[i] != NULL) { + swap_node->children[i]->parent = swap_node; + } + } + + swap_node->height = node->height; + /* Link the parent's reference to this node */ + avl_node_replace(tree, node, swap_node); + } + + free(node); + + /* Rebalance the tree */ + avl_tree_balance(tree, startpoint); +} + +static FreqAVLTree *avl_tree_init(void) +{ + FreqAVLTree *tree = malloc(sizeof(*tree)); + tree->root = NULL; + tree->min_freq_node = NULL; + return tree; +} + +static void avl_node_destory_recursive(FreqAVLNode *root) +{ + if (root == NULL) { + return; + } + + avl_node_destory_recursive(root->children[0]); + avl_node_destory_recursive(root->children[1]); + + free(root); +} + +static void avl_tree_destory(FreqAVLTree *tree) +{ + avl_node_destory_recursive(tree->root); +} + +static void freq_incr(FreqAVLTree* tree, LFUNode *lfu, int key) +{ + /* New frequency */ + list_del(&lfu->dlink); + int freq = ++lfu->freq; + FreqAVLNode *node = avl_tree_insert(tree, freq); + if (list_empty(&lfu->node->dhead)) { + if (lfu->node == tree->min_freq_node) { + tree->min_freq_node = node; + } + /* we must erase the empty node to rearrange the AVL tree */ + avl_node_erase(tree, lfu->node); + } + lfu->node = node; + list_add(&lfu->dlink, &lfu->node->dhead); +} + +LFUCache* lFUCacheCreate(int capacity) +{ + int i; + LFUCache* obj = malloc(sizeof(*obj) + capacity * sizeof(struct list_head)); + obj->size = 0; + obj->capacity = capacity; + obj->tree = avl_tree_init(); + for (i = 0; i < capacity; i++) { + INIT_LIST_HEAD(&obj->hheads[i]); + } + return obj; +} + +int lFUCacheGet(LFUCache* obj, int key) +{ + if (obj->capacity <= 0) { + return; + } + + LFUNode *lfu; + int hash = key % obj->capacity; + list_for_each_entry(lfu, &obj->hheads[hash], key_link) { + if (lfu->key == key) { + freq_incr(obj->tree, lfu, key); + return lfu->val; + } + } + return -1; +} + +void lFUCachePut(LFUCache* obj, int key, int value) +{ + if (obj->capacity <= 0) { + return; + } + + LFUNode *lfu; + int hash = key % obj->capacity; + list_for_each(lfu, &obj->hheads[hash], key_link) { + if (lfu->key == key) { + freq_incr(obj->tree, lfu, key); + lfu->val = value; + return; + } + } + + /* squeeze minimum frequency */ + if (obj->size == obj->capacity) { + FreqAVLNode *node = obj->tree->min_freq_node; + lfu = list_last_entry(&node->dhead, LFUNode, dlink); + list_del(&lfu->dlink); + list_del(&lfu->key_link); + /* NOTE: we DO NOT need to erase the empty AVL node since the min freq node would be update immediately */ + } else { + /* new LFU */ + obj->size++; + lfu = malloc(sizeof(*lfu)); + } + + lfu->key = key; + lfu->val = value; + lfu->freq = 1; + lfu->node = avl_tree_insert(obj->tree, lfu->freq); + obj->tree->min_freq_node = lfu->node; + list_add(&lfu->dlink, &lfu->node->dhead); + list_add(&lfu->key_link, &obj->hheads[hash]); +} + +void lFUCacheFree(LFUCache* obj) +{ + int i; + for (i = 0; i < obj->capacity; i++) { + 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); + } + } + + avl_tree_destory(obj->tree); + free(obj); +} + +/** + * Your LFUCache struct will be instantiated and called as such: + * LFUCache* obj = lFUCacheCreate(capacity); + * int param_1 = lFUCacheGet(obj, key); + + * lFUCachePut(obj, key, value); + + * lFUCacheFree(obj); +*/ + +int main(void) +{ + LFUCache* obj = lFUCacheCreate(2); +#if 1 + lFUCachePut(obj, 1, 1); + printf("Put 1 1\n"); + lFUCachePut(obj, 2, 2); + printf("Put 2 2\n"); + printf("Get 1 %d\n", lFUCacheGet(obj, 1)); + lFUCachePut(obj, 3, 3); + printf("Put 3 3\n"); + printf("Get 2 %d\n", lFUCacheGet(obj, 2)); + printf("Get 3 %d\n", lFUCacheGet(obj, 3)); + lFUCachePut(obj, 4, 4); + printf("Put 4 4\n"); + printf("Get 1 %d\n", lFUCacheGet(obj, 1)); + printf("Get 3 %d\n", lFUCacheGet(obj, 3)); + printf("Get 4 %d\n", lFUCacheGet(obj, 4)); +#else + lFUCachePut(obj, 2, 1); + printf("Put 2 1\n"); + lFUCachePut(obj, 3, 2); + printf("Put 3 2\n"); + printf("Get 3 %d\n", lFUCacheGet(obj, 3)); + printf("Get 2 %d\n", lFUCacheGet(obj, 2)); + lFUCachePut(obj, 4, 3); + printf("Put 4 3\n"); + printf("Get 2 %d\n", lFUCacheGet(obj, 2)); + printf("Get 3 %d\n", lFUCacheGet(obj, 3)); + printf("Get 4 %d\n", lFUCacheGet(obj, 4)); +#endif + lFUCacheFree(obj); + return 0; +} diff --git a/0460_lfu_cache/lfu_cache.cc b/0460_lfu_cache/lfu_cache.cc new file mode 100644 index 0000000..cfb3bc9 --- /dev/null +++ b/0460_lfu_cache/lfu_cache.cc @@ -0,0 +1,121 @@ +#include +#include +#include +#include + +using namespace std; + +class LFUCache { + typedef struct LFU { + int key_; + int value_; + int freq_; + LFU(int key, int value, int freq) : key_(key), value_(value), freq_(freq) {}; + } LFU; + +public: + LFUCache(int capacity) { + cap_ = capacity; + } + + int get(int key) { + if (key_map_.count(key) == 0) { + return -1; + } + + freq_incr(key); + return (*key_map_[key])->value_; + } + + void put(int key, int value) { + if (cap_ <= 0) { + return; + } + + if (key_map_.count(key) == 0) { + freq_incr(key); + (*key_map_[key])->value_ = value; + } else { + if (key_map_.size() == cap_) { + // squeeze minimum frequency + auto& li = freq_map_.begin()->second; + key_map_.erase(li.back()->key_); + li.pop_back(); + } + + _freq_incr(key, value, 0); + } + } + +private: + void freq_incr(int key) { + int value = (*key_map_[key])->value_; + int freq = (*key_map_[key])->freq_; + + // list.erase + freq_map.erase + auto& li = freq_map_[freq]; + li.erase(key_map_[key]); + if (li.empty()) { + freq_map_.erase(freq); + } + + _freq_incr(key, value, freq); + } + + void _freq_incr(int key, int value, int freq) { + if (freq_map_.count(freq + 1) == 0) { + freq_map_[freq + 1] = li_; + } + + auto& li = freq_map_[freq + 1]; + li.push_front(new LFU(key, value, freq + 1)); + key_map_[key] = li.begin(); + } + + void freq_map_show() { + cout << "freq map show:" << endl; + for (auto it : freq_map_) { + cout << it.first << ": "; + for (auto lfu : it.second) + cout << lfu->key_ << " "; + cout << "\t"; + } + cout << endl; + } + + int cap_; + list li_; + map freq_map_; + unordered_map key_map_; +}; + +/** + * Your LFUCache object will be instantiated and called as such: + * LFUCache* obj = new LFUCache(capacity); + * int param_1 = obj->get(key); + * obj->put(key,value); + */ + +int main() { + LFUCache *lfu = new LFUCache(2); + lfu->put(1, 1); + cout << "put 1 1" << endl; + lfu->put(2, 2); + cout << "put 2 2" << endl; + cout << "get " << lfu->get(1) << endl; // return 1 + lfu->put(3, 3); // evicts key 2 + cout << "put 3 3" << endl; + //lfu->get(2); // return -1 (not found) + cout << "get " << lfu->get(2) << endl; + //lfu->get(3); // return 3 + cout << "get " << lfu->get(3) << endl; + lfu->put(4, 4); // evicts key 1. + cout << "put 4 4" << endl; + //lfu->get(1); // return -1 (not found) + cout << "get " << lfu->get(1) << endl; + //lfu->get(3); // return 3 + cout << "get " << lfu->get(3) << endl; + //lfu->get(4); // return 4 + cout << "get " << lfu->get(4) << endl; + return 0; +} diff --git a/048_rotate_image/rotate.c b/048_rotate_image/rotate.c deleted file mode 100644 index f5e6c79..0000000 --- a/048_rotate_image/rotate.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include - -static void rotate(int** matrix, int matrixRowSize, int matrixColSize) -{ - int i, j; - if (matrixRowSize != matrixColSize) { - return; - } - - for (i = 0; i < matrixRowSize / 2; i++) { - int low = i, high = matrixColSize - i - 1; - for (j = low; j < high; j++) { - int tmp = matrix[i][j]; - matrix[i][j] = matrix[matrixColSize - 1 - j][i]; - matrix[matrixColSize - 1 - j][i] = matrix[matrixRowSize - 1 - i][matrixColSize - 1 - j]; - matrix[matrixRowSize - 1 - i][matrixColSize - 1 - j] = matrix[j][matrixRowSize - 1 - i]; - matrix[j][matrixRowSize - 1 - i] = tmp; - } - } -} - -int main(int argc, char **argv) -{ - if (argc != 3) { - fprintf(stderr, "Usage: ./test 3 3\n"); - } - - int i, j, count = 0; - int row_size = atoi(argv[1]); - int col_size = atoi(argv[2]); - int **matrix = malloc(row_size * sizeof(int *)); - for (i = 0; i < row_size; i++) { - matrix[i] = malloc(col_size * sizeof(int)); - for (j = 0; j < col_size; j++) { - matrix[i][j] = ++count; - printf("%d ", matrix[i][j]); - } - printf("\n"); - } - - rotate(matrix, row_size, col_size); - for (i = 0; i < col_size; i++) { - for (j = 0; j < row_size; j++) { - printf("%02d ", matrix[i][j]); - } - putchar('\n'); - } - - return 0; -} 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/0543_diameter_of_binary_tree/diameter_bst.cc b/0543_diameter_of_binary_tree/diameter_bst.cc new file mode 100644 index 0000000..28d57fe --- /dev/null +++ b/0543_diameter_of_binary_tree/diameter_bst.cc @@ -0,0 +1,33 @@ +#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: + int diameterOfBinaryTree(TreeNode* root) { + dfs(root); + return max_diameter; + } + +private: + int max_diameter = 0; + int dfs(TreeNode* root) { + if (root == nullptr) { + return 0; + } + + int ld = dfs(root->left); + int rd = dfs(root->right); + max_diameter = max(max_diameter, ld + rd); + return 1 + max(ld, rd); + } +}; 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/0563_binary_tree_tilt/tilt.cc b/0563_binary_tree_tilt/tilt.cc new file mode 100644 index 0000000..fec3498 --- /dev/null +++ b/0563_binary_tree_tilt/tilt.cc @@ -0,0 +1,35 @@ +#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 findTilt(TreeNode* root) { + dfs(root); + return tilt; + } + +private: + int tilt = 0; + int dfs(TreeNode *root) { + if (root == nullptr) { + return 0; + } + + int subl = dfs(root->left); + int subr = dfs(root->right); + tilt += abs(subl - subr); + return root->val + subl + subr; + } +}; 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/069_sqrt/sqrt.c b/069_sqrt/sqrt.c deleted file mode 100644 index 1d3a5c3..0000000 --- a/069_sqrt/sqrt.c +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include - -static int mySqrt(int x) -{ - if (x == 0) { - return 0; - } - - unsigned int left = 1; - unsigned int right = (unsigned int) x; - for (; ;) { - unsigned int mid = left + (right - left) / 2; - if (mid > x/mid) { - right = mid; - } else { - if (mid + 1 > x/(mid + 1)) { - return mid; - } else { - left = mid; - } - } - } -} - -int main(int argc, char **argv) -{ - if (argc != 2) { - fprintf(stderr, "Usage: ./test n\n"); - exit(-1); - } - - printf("%d\n", mySqrt(atoi(argv[1]))); - return 0; -} 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 setZeroes(int** matrix, int matrixRowSize, int matrixColSize) -{ - int row, col, bRow = 0, bCol = 0; - for (row = 0; row < matrixRowSize; row++) { - for (col = 0; col < matrixColSize; col++) { - if (matrix[row][col] == 0) { - if (row == 0) bCol = 1; - if (col == 0) bRow = 1; - matrix[0][col] = matrix[row][0] = 0; - } - } - } - - for (row = 1; row < matrixRowSize; row++) { - for(col = 1; col < matrixColSize; col++){ - if (matrix[0][col] == 0 || matrix[row][0] == 0) { - matrix[row][col] = 0; - } - } - } - - if (bRow) { - for(row = 0; row < matrixRowSize; row++) { - matrix[row][0] = 0; - } - } - - if (bCol) { - for (col = 0; col +#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/100_same_tree/same_tree.c b/100_same_tree/same_tree.c deleted file mode 100644 index 36bc7bb..0000000 --- a/100_same_tree/same_tree.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include -#include - -struct TreeNode { - int val; - struct TreeNode *left; - struct TreeNode *right; -}; - -static bool isSameTree(struct TreeNode* p, struct TreeNode* q) -{ - if (p != NULL && q != NULL) { - if (p->val != q->val) { - return false; - } - if (!isSameTree(p->left, q->left)) { - return false; - } - if (!isSameTree(p->right, q->right)) { - return false; - } - } else { - return p == q; - } - - return true; -} - -int main(void) -{ - printf("%s\n", isSameTree(NULL, NULL) ? "true" : "false"); - return 0; -} diff --git a/102_binary_tree_level_order_traversal/bst_bfs.c b/102_binary_tree_level_order_traversal/bst_bfs.c deleted file mode 100644 index b12c5ce..0000000 --- a/102_binary_tree_level_order_traversal/bst_bfs.c +++ /dev/null @@ -1,90 +0,0 @@ -#include -#include -#include - -#define BST_MAX_LEVEL 800 - -struct TreeNode { - int val; - struct TreeNode *left; - struct TreeNode *right; -}; - -static void bfs(struct TreeNode *root, int **results, int *count, int *col_sizes, int *size, int level) -{ - if (root == NULL) { - return; - } - - *count = level + 1 > *count ? level + 1 : *count; - if (col_sizes[level] == 0) { - *size = *size > 256 ? 256 : *size * 2; - results[level] = malloc(*size * sizeof(int)); - } - results[level][col_sizes[level]++] = root->val; - bfs(root->left, results, count, col_sizes, size, level + 1); - bfs(root->right, results, count, col_sizes, size, level + 1); -} - -/** - ** 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(). - **/ -static int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes) -{ - if (root == NULL) { - *returnSize = 0; - return NULL; - } - - 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)); - bfs(root, results, returnSize, *returnColumnSizes, &size, 0); - return results; -} - -int main(void) -{ - struct TreeNode root; - root.val = 3; - - struct TreeNode node1[2]; - node1[0].val = 9; - node1[1].val = 20; - - struct TreeNode node2[4]; - node2[2].val = 15; - node2[3].val = 7; - - root.left = &node1[0]; - root.right = &node1[1]; - - node1[0].left = NULL; - node1[0].right = NULL; - node1[1].left = &node2[2]; - node1[1].right = &node2[3]; - - node2[0].left = NULL; - node2[0].right = NULL; - node2[1].left = NULL; - node2[1].right = NULL; - node2[2].left = NULL; - node2[2].right = NULL; - node2[3].left = NULL; - node2[3].right = NULL; - - int i, j, count = 0, *col_sizes; - int **lists = levelOrder(&root, &count, &col_sizes); - for (i = 0; i < count; i++) { - for (j = 0; j < col_sizes[i]; j++) { - printf("%d ", lists[i][j]); - } - printf("\n"); - } - - return 0; -} diff --git a/106_construct_binary_tree_from_inorder_and_postorder_traversal/binary_tree_build.c b/106_construct_binary_tree_from_inorder_and_postorder_traversal/binary_tree_build.c deleted file mode 100644 index 60c9b62..0000000 --- a/106_construct_binary_tree_from_inorder_and_postorder_traversal/binary_tree_build.c +++ /dev/null @@ -1,147 +0,0 @@ -#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; - -struct hlist_head { - struct hlist_node *first; -}; - -struct hlist_node { - struct hlist_node *next, **prev; -}; - -static inline void INIT_HLIST_HEAD(struct hlist_head *h) { - h->first = NULL; -} - -static inline int hlist_empty(struct hlist_head *h) { - return !h->first; -} - -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) -{ - if (h->first != NULL) { - h->first->prev = &n->next; - } - n->next = h->first; - n->prev = &h->first; - h->first = n; -} - -static inline void hlist_del(struct hlist_node *n) -{ - struct hlist_node *next = n->next; - struct hlist_node **prev = n->prev; - *prev = next; - if (next != NULL) { - next->prev = prev; - } -} - -struct TreeNode { - int val; - struct TreeNode *left; - struct TreeNode *right; -}; - -struct order_node { - struct hlist_node node; - int val; - int index; -}; - -static int find(int num, int size, struct hlist_head *heads) -{ - struct hlist_node *p; - int hash = (num < 0 ? -num : num) % size; - hlist_for_each(p, &heads[hash]) { - struct order_node *on = list_entry(p, struct order_node, node); - if (num == on->val) { - return on->index; - } - } - return -1; -} - -static struct TreeNode *node_new(int val) -{ - struct TreeNode *tn = malloc(sizeof(*tn)); - tn->val = val; - tn->left = NULL; - tn->right = NULL; - return tn; -} - -static void node_add(int val, int index, int size, struct hlist_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]); -} - -static struct TreeNode *dfs(int *inorder, int in_low, int in_high, int *postorder, - int post_low, int post_high, struct hlist_head *in_heads, int size) -{ - if (in_low > in_high || post_low > post_high) { - return NULL; - } - struct TreeNode *tn = malloc(sizeof(*tn)); - tn->val = postorder[post_high]; - int index = find(postorder[post_high], size, in_heads); - tn->left = dfs(inorder, in_low, index - 1, postorder, post_low, post_low + (index - 1 - in_low), in_heads, size); - tn->right = dfs(inorder, index + 1, in_high, postorder, post_high - (in_high - index), post_high - 1, in_heads, size); - return tn; -} - -static struct TreeNode *buildTree(int *inorder, int inorderSize, int *postorder, int postorderSize) -{ - int i, j; - struct hlist_head *in_heads = malloc(inorderSize * sizeof(*in_heads)); - for (i = 0; i < inorderSize; i++) { - INIT_HLIST_HEAD(&in_heads[i]); - } - for (i = 0; i < inorderSize; i++) { - node_add(inorder[i], i, inorderSize, in_heads); - } - - return dfs(inorder, 0, inorderSize - 1, postorder, 0, postorderSize - 1, in_heads, inorderSize); -} - -static void dump(struct TreeNode *node) -{ - if (node == NULL) { - printf("# "); - return; - } - printf("%d ", node->val); - dump(node->left); - dump(node->right); -} - -int main(void) -{ - //int postorder[] = { 1,2,3 }; - //int postorder[] = { 2,1,3 }; - //int postorder[] = { 1,3,2 }; - //int postorder[] = { 2,3,1 }; - int postorder[] = { 3,2,1 }; - int inorder[] = { 1,2,3 }; - int post_size = sizeof(postorder) / sizeof(*postorder); - int in_size = sizeof(inorder) / sizeof(*inorder); - struct TreeNode *root = buildTree(inorder, in_size, postorder, post_size); - dump(root); - printf("\n"); - return 0; -} diff --git a/109_convert_sorted_list_to_binary_search_tree/bst_convert.c b/109_convert_sorted_list_to_binary_search_tree/bst_convert.c deleted file mode 100644 index c79f239..0000000 --- a/109_convert_sorted_list_to_binary_search_tree/bst_convert.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include - -struct ListNode { - int val; - struct ListNode *next; -}; - -struct TreeNode { - int val; - struct TreeNode *left; - struct TreeNode *right; -}; - -static struct TreeNode *traverse(int *nums, int lo, int hi) -{ - 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; - return node; -} - -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; - } - return traverse(nums, 0, i - 1); -} - -int main(int argc, char **argv) -{ - sortedListToBST(NULL); - return 0; -} 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/128_longest_consecutive_sequence/consec_seq.c b/128_longest_consecutive_sequence/consec_seq.c deleted file mode 100644 index 075844e..0000000 --- a/128_longest_consecutive_sequence/consec_seq.c +++ /dev/null @@ -1,130 +0,0 @@ -#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; - -struct hlist_head { - struct hlist_node *first; -}; - -struct hlist_node { - struct hlist_node *next, **pprev; -}; - -static inline void INIT_HLIST_HEAD(struct hlist_head *h) -{ - h->first = NULL; -} - -static inline int hlist_empty(struct hlist_head *h) -{ - return !h->first; -} - -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) -{ - if (h->first != NULL) { - h->first->pprev = &n->next; - } - n->next = h->first; - n->pprev = &h->first; - h->first = n; -} - -static inline void hlist_del(struct hlist_node *n) -{ - struct hlist_node *next = n->next; - struct hlist_node **pprev = n->pprev; - *pprev = next; - if (next != NULL) { - next->pprev = pprev; - } -} - -struct seq_node { - int num; - struct hlist_node node; -}; - -static struct seq_node *find(int num, int size, struct hlist_head *heads) -{ - 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); - if (node->num == num) { - return node; - } - } - return NULL; -} - -static int longestConsecutive(int* nums, int numsSize) -{ - int i, hash, length = 0; - struct seq_node *node; - struct hlist_head *heads = malloc(numsSize * sizeof(*heads)); - - for (i = 0; i < numsSize; i++) { - INIT_HLIST_HEAD(&heads[i]); - } - - for (i = 0; i < numsSize; i++) { - if (!find(nums[i], numsSize, heads)) { - 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]); - } - } - - 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) { - len++; - hlist_del(&node->node); - } - - int right = num; - while ((node = find(++right, numsSize, heads)) != NULL) { - len++; - hlist_del(&node->node); - } - - length = len > length ? len : length; - } - } - - return length; -} - -int main(int argc, char **argv) -{ - int i, size = argc - 1; - int *nums = malloc(size * sizeof(int)); - for (i = 0; i < size; i++) { - nums[i] = atoi(argv[i + 1]); - } - printf("%d\n", longestConsecutive(nums, size)); - return 0; -} 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/1372_longest_zigzag_path_in_a_binary_tree/zigzag.cc b/1372_longest_zigzag_path_in_a_binary_tree/zigzag.cc new file mode 100644 index 0000000..9ac4d56 --- /dev/null +++ b/1372_longest_zigzag_path_in_a_binary_tree/zigzag.cc @@ -0,0 +1,34 @@ +#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: + int longestZigZag(TreeNode* root) { + dfs(root); + return maxzz - 1; + } +private: + int maxzz = 0; + pair dfs(TreeNode *root) { + if (root == nullptr) { + return make_pair(0, 0); + } + + auto subl = dfs(root->left); + auto subr = dfs(root->right); + int sublzz = 1 + subl.second; + int subrzz = 1 + subr.first; + maxzz = max(maxzz, max(sublzz, subrzz)); + return make_pair(sublzz, subrzz); + } +}; diff --git a/1373_maximum_sum_bst_in_binary_tree/max_bst.cc b/1373_maximum_sum_bst_in_binary_tree/max_bst.cc new file mode 100644 index 0000000..72d9493 --- /dev/null +++ b/1373_maximum_sum_bst_in_binary_tree/max_bst.cc @@ -0,0 +1,53 @@ +#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 maxSumBST(TreeNode* root) { + dfs(root); + return max(0, max_sum); + } +private: + struct TreeInfo { + bool isBst; + int min_val; + int max_val; + int sum_val; + TreeInfo() : isBst(true), min_val(INT_MAX), max_val(INT_MIN), sum_val(0) {} + TreeInfo(bool bst, int min, int max, int sum) : isBst(bst), min_val(min), max_val(max), sum_val(sum) {} + }; + + int max_sum = INT_MIN; + TreeInfo *dfs(TreeNode *root) { + if (root == nullptr) { + return new TreeInfo(); + } + + auto subl = dfs(root->left); + auto subr = dfs(root->right); + + int sum = root->val + subl->sum_val + subr->sum_val; + if (subl->isBst && subr->isBst && root->val > subl->max_val && root->val < subr->min_val) { + max_sum = max(sum, max_sum); + // For leaf nodes + int min_val = min(root->val, subl->min_val); + int max_val = max(root->val, subr->max_val); + return new TreeInfo(true, min_val, max_val, sum); + } else { + return new TreeInfo(false, INT_MAX, INT_MIN, sum); + } + } +}; diff --git a/139_word_break/word_break.c b/139_word_break/word_break.c deleted file mode 100644 index 40992fa..0000000 --- a/139_word_break/word_break.c +++ /dev/null @@ -1,173 +0,0 @@ -#include -#include -#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) -{ - 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 { - 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; - } - } - } - - return result; - } -} - -static 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)); - - for (i = 0; i < wordDictSize; i++) { - sizes[i] = strlen(wordDict[i]); - total += sizes[i]; - } - - struct dfs_cache **caches = malloc(len * sizeof(*caches)); - memset(caches, 0, len * sizeof(*caches)); - return dfs(s, wordDict, sizes, wordDictSize, caches, 0) == NULL; -} - -int main(int argc, char **argv) -{ - if (argc < 3) { - fprintf(stderr, "Usage: ./test word dictionary...\n"); - exit(-1); - } - - printf("%s\n", wordBreak(argv[1], argv + 2, argc - 2) ? "true" : "false"); - return 0; -} diff --git a/140_word_break_ii/word_break.c b/140_word_break_ii/word_break.c deleted file mode 100644 index 2813c4f..0000000 --- a/140_word_break_ii/word_break.c +++ /dev/null @@ -1,201 +0,0 @@ -#include -#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) -{ - 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 { - 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 { - wn = malloc(sizeof(*wn)); - wn->word = words[i]; - list_add(&wn->link, result->heads[result->num++]); - } - } - } - - return result; - } -} - -/** - ** 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) -{ - if (wordDictSize == 0) { - *returnSize = 0; - return NULL; - } - - int i, total = 0; - int len = strlen(s); - int *sizes = malloc(wordDictSize * sizeof(int)); - - /* Add into hash list */ - for (i = 0; i < wordDictSize; i++) { - sizes[i] = strlen(wordDict[i]); - total += sizes[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); - - char **results = malloc(cache->num * sizeof(char *)); - for (i = 0; i < cache->num; 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); - char *q = wn->word; - while ((*p++ = *q++) != '\0') {} - *(p - 1) = ' '; - } - *(p - 1) = '\0'; - } - - *returnSize = cache->num; - return results; -} - -int main(int argc, char **argv) -{ - if (argc < 3) { - fprintf(stderr, "Usage: ./test word dictionary...\n"); - exit(-1); - } - - int i, count = 0; - char **list = wordBreak(argv[1], argv + 2, argc - 2, &count); - for (i = 0; i < count; i++) { - printf("%s\n", list[i]); - } - return 0; -} diff --git a/146_lru_cache/lru_cache.c b/146_lru_cache/lru_cache.c deleted file mode 100644 index 9d45326..0000000 --- a/146_lru_cache/lru_cache.c +++ /dev/null @@ -1,291 +0,0 @@ -#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_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 hlist_node; - -struct hlist_head { - struct hlist_node *first; -}; - -struct hlist_node { - struct hlist_node *next, **pprev; -}; - -static inline void INIT_HLIST_HEAD(struct hlist_head *h) { - h->first = NULL; -} - -static inline int hlist_empty(struct hlist_head *h) { - return !h->first; -} - -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) -{ - if (h->first != NULL) { - h->first->pprev = &n->next; - } - n->next = h->first; - n->pprev = &h->first; - h->first = n; -} - -static inline void hlist_del(struct hlist_node *n) -{ - struct hlist_node *next = n->next; - struct hlist_node **pprev = n->pprev; - *pprev = next; - if (next != NULL) { - next->pprev = pprev; - } -} - -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; -} - -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) -{ - __list_del(entry); - list_add_tail(entry, head); -} - -typedef struct { - int capacity; - int count; - struct list_head dhead; - struct hlist_head hhead[]; -} LRUCache; - -typedef struct { - int key; - int value; - struct hlist_node node; - struct list_head link; -} LRUNode; - - -LRUCache *lRUCacheCreate(int capacity) -{ - int i; - LRUCache *obj = malloc(2 * sizeof(int) + sizeof(struct list_head) + capacity * sizeof(struct hlist_head)); - obj->count = 0; - obj->capacity = capacity; - INIT_LIST_HEAD(&obj->dhead); - for (i = 0; i < capacity; i++) { - INIT_HLIST_HEAD(&obj->hhead[i]); - } - return obj; -} - -void lRUCacheFree(LRUCache *obj) -{ - struct list_head *pos, *n; - list_for_each_safe(pos, n, &obj->dhead) { - LRUNode *cache = list_entry(pos, LRUNode, link); - list_del(&cache->link); - free(cache); - } - free(obj); -} - -int lRUCacheGet(LRUCache *obj, int key) -{ - int hash = key % obj->capacity; - struct hlist_node *pos; - hlist_for_each(pos, &obj->hhead[hash]) { - LRUNode *cache = list_entry(pos, LRUNode, node); - if (cache->key == key) { - /* Move it to header */ - list_move(&cache->link, &obj->dhead); - return cache->value; - } - } - return -1; -} - -void lRUCachePut(LRUCache *obj, int key, int value) -{ - LRUNode *cache = NULL; - int hash = key % obj->capacity; - struct hlist_node *pos; - hlist_for_each(pos, &obj->hhead[hash]) { - LRUNode *c = list_entry(pos, LRUNode, node); - if (c->key == key) { - list_move(&c->link, &obj->dhead); - cache = c; - } - } - - if (cache == NULL) { - if (obj->count == obj->capacity) { - cache = list_last_entry(&obj->dhead, LRUNode, link); - list_move(&cache->link, &obj->dhead); - hlist_del(&cache->node); - hlist_add_head(&cache->node, &obj->hhead[hash]); - } else { - cache = malloc(sizeof(LRUNode)); - hlist_add_head(&cache->node, &obj->hhead[hash]); - list_add(&cache->link, &obj->dhead); - obj->count++; - } - cache->key = key; - } - cache->value = value; -} - -void lRUCacheDump(LRUCache *obj) -{ - if (obj == NULL) return; - - int i; - LRUNode *cache; - printf(">>> Total %d nodes: \n", obj->count); - for (i = 0; i < obj->count; i++) { - printf("hash:%d:", i); - struct hlist_node *pos; - hlist_for_each(pos, &obj->hhead[i]) { - cache = list_entry(pos, LRUNode, node); - if (cache != NULL) { - printf(" (%d %d)", cache->key, cache->value); - } - } - printf("\n"); - } - - printf(">>> Double list dump\n"); - struct list_head *p; - list_for_each(p, &obj->dhead) { - cache = list_entry(p, LRUNode, link); - printf("(%d %d)\n", cache->key, cache->value); - } -} - -int main(void) -{ - LRUCache *obj; - obj = lRUCacheCreate(2); - printf("put 1, 1\n"); - lRUCachePut(obj, 1, 1); - printf("put 2, 2\n"); - lRUCachePut(obj, 2, 2); - printf("get 1, %d\n", lRUCacheGet(obj, 1)); - printf("put 3, 3\n"); - lRUCachePut(obj, 3, 3); - printf("get 2, %d\n", lRUCacheGet(obj, 2)); - printf("put 4, 4\n"); - lRUCachePut(obj, 4, 4); - printf("get 1, %d\n", lRUCacheGet(obj, 1)); - printf("get 3, %d\n", lRUCacheGet(obj, 3)); - printf("get 4, %d\n", lRUCacheGet(obj, 4)); -//#if 1 -// obj = lRUCacheCreate(2); -// lRUCacheDump(obj); -// printf("get 2, %d\n", lRUCacheGet(obj, 2)); -// printf("put 2, 6\n"); -// lRUCachePut(obj, 2, 6); -// lRUCacheDump(obj); -// printf("get 1, %d\n", lRUCacheGet(obj, 1)); -// printf("put 1, 5\n"); -// lRUCachePut(obj, 1, 5); -// lRUCacheDump(obj); -// printf("put 1, 2\n"); -// lRUCachePut(obj, 1, 2); -// lRUCacheDump(obj); -// printf("get 1, %d\n", lRUCacheGet(obj, 1)); -// printf("get 2, %d\n", lRUCacheGet(obj, 2)); -// lRUCacheFree(obj); -//#else -// obj = lRUCacheCreate(2); -// printf("put 2, 1\n"); -// lRUCachePut(obj, 2, 1); -// printf("put 1, 1\n"); -// lRUCachePut(obj, 1, 1); -// lRUCacheDump(obj); -// printf("get 2, %d\n", lRUCacheGet(obj, 2)); -// lRUCacheDump(obj); -// printf("put 4, 1\n"); -// lRUCachePut(obj, 4, 1); -// lRUCacheDump(obj); -// printf("get 1, %d\n", lRUCacheGet(obj, 1)); -// printf("get 2, %d\n", lRUCacheGet(obj, 2)); -// lRUCacheFree(obj); -//#endif - - return 0; -} diff --git a/190_reverse_bits/reverse_bits.c b/190_reverse_bits/reverse_bits.c deleted file mode 100644 index 5fcf123..0000000 --- a/190_reverse_bits/reverse_bits.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include -#include - -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; -} - -int main(int argc, char **argv) -{ - if (argc != 2) { - fprintf(stderr, "Usage: ./test n\n"); - exit(-1); - } - - printf("%u\n", reverseBits(atoi(argv[1]))); - return 0; -} diff --git a/215_kth_largest_element_in_an_array/kth_elem.c b/215_kth_largest_element_in_an_array/kth_elem.c deleted file mode 100644 index 208050f..0000000 --- a/215_kth_largest_element_in_an_array/kth_elem.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include - -static int compare(const void *a, const void *b) -{ - return *(int *) a - *(int *) b; -} - -int findKthLargest(int* nums, int numsSize, int k) { - qsort(nums, numsSize, sizeof(int), compare); - return nums[numsSize - k]; -} - - -int main(int argc, char **argv) -{ - if (argc < 3) { - fprintf(stderr, "Usage: ./test k n1 n2...\n"); - exit(-1); - } - - int i, count = argc - 2; - int *nums = malloc(count * sizeof(int)); - for (i = 0; i < count; i++) { - nums[i] = atoi(argv[i + 2]); - } - printf("%d\n", findKthLargest(nums, count, atoi(argv[1]))); - return 0; -} diff --git a/224_basic_calculator/calculator.c b/224_basic_calculator/calculator.c deleted file mode 100644 index e4cfac5..0000000 --- a/224_basic_calculator/calculator.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include - -static int calculator(char *s) -{ - int n; - int pos1 = 0; - int pos2 = 0; - int *nums = malloc(1000 * sizeof(int)); - char *signs = malloc(1000 * sizeof(char)); - - 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--; - - if (pos1 >= 2 && signs[pos2 - 1] != '(' && signs[pos2 - 1] != '(') { - int a = nums[--pos1]; - if (signs[--pos2] == '+') { - n = a + n; - } else { - n = a - n; - } - } - nums[pos1++] = n; - break; - } - s++; - } - - return n; -} - -int main(int argc, char **argv) -{ - if (argc != 2) { - fprintf(stderr, "Usage: ./test string\n"); - exit(-1); - } - printf("%d\n", calculator(argv[1])); - return 0; -} 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.