diff --git a/0001_two_sum/Makefile b/0001_two_sum/Makefile new file mode 100644 index 0000000..e896cb5 --- /dev/null +++ b/0001_two_sum/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test two_sum.c diff --git a/0001_two_sum/two_sum.c b/0001_two_sum/two_sum.c new file mode 100644 index 0000000..6a701ea --- /dev/null +++ b/0001_two_sum/two_sum.c @@ -0,0 +1,62 @@ +#include +#include + + +struct object { + int val; + int index; +}; + +static int compare(const void *a, const void *b) +{ + return ((struct object *) a)->val - ((struct object *) b)->val; +} + +int * twosum(int *nums, int numsSize, int target, int *returnSize) +{ + int i, j; + struct object *objs = malloc(numsSize * sizeof(*objs)); + for (i = 0; i < numsSize; i++) { + objs[i].val = nums[i]; + objs[i].index = i; + } + qsort(objs, numsSize, sizeof(*objs), compare); + + int *results = malloc(2 * sizeof(int)); + i = 0; + j = numsSize - 1; + while (i < j) { + int sum = objs[i].val + objs[j].val; + if (sum < target) { + i++; + } else if (sum > target) { + j--; + } else { + results[0] = objs[i].index; + results[1] = objs[j].index; + *returnSize = 2; + return results; + } + } + return NULL; +} + +int main(void) +{ + //int nums[] = {-1, -2, -3, -4, -5}; + //int target = -8; + //int nums[] = {0,4,3,0}; + //int target = 0; + int nums[] = { 3, 2, 3 }; + int size = sizeof(nums) / sizeof(*nums); + int target = 6; + int count = 0; + int *indexes = twosum(nums, size, target, &count); + if (indexes != NULL) { + printf("%d %d\n", indexes[0], indexes[1]); + } else { + printf("Not found\n"); + } + + return 0; +} diff --git a/0001_two_sum/two_sum.cc b/0001_two_sum/two_sum.cc new file mode 100644 index 0000000..7dca0f0 --- /dev/null +++ b/0001_two_sum/two_sum.cc @@ -0,0 +1,22 @@ +#include + +using namespace std; + +class Solution { +public: + vector twoSum(vector& nums, int target) { + vector res; + unordered_map ht; + for (int i = 0; i < nums.size(); i++) { + int other = target - nums[i]; + if (ht.count(other)) { + /* Only one solution for purpose of this problem */ + res.append(ht[other]); + res.append(i); + return res; + } + ht[nums[i]] = i; + } + return res; + } +}; diff --git a/0002_add_two_numbers/Makefile b/0002_add_two_numbers/Makefile new file mode 100644 index 0000000..f5dfb55 --- /dev/null +++ b/0002_add_two_numbers/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test add_two_numbers.c diff --git a/002_add_two_numbers/add_two_numbers.c b/0002_add_two_numbers/add_two_numbers.c similarity index 69% rename from 002_add_two_numbers/add_two_numbers.c rename to 0002_add_two_numbers/add_two_numbers.c index 3c5e2a2..2dd91d5 100644 --- a/002_add_two_numbers/add_two_numbers.c +++ b/0002_add_two_numbers/add_two_numbers.c @@ -2,55 +2,53 @@ #include #include + /* Definition for singly-linked list. */ struct ListNode { int val; struct ListNode *next; }; -struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) { - int carry_num = 0; - int first = 1; - struct ListNode *res = NULL; - struct ListNode *p = NULL; - struct ListNode *prev = p; +struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) +{ + int carry = 0; + struct ListNode dummy; + struct ListNode *p = l1, *prev = &dummy; - while (l1 != NULL || l2 != NULL || carry_num) { + dummy.next = p; + while (l1 != NULL || l2 != NULL) { int sum = 0; - int last_carry = carry_num; + if (l1 != NULL) { sum += l1->val; l1 = l1->next; } + if (l2 != NULL) { + if (p == NULL) { + /* l2 longer than l1 */ + prev->next = l2; + p = l2; + } sum += l2->val; l2 = l2->next; } - if (sum >= 10) { - sum -= 10; - carry_num = 1; - } else { - carry_num = 0; - } - p = malloc(sizeof(*p)); - if (first) { - res = p; - first = 0; - } - p->val = sum + last_carry; - if (p->val >= 10) { - p->val -= 10; - carry_num = 1; - } - p->next = NULL; - if (prev != NULL) { - prev->next = p; - } + sum += carry; + carry = sum / 10; + p->val = sum % 10; prev = p; + p = p->next; } - return res; + if (carry) { + p = malloc(sizeof(*p)); + p->val = carry; + p->next = NULL; + prev->next = p; + } + + return dummy.next; } static struct ListNode *node_build(const char *digits) @@ -90,6 +88,11 @@ static void show(struct ListNode *ln) int main(int argc, char **argv) { + if (argc < 3) { + fprintf(stderr, "Usage: ./test n1 n2\n"); + exit(-1); + } + struct ListNode *l1 = node_build(argv[1]); struct ListNode *l2 = node_build(argv[2]); struct ListNode *res = addTwoNumbers(l1, l2); diff --git a/0002_add_two_numbers/add_two_numbers.cc b/0002_add_two_numbers/add_two_numbers.cc new file mode 100644 index 0000000..192e3e5 --- /dev/null +++ b/0002_add_two_numbers/add_two_numbers.cc @@ -0,0 +1,55 @@ +#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* addTwoNumbers(ListNode* l1, ListNode* l2) { + int carry = 0; + struct ListNode dummy; + struct ListNode *p = l1, *prev = &dummy; + + dummy.next = p; + while (l1 != nullptr || l2 != nullptr) { + int sum = 0; + + if (l1 != nullptr) { + sum += l1->val; + l1 = l1->next; + } + + if (l2 != nullptr) { + if (p == nullptr) { + /* l2 longer than l1 */ + prev->next = l2; + p = l2; + } + sum += l2->val; + l2 = l2->next; + } + + sum += carry; + carry = sum / 10; + p->val = sum % 10; + prev = p; + p = p->next; + } + + if (carry) { + p = new ListNode(carry); + prev->next = p; + } + + return dummy.next; + } +}; diff --git a/0003_longest_substring_without_repeat/Makefile b/0003_longest_substring_without_repeat/Makefile new file mode 100644 index 0000000..984d74e --- /dev/null +++ b/0003_longest_substring_without_repeat/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test longest_substring_without_repeat.c 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/0004_median_of_two_sorted_array/Makefile b/0004_median_of_two_sorted_array/Makefile new file mode 100644 index 0000000..7f15f60 --- /dev/null +++ b/0004_median_of_two_sorted_array/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test median_of_two_sorted_array.c 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 61% 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 index 4f614a2..d1472f7 100644 --- 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 @@ -1,37 +1,27 @@ #include #include -static double find_kth(int a[], int m, int b[], int n, int k) -{ - /* Always assume that m is equal or smaller than n */ - if (m > n) { - return find_kth(b, n, a, m, k); - } - if (m == 0) { - return b[k - 1]; - } - if (k == 1) { - return a[0] < b[0] ? a[0] : b[0]; - } - - /* Divide k into two parts */ - int i = k / 2 < m ? k / 2 : m; - int j = k - i; - if (a[i - 1] < b[j - 1]) { - return find_kth(a + i, m - i, b, n, k - i); - } else if (a[i - 1] > b[j - 1]) { - return find_kth(a, m, b + j, n - j, k - j); - } else { - return a[i - 1]; +static double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) +{ + int sum = nums1Size + nums2Size; + int *nums = malloc(sizeof(int) * sum); + int i = 0, j = 0, k = 0; + int half = sum / 2 + 1; + while (k < half) { + int n; + if (i < nums1Size && j < nums2Size) { + n = (nums1[i] < nums2[j]) ? nums1[i++] : nums2[j++]; + } else if (i < nums1Size) { + n = nums1[i++]; + } else if (j < nums2Size) { + n = nums2[j++]; + } + nums[k++] = n; } -} - -double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { - int half = (nums1Size + nums2Size) / 2; - if ((nums1Size + nums2Size) & 0x1) { - return find_kth(nums1, nums1Size, nums2, nums2Size, half + 1); + if (sum % 2) { + return nums[k-1]; } else { - return (find_kth(nums1, nums1Size, nums2, nums2Size, half) + find_kth(nums1, nums1Size, nums2, nums2Size, half + 1)) / 2; + return (nums[k-1] + nums[k-2]) / 2.0; } } diff --git a/0004_median_of_two_sorted_array/median_of_two_sorted_array.cc b/0004_median_of_two_sorted_array/median_of_two_sorted_array.cc new file mode 100644 index 0000000..a5b46f2 --- /dev/null +++ b/0004_median_of_two_sorted_array/median_of_two_sorted_array.cc @@ -0,0 +1,30 @@ +#include + +using namespace std; + +class Solution { +public: + double findMedianSortedArrays(vector& nums1, vector& nums2) { + int sum = nums1.size() + nums2.size(); + vector nums; + int i = 0, j = 0, k; + int half = sum / 2 + 1; + for (k = 0; k < half; k++) { + int n; + if (i < nums1.size() && j < nums2.size()) { + n = (nums1[i] < nums2[j]) ? nums1[i++] : nums2[j++]; + } else if (i < nums1.size()) { + n = nums1[i++]; + } else if (j < nums2.size()) { + n = nums2[j++]; + } + nums.push_back(n); + } + + if (sum % 2) { + return nums[k-1]; + } else { + return (nums[k-1] + nums[k-2]) / 2.0; + } + } +}; diff --git a/0005_longest_palindromic_substring/Makefile b/0005_longest_palindromic_substring/Makefile new file mode 100644 index 0000000..4fe893e --- /dev/null +++ b/0005_longest_palindromic_substring/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test longest_palindromic_substring.c diff --git a/0005_longest_palindromic_substring/longest_palindromic_substring.c b/0005_longest_palindromic_substring/longest_palindromic_substring.c new file mode 100644 index 0000000..9a9b2a7 --- /dev/null +++ b/0005_longest_palindromic_substring/longest_palindromic_substring.c @@ -0,0 +1,86 @@ +#include +#include +#include + +static inline int min(int a, int b) +{ + return a < b ? a : b; +} + +static int manacher(char *s, char output[]) +{ + int i, j; + char s2[3000] = { '\0' }; + + s2[0] = '$'; + for (i = 0; s[i] != '\0'; i++) { + s2[(i<<1)+1] = '#'; + s2[(i<<1)+2] = s[i]; + } + s2[(i<<1)+1] = '#'; + int len = (i<<1)+2; + s2[len] = '\0'; + + int p[3000] = { 0 }; // 以s2中某一点为中心的回文半径 + int id = 0; // 回文的中心点 + int limit = 0; // 最长回文的右边界点 + int maxLen = 0; // 最大回文长度 + int maxId = 0; // 最长回文的中心点 + for (i = 1; i < len; i++) { + if (i < limit) { + p[i] = min(p[2*id-i], limit-i); + } else { + p[i] = 1; + } + + while (s2[i+p[i]] == s2[i-p[i]]) { + p[i]++; + } + + if (i+p[i] > limit) { + limit = i+p[i]; + id = i; + } + if (maxLen < p[i]-1) { + maxLen = p[i]-1; + maxId = i; + } + } + + for (j = 0, i = maxId - maxLen; i <= maxId+maxLen; i++) { + if (s2[i] != '#') { + output[j++] = s2[i]; + } + } + return maxLen; +} + +static char *longestPalindrom(char *s) +{ + int i; + if (s == NULL) { + return NULL; + } + + int len = strlen(s); + if (len <= 1) { + return s; + } + + char *palindrome = malloc(2000); + memset(palindrome, 0, sizeof(palindrome)); + + int size = manacher(s, palindrome); + palindrome[size] = '\0'; + return palindrome; +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test string\n"); + exit(-1); + } + printf("%s\n", longestPalindrom(argv[1])); + return 0; +} 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 char* convert(char* s, int numRows) { +static char* convert(char* s, int numRows) +{ if (numRows <= 1) return s; int len = strlen(s); diff --git a/0006_zigzag_conversion/zigzag_conversion.cc b/0006_zigzag_conversion/zigzag_conversion.cc new file mode 100644 index 0000000..5ee1887 --- /dev/null +++ b/0006_zigzag_conversion/zigzag_conversion.cc @@ -0,0 +1,29 @@ +#include + +using namespace std; + +class Solution { +public: + string convert(string s, int numRows) { + if (numRows <= 1) { + return s; + } + + string new_s; + for (int row = 0; row < numRows; row++) { + int delta; + int interval1 = numRows + (numRows - 2) - row * 2; + int interval2 = 2 * row; + bool flag = false; + for (int i = row; i < s.length(); i += delta) { + new_s.push_back(s[i]); + do { + delta = !flag ? interval1 : interval2; + flag = !flag; + } while (delta == 0); + } + } + + return new_str; + } +}; diff --git a/0007_reverse_integer/Makefile b/0007_reverse_integer/Makefile new file mode 100644 index 0000000..100f5b9 --- /dev/null +++ b/0007_reverse_integer/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test reverse_integer.c diff --git a/007_reverse_integer/reverse_integer.c b/0007_reverse_integer/reverse_integer.c similarity index 76% rename from 007_reverse_integer/reverse_integer.c rename to 0007_reverse_integer/reverse_integer.c index 07a3b69..a319c5b 100644 --- a/007_reverse_integer/reverse_integer.c +++ b/0007_reverse_integer/reverse_integer.c @@ -2,20 +2,24 @@ #include #include + static int reverse(int x) { - int y = 0; + int n = 0; while (x != 0) { - int n = x % 10; - // Checking the over/underflow. - // Actually, it should be y>(INT_MAX-n)/10, but n/10 is 0, so omit it. - if (y > INT_MAX / 10 || y < INT_MIN / 10) { + int r = x % 10; + /* Checking the over/underflow. */ + if (n > INT_MAX / 10 || (n == INT_MAX / 10 && r > 7)) { + return 0; + } + if (n < INT_MIN / 10 || (n == INT_MIN / 10 && r < -8)) { return 0; } - y = y * 10 + n; + + n = n * 10 + r; x /= 10; } - return y; + return n; } #define TEST(n, e) printf("%12d => %-12d %s!\n", n, reverse(n), e == reverse(n)?"passed":"failed") diff --git a/0007_reverse_integer/reverse_integer.cc b/0007_reverse_integer/reverse_integer.cc new file mode 100644 index 0000000..3ed2273 --- /dev/null +++ b/0007_reverse_integer/reverse_integer.cc @@ -0,0 +1,24 @@ +#include + +using namespace std; + +class Solution { +public: + int reverse(int x) { + int n = 0; + while (x != 0) { + // Checking the over/underflow. + int r = x % 10; + if (n > INT_MAX / 10 || (n == INT_MAX / 10 && r > 7)) { + return 0; + } + if (n < INT_MIN / 10 || (n == INT_MIN / 10 && r < -8)) { + return 0; + } + + n = n * 10 + r; + x = x / 10; + } + return n; + } +}; diff --git a/0008_atoi/Makefile b/0008_atoi/Makefile new file mode 100644 index 0000000..c401790 --- /dev/null +++ b/0008_atoi/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test atoi.c diff --git a/0008_atoi/atoi.c b/0008_atoi/atoi.c new file mode 100644 index 0000000..c57769b --- /dev/null +++ b/0008_atoi/atoi.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include + + +static int myAtoi(char* str) +{ + char *s; + long n = 0; + int sign = 0; + + while (*str == ' ' || *str == '\t') { + str++; + } + + if (*str == '-') { + if (isdigit(*++str)) { + sign = 1; + } else { + return 0; + } + } + + if (*str == '+') { + if (isdigit(*++str)) { + sign = 0; + } else { + return 0; + } + } + + for (s = str; *s != '\0'; s++) { + if (isdigit(*s)) { + int d = *s - '0'; + if (sign) { + if (-n < (INT_MIN + d) / 10) { + n = INT_MIN; + break; + } + } else { + if (n > (INT_MAX - d) / 10) { + n = INT_MAX; + break; + } + } + n = n * 10 + d; + } else { + break; + } + } + + return sign ? -n : n; +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + printf("Usage: ./atoi 123\n"); + exit(-1); + } + + int n = myAtoi(argv[1]); + printf("n = %d %x\n", n, n); + + return 0; +} diff --git a/0008_atoi/atoi.cc b/0008_atoi/atoi.cc new file mode 100644 index 0000000..002fab8 --- /dev/null +++ b/0008_atoi/atoi.cc @@ -0,0 +1,55 @@ +#include + +using namespace std; + +class Solution { +public: + int myAtoi(string str) { + long n = 0; + int i, sign = 0; + + for (i = 0; i < str.length(); i++) { + if (str[i] != ' ' && str[i] != '\t') { + break; + } + } + + if (str[i] == '-') { + if (isdigit(str[++i])) { + sign = 1; + } else { + return 0; + } + } + + if (str[i] == '+') { + if (isdigit(str[++i])) { + sign = 0; + } else { + return 0; + } + } + + for (; i < str.length(); i++) { + if (isdigit(str[i])) { + int d = str[i] - '0'; + if (sign) { + if (-n < (INT_MIN + d) / 10) { + n = INT_MIN; + break; + } + } else { + if (n > (INT_MAX - d) / 10) { + n = INT_MAX; + break; + } + } + n = n * 10 + d; + } else { + break; + } + } + + return sign ? -n : n; + } +}; diff --git a/0009_palindrome_number/Makefile b/0009_palindrome_number/Makefile new file mode 100644 index 0000000..b8ce0a3 --- /dev/null +++ b/0009_palindrome_number/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test palindrome_number.c diff --git a/009_palindrome_number/palindrome_number.c b/0009_palindrome_number/palindrome_number.c similarity index 54% rename from 009_palindrome_number/palindrome_number.c rename to 0009_palindrome_number/palindrome_number.c index 4b8d801..c870b2b 100644 --- a/009_palindrome_number/palindrome_number.c +++ b/0009_palindrome_number/palindrome_number.c @@ -2,17 +2,27 @@ #include #include + static int reverse(int x) { - int y = 0; - while (x) { - y = y * 10 + x % 10; + int n = 0; + while (x != 0) { + int r = x % 10; + /* Checking the over/underflow. */ + if (n > INT_MAX / 10 || (n == INT_MAX / 10 && r > 7)) { + return 0; + } + if (n < INT_MIN / 10 || (n == INT_MIN / 10 && r < -8)) { + return 0; + } + n = n * 10 + r; x /= 10; } - return y; + return n; } -static bool isPalindrome(int x) { +static bool isPalindrome(int x) +{ if (x == 0) { return true; } diff --git a/0009_palindrome_number/palindrome_number.cc b/0009_palindrome_number/palindrome_number.cc new file mode 100644 index 0000000..e6b77a5 --- /dev/null +++ b/0009_palindrome_number/palindrome_number.cc @@ -0,0 +1,35 @@ +#include + +using namespace std; + +class Solution { +public: + bool isPalindrome(int x) { + if (x == 0) { + return true; + } + if (x < 0) { + return false; + } + return x == reverse(x); + } + +private: + int reverse(int x) { + int n = 0; + while (x != 0) { + // Checking the over/underflow. + int r = x % 10; + if (n > INT_MAX / 10 || (n == INT_MAX / 10 && r > 7)) { + return 0; + } + if (n < INT_MIN / 10 || (n == INT_MIN / 10 && r < -8)) { + return 0; + } + + n = n * 10 + r; + x = x / 10; + } + return n; + } +}; diff --git a/0010_regular_expression_matching/Makefile b/0010_regular_expression_matching/Makefile new file mode 100644 index 0000000..1f5279e --- /dev/null +++ b/0010_regular_expression_matching/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test regular_expression.c diff --git a/0010_regular_expression_matching/regular_expression.c b/0010_regular_expression_matching/regular_expression.c new file mode 100644 index 0000000..c736041 --- /dev/null +++ b/0010_regular_expression_matching/regular_expression.c @@ -0,0 +1,30 @@ +#include +#include +#include + + +static bool isMatch(char *s, char *p) +{ + if (*p == '\0') { + return *s == '\0'; + } + + bool first_match = (*s != '\0') && (*s == *p || *p == '.'); + + if (p[1] == '*') { + return isMatch(s, p + 2) || (first_match && isMatch(s + 1, p)); + } else { + return first_match && isMatch(s + 1, p + 1); + } +} + +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/0010_regular_expression_matching/regular_expression.cc b/0010_regular_expression_matching/regular_expression.cc new file mode 100644 index 0000000..45ab1c0 --- /dev/null +++ b/0010_regular_expression_matching/regular_expression.cc @@ -0,0 +1,30 @@ +#include + +using namespace std; + +class Solution { +public: + /* recursive version too slow thanks to substr() */ + bool isMatch(string s, string p) { + vector> dp(s.size() + 1, vector(p.size() + 1, false)); + dp[0][0] = true; + for (int i = 1; i <= p.length(); i++) { + dp[0][i] = p[0][i - 1] == '*' && i >= 2 && dp[0][i - 2]; + } + + for (int i = 1; i <= s.length(); i++) { + for (int j = 1; j <= p.length(); j++) { + bool match; + if (j >= 2 && p[j - 1] == '*') { + match = (s[i - 1] == p[j - 2] || p[j - 2] == '.'); + dp[i][j] = dp[i][j - 2] || (match && dp[i - 1][j]); + } else { + match = (s[i - 1] == p[j - 1] || p[j - 1] == '.'); + dp[i][j] = match && dp[i - 1][j - 1]; + } + } + } + + return dp[s.size()][p.size()]; + } +}; diff --git a/0011_container_with_most_water/Makefile b/0011_container_with_most_water/Makefile new file mode 100644 index 0000000..f262392 --- /dev/null +++ b/0011_container_with_most_water/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test container.c diff --git a/011_container_with_most_water/container.c b/0011_container_with_most_water/container.c similarity index 75% rename from 011_container_with_most_water/container.c rename to 0011_container_with_most_water/container.c index 2534ab3..22d667e 100644 --- a/011_container_with_most_water/container.c +++ b/0011_container_with_most_water/container.c @@ -9,13 +9,9 @@ static int maxArea(int* height, int heightSize) int area = (max - min) * (height[min] < height[max] ? height[min] : height[max]); area_max = area > area_max ? area : area_max; if (height[min] < height[max]) { - while (++min < max && height[min] <= height[min - 1]) { - continue; - } + min++; } else { - while (min < --max && height[max] <= height[max + 1]) { - continue; - } + max--; } } return area_max; diff --git a/0011_container_with_most_water/container.cc b/0011_container_with_most_water/container.cc new file mode 100644 index 0000000..480e6df --- /dev/null +++ b/0011_container_with_most_water/container.cc @@ -0,0 +1,21 @@ +#include + +using namespace std; + +class Solution { +public: + int maxArea(vector& height) { + int min = 0, max = height.size() - 1; + int area_max = 0; + while (min < max) { + int area = (max - min) * (height[min] < height[max] ? height[min] : height[max]); + area_max = area > area_max ? area : area_max; + if (height[min] < height[max]) { + min++; + } else { + max--; + } + } + return area_max; + } +}; diff --git a/0012_roman_numeral/Makefile b/0012_roman_numeral/Makefile new file mode 100644 index 0000000..f27ed8d --- /dev/null +++ b/0012_roman_numeral/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o roman_numeral roman_numeral.c diff --git a/012_roman_numeral/roman_numeral.c b/0012_roman_numeral/roman_numeral.c similarity index 90% rename from 012_roman_numeral/roman_numeral.c rename to 0012_roman_numeral/roman_numeral.c index 8a632e8..b66c249 100644 --- a/012_roman_numeral/roman_numeral.c +++ b/0012_roman_numeral/roman_numeral.c @@ -2,7 +2,8 @@ #include #include -static void num2char(char **num, int bit, int n) { +static void num2char(char **num, int bit, int n) +{ int i; char low, mid, high; char *p = *num; @@ -59,17 +60,16 @@ static void num2char(char **num, int bit, int n) { *num = p; } -static char roman_numeral[64]; +static char roman_numeral[64] = { '\0' }; -static char *intToRoman(int num) { +static char *intToRoman(int num) +{ + int i; char *p = &roman_numeral[0]; int thousand_bit = num / 1000; int hundred_bit = (num % 1000) / 100; int ten_bit = (num % 100) / 10; int one_bit = num % 10; - int i; - - memset(roman_numeral, 0, sizeof(roman_numeral)); if (thousand_bit > 0) { if (thousand_bit < 4) { @@ -82,7 +82,8 @@ static char *intToRoman(int num) { num2char(&p, hundred_bit, 2); num2char(&p, ten_bit, 1); num2char(&p, one_bit, 0); - + *p = '\0'; + return roman_numeral; } diff --git a/0012_roman_numeral/roman_numeral.cc b/0012_roman_numeral/roman_numeral.cc new file mode 100644 index 0000000..8b97a6f --- /dev/null +++ b/0012_roman_numeral/roman_numeral.cc @@ -0,0 +1,82 @@ +#include + +using namespace std; + +class Solution { +public: + string intToRoman(int num) { + int thousand_bit = num / 1000; + int hundred_bit = (num % 1000) / 100; + int ten_bit = (num % 100) / 10; + int one_bit = num % 10; + + if (thousand_bit > 0) { + if (thousand_bit < 4) { + for (int i = 0; i < thousand_bit; i++) { + roman_numeral.push_back('M'); + } + } + } + + num2char(hundred_bit, 2); + num2char(ten_bit, 1); + num2char(one_bit, 0); + + return roman_numeral; + } + +private: + string roman_numeral; + void num2char(int bit, int n) { + char low, mid, high; + + switch (n) { + case 2: + low = 'C'; + mid = 'D'; + high = 'M'; + break; + case 1: + low = 'X'; + mid = 'L'; + high = 'C'; + break; + case 0: + low = 'I'; + mid = 'V'; + high = 'X'; + break; + } + + if (bit > 0) { + switch (bit) { + case 1: + case 2: + case 3: + for (int i = 0; i < bit; i++) { + roman_numeral.push_back(low); + } + break; + case 4: + roman_numeral.push_back(low); + roman_numeral.push_back(mid); + break; + case 5: + roman_numeral.push_back(mid); + break; + case 6: + case 7: + case 8: + roman_numeral.push_back(mid); + for (int i = 5; i < bit; i++) { + roman_numeral.push_back(low); + } + break; + case 9: + roman_numeral.push_back(low); + roman_numeral.push_back(high); + break; + } + } + } +}; diff --git a/0013_roman_to_integer/Makefile b/0013_roman_to_integer/Makefile new file mode 100644 index 0000000..48e0ed0 --- /dev/null +++ b/0013_roman_to_integer/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test roman_to_integer.c diff --git a/013_roman_to_integer/roman_to_integer.c b/0013_roman_to_integer/roman_to_integer.c similarity index 71% rename from 013_roman_to_integer/roman_to_integer.c rename to 0013_roman_to_integer/roman_to_integer.c index d7899c3..3432213 100644 --- a/013_roman_to_integer/roman_to_integer.c +++ b/0013_roman_to_integer/roman_to_integer.c @@ -19,19 +19,21 @@ static int roman_to_integer(char c) case 'M': return 1000; default: - return; + return 0; } } -int romanToInt (char *s) { - int i, result = roman_to_integer(s[0]); +int romanToInt (char *s) +{ + int i, curr = roman_to_integer(s[0]); + int result = curr; for (i = 1; s[i] != '\0'; i++) { - int prev = roman_to_integer(s[i - 1]); - int curr = roman_to_integer(s[i]); - //if left + +using namespace std; + +class Solution { +public: + int romanToInt(string s) { + int curr = roman_to_integer(s[0]); + int result = curr; + + for (int i = 1; i < s.length(); i++) { + int prev = curr; + curr = roman_to_integer(s[i]); + /* left < right : IV(4), XL(40), IX(9) ... */ + if (prev < curr) { + result -= prev - (curr - prev); + } else { + result += curr; + } + } + + return result; + } + +private: + int roman_to_integer(char c) { + switch(c) { + case 'I': + return 1; + case 'V': + return 5; + case 'X': + return 10; + case 'L': + return 50; + case 'C': + return 100; + case 'D': + return 500; + case 'M': + return 1000; + default: + return 0; + } + } +}; diff --git a/0014_longest_common_prefix/Makefile b/0014_longest_common_prefix/Makefile new file mode 100644 index 0000000..dd6aa66 --- /dev/null +++ b/0014_longest_common_prefix/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test common_prefix.c diff --git a/0014_longest_common_prefix/common_prefix.c b/0014_longest_common_prefix/common_prefix.c new file mode 100644 index 0000000..b5e5bbc --- /dev/null +++ b/0014_longest_common_prefix/common_prefix.c @@ -0,0 +1,36 @@ +#include +#include +#include + + +static char* longestCommonPrefix(char** strs, int strsSize) +{ + if (strsSize == 0) { + return ""; + } + + int i, count = 0; + char *result = malloc(1000); + while (strs[0][count] != '\0') { + char c = strs[0][count]; + for (i = 1; i < strsSize; i++) { + if (c != strs[i][count]) { + break; + } + } + + if (i == strsSize) { + result[count++] = c; + } else { + break; + } + } + result[count++] = '\0'; + return result; +} + +int main(int argc, char **argv) +{ + printf("%s\n", longestCommonPrefix(argv + 1, argc - 1)); + return 0; +} diff --git a/0014_longest_common_prefix/common_prefix.cc b/0014_longest_common_prefix/common_prefix.cc new file mode 100644 index 0000000..399c991 --- /dev/null +++ b/0014_longest_common_prefix/common_prefix.cc @@ -0,0 +1,23 @@ +#include + +using namespace std; + +class Solution { +public: + string longestCommonPrefix(vector& strs) { + string lcp; + if (strs.empty()) { + return lcp; + } + for (int j = 0; j < strs[0].length(); j++) { + char c = strs[0][j]; + for (int i = 1; i < strs.size(); i++) { + if (c != strs[i][j]) { + return lcp; + } + } + lcp.push_back(c); + } + return lcp; + } +}; diff --git a/0015_three_sum/Makefile b/0015_three_sum/Makefile new file mode 100644 index 0000000..fb5e2bb --- /dev/null +++ b/0015_three_sum/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test three_sum.c diff --git a/015_three_sum/three_sum.c b/0015_three_sum/three_sum.c similarity index 57% rename from 015_three_sum/three_sum.c rename to 0015_three_sum/three_sum.c index 0962842..5b096c1 100644 --- a/015_three_sum/three_sum.c +++ b/0015_three_sum/three_sum.c @@ -1,26 +1,20 @@ #include #include -static void insert_sort(int *nums, int len) + +static int compare(const void *a, const void *b) { - int i, j; - for (i = 1; i < len; i++) { - int tmp = nums[i]; - for (j = i - 1; j >= 0 && nums[j] > tmp; j--) { - nums[j + 1] = nums[j]; - } - nums[j + 1] = tmp; - } + return *(int *) a - *(int *) b; } static void two_sum(int *nums, int low, int high, int target, int **results, int *count) { while (low < high) { - int diff = target - nums[low]; - if (diff > nums[high]) { - while (++low < high && nums[low] == nums[low - 1]) {} - } else if (diff < nums[high]) { - while (--high > low && nums[high] == nums[high + 1]) {} + int sum = nums[low] + nums[high]; + if (sum < target) { + low++; + } else if (sum > target) { + high--; } else { results[*count] = malloc(3 * sizeof(int)); results[*count][0] = -target; @@ -37,33 +31,45 @@ 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; } - insert_sort(nums, numsSize); - int i, j, count = 0, capacity = 50000; + qsort(nums, numsSize, sizeof(*nums), compare); + + *returnSize = 0; + int i, j, capacity = 50000; int **results = malloc(capacity * sizeof(int *)); - for (i = 0; i < numsSize; i++) { - if (i == 0 || i > 0 && nums[i] != nums[i - 1]) { - two_sum(nums, i + 1, numsSize - 1, -nums[i], results, &count); + for (i = 0; i < numsSize - 2; i++) { + if (i == 0 || (i > 0 && nums[i] != nums[i - 1])) { + two_sum(nums, i + 1, numsSize - 1, -nums[i], results, returnSize); } } - *returnSize = count; + + *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/0015_three_sum/three_sum.cc b/0015_three_sum/three_sum.cc new file mode 100644 index 0000000..6cd5550 --- /dev/null +++ b/0015_three_sum/three_sum.cc @@ -0,0 +1,34 @@ +#include + +using namespace std; + +class Solution { +public: + vector> threeSum(vector& nums) { + vector> res; + if (nums.size() >= 3) { + sort(nums.begin(), nums.end()); + for (int i = 0; i < nums.size() - 2; i++) { + if (i > 0 && nums[i - 1] == nums[i]) { continue; } + twoSum(nums.begin() + i + 1, nums.end() - 1, -nums[i], res); + } + } + return res; + } + +private: + void twoSum(vector::iterator lo, vector::iterator hi, int target, vector>& res) { + while (lo < hi) { + int sum = *lo + *hi; + if (sum < target) { + lo++; + } else if (sum > target) { + hi--; + } else { + res.push_back(vector {-target, *lo, *hi}); + while (++lo < hi && *lo == *(lo - 1)) {} + while (lo < hi-- && *hi == *(hi + 1)) {} + } + } + } +}; diff --git a/0016_three_sum_closest/Makefile b/0016_three_sum_closest/Makefile new file mode 100644 index 0000000..71f9b43 --- /dev/null +++ b/0016_three_sum_closest/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test three_sum_closest.c -lm diff --git a/016_three_sum_closest/three_sum_closest.c b/0016_three_sum_closest/three_sum_closest.c similarity index 70% rename from 016_three_sum_closest/three_sum_closest.c rename to 0016_three_sum_closest/three_sum_closest.c index f27f231..ae0eb6c 100644 --- a/016_three_sum_closest/three_sum_closest.c +++ b/0016_three_sum_closest/three_sum_closest.c @@ -3,26 +3,20 @@ #include #include -static void insert_sort(int *a, int size) +static int compare(const void *a, const void *b) { - int i, j; - for (i = 1; i < size; i++) { - int tmp = a[i]; - for (j = i - 1; j >= 0 && a[j] > tmp; j--) { - a[j + 1] = a[j]; - } - a[j + 1] = tmp; - } + return *(int *) a - *(int *) b; } -static int threeSumClosest(int* nums, int numsSize, int target) { +static int threeSumClosest(int* nums, int numsSize, int target) +{ int i, min_diff = INT_MAX; if (numsSize < 3) { return min_diff; } - insert_sort(nums, numsSize); + qsort(nums, numsSize, sizeof(*nums), compare); for (i = 0; i < numsSize - 2; i++) { int left = i + 1; @@ -37,7 +31,7 @@ static int threeSumClosest(int* nums, int numsSize, int target) { } else if (diff > 0) { right--; } else { - break; + return target; } } } diff --git a/0016_three_sum_closest/three_sum_closest.cc b/0016_three_sum_closest/three_sum_closest.cc new file mode 100644 index 0000000..6f1299c --- /dev/null +++ b/0016_three_sum_closest/three_sum_closest.cc @@ -0,0 +1,37 @@ +#include + +using namespace std; + +class Solution { +public: + int threeSumClosest(vector& nums, int target) { + if (nums.size() < 3) { + return INT_MAX; + } + + int min_diff = INT_MAX; + sort(nums.begin(), nums.end()); + + for (int i = 0; i < nums.size() - 2; i++) { + if (i > 0 && nums[i - 1] == nums[i]) { continue; } + + int lo = i + 1; + int hi = nums.size() - 1; + while (lo < hi) { + int diff = nums[i] + nums[lo] + nums[hi] - target; + if (abs(diff) < abs(min_diff)) { + min_diff = diff; + } + if (diff < 0) { + lo++; + } else if (diff > 0) { + hi--; + } else { + return target; + } + } + } + + return min_diff + target; + } +}; diff --git a/0017_letter_combinations_of_a_phone_number/Makefile b/0017_letter_combinations_of_a_phone_number/Makefile new file mode 100644 index 0000000..8b9d35d --- /dev/null +++ b/0017_letter_combinations_of_a_phone_number/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o letter_combinations letter_combinations.c 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 71% rename from 017_letter_combinations_of_a_phone_number/letter_combinations.c rename to 0017_letter_combinations_of_a_phone_number/letter_combinations.c index 359c33a..2104923 100644 --- a/017_letter_combinations_of_a_phone_number/letter_combinations.c +++ b/0017_letter_combinations_of_a_phone_number/letter_combinations.c @@ -6,35 +6,15 @@ ** Return an array of size *returnSize. ** Note: The returned array must be malloced, assume caller calls free(). **/ -char** letterCombinations(char* digits, int* returnSize) { - char *letter_matrix[10]; - letter_matrix[0] = ""; - letter_matrix[1] = " "; - letter_matrix[2] = "abc"; - letter_matrix[3] = "def"; - letter_matrix[4] = "ghi"; - letter_matrix[5] = "jkl"; - letter_matrix[6] = "mno"; - letter_matrix[7] = "pqrs"; - letter_matrix[8] = "tuv"; - letter_matrix[9] = "wxyz"; - - int letter_length[10]; - letter_length[0] = 0; - letter_length[1] = 1; - letter_length[2] = 3; - letter_length[3] = 3; - letter_length[4] = 3; - letter_length[5] = 3; - letter_length[6] = 3; - letter_length[7] = 4; - letter_length[8] = 3; - letter_length[9] = 4; - +static char** letterCombinations(char* digits, int* returnSize) +{ int i, j, k; int empty = 1; int count = 1; int digit_len = strlen(digits); + char *letter_matrix[10] = {"", " ", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz", }; + int letter_length[10] = {0, 1, 3, 3, 3, 3, 3, 4, 3, 4, }; + for (i = 0; i < digit_len; i++) { int index = digits[i] - '0'; if (letter_length[index] > 0) { diff --git a/0017_letter_combinations_of_a_phone_number/letter_combinations.cpp b/0017_letter_combinations_of_a_phone_number/letter_combinations.cpp new file mode 100644 index 0000000..2d375c4 --- /dev/null +++ b/0017_letter_combinations_of_a_phone_number/letter_combinations.cpp @@ -0,0 +1,43 @@ +#include +using namespace std; + +class Solution +{ +public: + vector m = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; + vector ans; + vector letterCombinations(string digits) + { + solve(0, "", digits); + return ans; + } + void solve(int i, string path, string digits) + { + if (i >= digits.size()) + { + if (path.size() > 0) + ans.push_back(path); + return; + } + for (auto c : m[digits[i] - '0']) + { + path += c; + solve(i + 1, path, digits); + path.pop_back(); + } + } +}; + +int main() +{ + cout << "Enter A string : "; + string s; + cin >> s; + Solution sol; + // vector ans = sol.letterCombinations(s) ; + for (auto str : sol.letterCombinations(s)) + { + cout << str << " "; + } + return 0; +} \ No newline at end of file diff --git a/0018_four_sum/Makefile b/0018_four_sum/Makefile new file mode 100644 index 0000000..8b576d1 --- /dev/null +++ b/0018_four_sum/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test four_sum.c diff --git a/0018_four_sum/four_sum.c b/0018_four_sum/four_sum.c new file mode 100644 index 0000000..8b06eaf --- /dev/null +++ b/0018_four_sum/four_sum.c @@ -0,0 +1,84 @@ +#include +#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, long target, int total, int k, + int *stack, int len, int **results, int *count) +{ + int i; + if (k == 2) { + while (low < high) { + int sum = nums[low] + nums[high]; + if (sum < target) { + low++; + } else if (sum > target) { + high--; + } else { + stack[len++] = nums[low]; + stack[len++] = nums[high]; + results[*count] = malloc(total * sizeof(int)); + memcpy(results[*count], stack, total * sizeof(int)); + (*count)++; + len -= 2; + while (++low < high && nums[low] == nums[low - 1]) {} + while (--high > low && nums[high] == nums[high + 1]) {} + } + } + } else { + /* 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 + 1, results, count); + } + } +} + +/** + * 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** fourSum(int* nums, int numsSize, int target, int* returnSize, int** returnColumnSizes) +{ + *returnSize = 0; + int i, capacity = 50000; + int **results = 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 = malloc(capacity * sizeof(int)); + for (i = 0; i < *returnSize; i++) { + (*returnColumnSizes)[i] = 4; + } + + return results; +} + +int main(void) +{ + int i, j, count, target = 11, *col_sizes; + //int nums[] = { 1, 0, -1, 0, -2, 2 }; + //int nums[] = { -3, -2, -1, 0, 0, 1, 2, 3 }; + int nums[] = { 0, 1, 5, 0, 1, 5, 5, -4 }; + int **quadruplets = fourSum(nums, sizeof(nums) / sizeof(*nums), target, &count, &col_sizes); + for (i = 0; i < count; i++) { + for (j = 0; j < col_sizes[i]; j++) { + printf("%d ", quadruplets[i][j]); + } + printf("\n"); + } + + return 0; +} diff --git a/0018_four_sum/four_sum.cc b/0018_four_sum/four_sum.cc new file mode 100644 index 0000000..d661eb9 --- /dev/null +++ b/0018_four_sum/four_sum.cc @@ -0,0 +1,44 @@ +#include + +using namespace std; + +class Solution { +public: + vector> fourSum(vector& nums, int target) { + vector> res; + if (nums.size() >= 4) { + vector stack; + sort(nums.begin(), nums.end()); + k_sum(nums.begin(), nums.end() - 1, target, 4, stack, res); + } + return res; + } + +private: + void k_sum(vector::iterator lo, vector::iterator hi, int target, + int k, vector& stack, vector>& res) { + if (k == 2) { + while (lo < hi) { + int sum = *lo + *hi; + if (sum < target) { + lo++; + } else if (sum > target) { + hi--; + } else { + stack.push_back(*lo); + stack.push_back(*hi); + res.push_back(stack); + while (++lo < hi && *lo == *(lo - 1)) {} + while (lo < hi-- && *hi == *(hi + 1)) {} + } + } + } else { + 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); + stack.pop_back(); + } + } + } +}; diff --git a/0019_remove_nth_node_from_end_of_list/Makefile b/0019_remove_nth_node_from_end_of_list/Makefile new file mode 100644 index 0000000..0ec5947 --- /dev/null +++ b/0019_remove_nth_node_from_end_of_list/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test remove_end.c 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 84% 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 index 4c96721..d9242db 100644 --- a/019_remove_nth_node_from_end_of_list/remove_end.c +++ b/0019_remove_nth_node_from_end_of_list/remove_end.c @@ -1,15 +1,18 @@ #include #include - struct ListNode { - int val; - struct ListNode *next; - }; +struct ListNode { + int val; + struct ListNode *next; +}; -struct ListNode* removeNthFromEnd(struct ListNode* head, int n) { - struct ListNode *p, *prev, dummy; - if (n < 1) return NULL; +static struct ListNode* removeNthFromEnd(struct ListNode* head, int n) +{ + if (n == 0) { + return NULL; + } + struct ListNode *p, *prev, dummy; dummy.next = head; p = prev = &dummy; while (n-- > 0) { @@ -26,7 +29,7 @@ struct ListNode* removeNthFromEnd(struct ListNode* head, int n) { if (tmp == head) { head = tmp->next; } - free(tmp); + return head; } diff --git a/0019_remove_nth_node_from_end_of_list/remove_end.cc b/0019_remove_nth_node_from_end_of_list/remove_end.cc new file mode 100644 index 0000000..5857e92 --- /dev/null +++ b/0019_remove_nth_node_from_end_of_list/remove_end.cc @@ -0,0 +1,42 @@ +#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* removeNthFromEnd(ListNode* head, int n) { + if (n == 0) { + return nullptr; + } + + struct ListNode *p, *prev, dummy; + dummy.next = head; + p = prev = &dummy; + while (n-- > 0) { + p = p->next; + } + + while (p->next != nullptr) { + p = p->next; + prev = prev->next; + } + + struct ListNode *tmp = prev->next; + prev->next = tmp->next; + if (tmp == head) { + head = tmp->next; + } + + return head; + } +}; diff --git a/001_two_sum/Makefile b/001_two_sum/Makefile deleted file mode 100644 index ffb6456..0000000 --- a/001_two_sum/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test two_sum.c diff --git a/001_two_sum/two_sum.c b/001_two_sum/two_sum.c deleted file mode 100644 index 10f1319..0000000 --- a/001_two_sum/two_sum.c +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include - -static void bubble_sort(int *nums, int *indexes, int size) -{ - int i, flag = size; - while (flag > 0) { - int len = flag; - flag = 0; - for (i = 1; i < len; i++) { - if (nums[i] < nums[i - 1]) { - int tmp = nums[i]; - nums[i] = nums[i - 1]; - nums[i - 1] = tmp; - tmp = indexes[i]; - indexes[i] = indexes[i - 1]; - indexes[i - 1] = tmp; - flag = i; - } - } - } -} - -static int * twosum(int *nums, int numsSize, int target) -{ - int i, j; - int *indexes = malloc(numsSize * sizeof(int)); - for (i = 0; i < numsSize; i++) { - indexes[i] = i; - } - bubble_sort(nums, indexes, numsSize); - - int count = 0; - int *results = malloc(2 * sizeof(int)); - i = 0; - j = numsSize - 1; - while (i < j) { - int diff = target - nums[i]; - if (diff > nums[j]) { - while (++i < j && nums[i] == nums[i - 1]) {} - } else if (diff < nums[j]) { - while (--j > i && nums[j] == nums[j + 1]) {} - } else { - results[0] = indexes[i]; - results[1] = indexes[j]; - return results; - } - } - return NULL; -} - -int main(void) -{ - //int nums[] = {-1, -2, -3, -4, -5}; - //int target = -8; - //int nums[] = {0,4,3,0}; - //int target = 0; - int nums[] = { 3, 2, 3 }; - int count = sizeof(nums) / sizeof(*nums); - int target = 6; - int *indexes = twosum(nums, count, target); - if (indexes != NULL) { - printf("%d %d\n", indexes[0], indexes[1]); - } else { - printf("Not found\n"); - } - - return 0; -} diff --git a/0020_valid_parentheses/Makefile b/0020_valid_parentheses/Makefile new file mode 100644 index 0000000..4a73e93 --- /dev/null +++ b/0020_valid_parentheses/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test valid_parentheses.c diff --git a/020_valid_parentheses/valid_parentheses.c b/0020_valid_parentheses/valid_parentheses.c similarity index 66% rename from 020_valid_parentheses/valid_parentheses.c rename to 0020_valid_parentheses/valid_parentheses.c index 8fa87c8..3e825e3 100644 --- a/020_valid_parentheses/valid_parentheses.c +++ b/0020_valid_parentheses/valid_parentheses.c @@ -4,28 +4,24 @@ static bool isValid(char *s) { - int n = 0, cap = 100; - char *stack = malloc(cap); + int n = 0; + char stack[100]; while (*s != '\0') { switch(*s) { case '(': case '[': case '{': - if (n + 1 >= cap) { - cap *= 2; - stack = realloc(stack, cap); - } stack[n++] = *s; break; case ')': - if (stack[--n] != '(') return false; + if (n == 0 || stack[--n] != '(') return false; break; case ']': - if (stack[--n] != '[') return false; + if (n == 0 || stack[--n] != '[') return false; break; case '}': - if (stack[--n] != '{') return false; + if (n == 0 || stack[--n] != '{') return false; break; default: return false; diff --git a/0020_valid_parentheses/valid_parentheses.cc b/0020_valid_parentheses/valid_parentheses.cc new file mode 100644 index 0000000..9593ec8 --- /dev/null +++ b/0020_valid_parentheses/valid_parentheses.cc @@ -0,0 +1,41 @@ +#include + +using namespace std; + +class Solution { +public: + bool isValid(string s) { + stack stk; + for (int i = 0; i < s.length(); i++) { + switch(s[i]) { + case '(': + case '[': + case '{': + stk.push(s[i]); + break; + case ')': + if (stk.empty() || stk.top() != '(') { + return false; + } else { + stk.pop(); + break; + } + case ']': + if (stk.empty() || stk.top() != '[') { + return false; + } else { + stk.pop(); + break; + } + case '}': + if (stk.empty() || stk.top() != '{') { + return false; + } else { + stk.pop(); + break; + } + } + } + return stk.empty(); + } +}; diff --git a/0021_merge_two_sorted_lists/Makefile b/0021_merge_two_sorted_lists/Makefile new file mode 100644 index 0000000..aca334a --- /dev/null +++ b/0021_merge_two_sorted_lists/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test merge_lists.c diff --git a/0021_merge_two_sorted_lists/merge_lists.c b/0021_merge_two_sorted_lists/merge_lists.c new file mode 100644 index 0000000..021a584 --- /dev/null +++ b/0021_merge_two_sorted_lists/merge_lists.c @@ -0,0 +1,45 @@ +#include +#include + +struct ListNode { + int val; + struct ListNode *next; +}; + +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; +} + +int main(int argc, char **argv) +{ + struct ListNode l1; + l1.val = 2; + l1.next = NULL; + struct ListNode l2; + l2.val = 1; + l2.next = NULL; + struct ListNode * list = mergeTwoLists(&l1, &l2); + while (list != NULL) { + printf("%d ", list->val); + list = list->next; + } + printf("\n"); + return 0; +} diff --git a/0021_merge_two_sorted_lists/merge_lists.cc b/0021_merge_two_sorted_lists/merge_lists.cc new file mode 100644 index 0000000..58a47f7 --- /dev/null +++ b/0021_merge_two_sorted_lists/merge_lists.cc @@ -0,0 +1,36 @@ +#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* mergeTwoLists(ListNode* l1, ListNode* l2) { + struct ListNode *tail, dummy; + tail = &dummy; + dummy.next = l1; + + while (l1 != nullptr && l2 != nullptr) { + if (l1->val <= l2->val) { + tail->next = l1; + l1 = l1->next; + } else { + tail->next = l2; + l2 = l2->next; + } + } + + tail->next = l1 != nullptr ? l1 : l2; + + return dummy.next; + } +}; diff --git a/0022_generate_parathesis/Makefile b/0022_generate_parathesis/Makefile new file mode 100644 index 0000000..fb8a13d --- /dev/null +++ b/0022_generate_parathesis/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test parenthesis.c diff --git a/0022_generate_parathesis/parenthesis.c b/0022_generate_parathesis/parenthesis.c new file mode 100644 index 0000000..174b3ed --- /dev/null +++ b/0022_generate_parathesis/parenthesis.c @@ -0,0 +1,50 @@ +#include +#include +#include + +static void dfs(int n, int left, int right, char *stack, int len, char **results, int *count) +{ + if (len == 2 * n) { + results[*count] = malloc((len + 1) * sizeof(char)); + strcpy(results[(*count)++], stack); + return; + } + + if (left < n) { + stack[len] = '('; + dfs(n, left + 1, right, stack, len + 1, results, count); + } + + if (right < left) { + stack[len] = ')'; + dfs(n, left, right + 1, stack, len + 1, results, count); + } +} + +/** + ** Return an array of size *returnSize. + ** Note: The returned array must be malloced, assume caller calls free(). + **/ +static char** generateParenthesis(int n, int* returnSize) +{ + char *stack = calloc(2 * n + 1, sizeof(char)); + char **parentheses = malloc(5000 * sizeof(char *)); + *returnSize = 0; + dfs(n, 0, 0, stack, 0, parentheses, returnSize); + + return parentheses; +} + +int main(int argc, char **argv) +{ + int i, count; + if (argc != 2) { + fprintf(stderr, "Usage: ./test 3\n"); + exit(-1); + } + char ** lists = generateParenthesis(atoi(argv[1]), &count); + for (i = 0; i < count; i++) { + printf("%s\n", lists[i]); + } + return 0; +} diff --git a/0022_generate_parathesis/parenthesis.cc b/0022_generate_parathesis/parenthesis.cc new file mode 100644 index 0000000..ba7451e --- /dev/null +++ b/0022_generate_parathesis/parenthesis.cc @@ -0,0 +1,33 @@ +#include + +using namespace std; + +class Solution { +public: + vector generateParenthesis(int n) { + vector res; + dfs(n, 0, 0, res); + return res; + } + +private: + string stack; + void dfs(int n, int l, int r, vector& res) { + if (stack.length() == 2 * n) { + res.push_back(stack); + return; + } + + 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(); + } + } +}; diff --git a/0022_generate_parathesis/young_tableau.cc b/0022_generate_parathesis/young_tableau.cc new file mode 100644 index 0000000..04ffc7d --- /dev/null +++ b/0022_generate_parathesis/young_tableau.cc @@ -0,0 +1,60 @@ +#include +#include +#include + + +using namespace std; + +class Solution { +public: + vector> young_tableau(int n) { + vector> res; + dfs(n, 0, 0, res); + return res; + } + +private: + vector stack; + + void dfs(int n, int l, int r, vector>& res) { + if (stack.size() == 2 * n) { + vector sol(2 * n); + for (int i = 0, j = 0, k = n; i < 2 * n; i++) { + if (stack[i] == '(') { + sol[j++] = i + 1; + } else { + sol[k++] = i + 1; + } + } + res.push_back(sol); + } else { + if (l < n) { + stack.push_back('('); + dfs(n, l + 1, r, res); + stack.pop_back(); + } + + if (r < l) { + stack.push_back(')'); + dfs(n, l, r + 1, res); + stack.pop_back(); + } + } + } +}; + +int main(int argc, char **argv) +{ + int n = atoi(argv[1]); + Solution *solution = new Solution(); + vector> res = solution->young_tableau(n); + for (auto& v : res) { + for (int i = 0; i < 2 * n; i++) { + if (i == n) cout << endl; + cout << v[i] << ' '; + } + cout << endl; + } + + return 0; +} diff --git a/0023_merge_k_sorted_lists/Makefile b/0023_merge_k_sorted_lists/Makefile new file mode 100644 index 0000000..aca334a --- /dev/null +++ b/0023_merge_k_sorted_lists/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test merge_lists.c 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/0023_merge_k_sorted_lists/merge_lists.cc b/0023_merge_k_sorted_lists/merge_lists.cc new file mode 100644 index 0000000..0e9d8d4 --- /dev/null +++ b/0023_merge_k_sorted_lists/merge_lists.cc @@ -0,0 +1,42 @@ +#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* mergeKLists(vector& lists) { + auto cmp = [](struct ListNode *n1, struct ListNode *n2) { + return n1->val > n2->val; + } + priority_queue, decltype(cmp)> queue(cmp); + + for (int i = 0; i < lists.size(); i++) { + if (lists[i] != nullptr) { + queue.push(lists[i]); + } + } + + struct ListNode dummy, *p = &dummy;; + while (!queue.empty()) { + ListNode *node = queue.top(); + queue.pop(); + p->next = node; + p = node; + if (node->next != nullptr) { + queue.push(node->next); + } + } + + return dummy.next; + } +}; diff --git a/0024_swap_nodes_in_pairs/Makefile b/0024_swap_nodes_in_pairs/Makefile new file mode 100644 index 0000000..8d9393d --- /dev/null +++ b/0024_swap_nodes_in_pairs/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test swap_nodes.c diff --git a/024_swap_nodes_in_pairs/swap_nodes.c b/0024_swap_nodes_in_pairs/swap_nodes.c similarity index 66% rename from 024_swap_nodes_in_pairs/swap_nodes.c rename to 0024_swap_nodes_in_pairs/swap_nodes.c index c491b22..dea9621 100644 --- a/024_swap_nodes_in_pairs/swap_nodes.c +++ b/0024_swap_nodes_in_pairs/swap_nodes.c @@ -6,24 +6,26 @@ struct ListNode { struct ListNode *next; }; -static struct ListNode* swapPairs(struct ListNode* head) { - struct ListNode dummy, *p, *prev, *next; +static struct ListNode* swapPairs(struct ListNode* head) +{ if (head == NULL) { return NULL; } + struct ListNode dummy; dummy.next = head; - prev = &dummy; - p = dummy.next; - next = p->next; - while (p != NULL && next != NULL) { - prev->next = next; - p->next = next->next; - next->next = p; + struct ListNode *prev = &dummy; + struct ListNode *p = dummy.next; + + while (p != NULL && p->next != NULL) { + struct ListNode *q = p->next; + /* deletion */ + p->next = q->next; + /* insertion */ + q->next = p; + prev->next = q; + /* iteration */ prev = p; p = p->next; - if (p != NULL) { - next = p->next; - } } return dummy.next; } diff --git a/0024_swap_nodes_in_pairs/swap_nodes.cc b/0024_swap_nodes_in_pairs/swap_nodes.cc new file mode 100644 index 0000000..cca65b3 --- /dev/null +++ b/0024_swap_nodes_in_pairs/swap_nodes.cc @@ -0,0 +1,33 @@ +#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* swapPairs(ListNode* head) { + struct ListNode dummy, *prev = &dummy, *p = head; + dummy.next = head; + while (p != nullptr && p->next != nullptr) { + struct ListNode *q = p->next; + /* deletion */ + p->next = q->next; + /* insertion */ + q->next = prev->next; + prev->next = q; + /* iteration */ + prev = p; + p = p->next; + } + return dummy.next; + } +}; diff --git a/0025_reverse_nodes_in_k_group/Makefile b/0025_reverse_nodes_in_k_group/Makefile new file mode 100644 index 0000000..24a4db6 --- /dev/null +++ b/0025_reverse_nodes_in_k_group/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test reverse_nodes.c diff --git a/0025_reverse_nodes_in_k_group/reverse_nodes.c b/0025_reverse_nodes_in_k_group/reverse_nodes.c new file mode 100644 index 0000000..ecbe9a1 --- /dev/null +++ b/0025_reverse_nodes_in_k_group/reverse_nodes.c @@ -0,0 +1,62 @@ +#include +#include + +struct ListNode { + int val; + struct ListNode *next; +}; + +static struct ListNode* reverseKGroup(struct ListNode* head, int k) +{ + int len = 0; + struct ListNode dummy; + struct ListNode *prev = &dummy; + dummy.next = head; + for (; head != NULL; head = head->next) { + if (++len % k == 0) { + /* 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 *q = p->next; + /* deletion */ + p->next = q->next; + /* insertion */ + q->next = prev->next; + prev->next = q; + } + /* For iteration */ + prev = p; + head = p; + } + } + return dummy.next; +} + +int main(int argc, char **argv) +{ + int i; + struct ListNode *p, *prev, dummy, *list; + + dummy.next = NULL; + prev = &dummy; + for (i = 2; i < argc; i++) { + p = malloc(sizeof(*p)); + int n = atoi(argv[i]); + printf("%d ", n); + p->val = n; + p->next = NULL; + prev->next = p; + prev = p; + } + putchar('\n'); + + list = reverseKGroup(dummy.next, atoi(argv[1])); + for (p = list; p != NULL; p = p->next) { + printf("%d ", p->val); + } + putchar('\n'); + + return 0; +} diff --git a/0025_reverse_nodes_in_k_group/reverse_nodes.cc b/0025_reverse_nodes_in_k_group/reverse_nodes.cc new file mode 100644 index 0000000..73362b2 --- /dev/null +++ b/0025_reverse_nodes_in_k_group/reverse_nodes.cc @@ -0,0 +1,41 @@ +#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* reverseGroup(ListNode* head, int k) { + int len = 0; + struct ListNode dummy, *prev = &dummy; + dummy.next = head; + + for (; head != nullptr; head = head->next) { + if (++len % k == 0) { + struct ListNode *p = prev->next; + while (prev->next != head) { + struct ListNode *q = p->next; + /* deletion */ + p->next = q->next; + /* insertion */ + q->next = prev->next; + prev->next = q; + } + /* iteration */ + prev = p; + head = p; + } + } + + return dummy.next; + } +}; diff --git a/0026_remove_duplicates_from_sorted_array/Makefile b/0026_remove_duplicates_from_sorted_array/Makefile new file mode 100644 index 0000000..a4e0790 --- /dev/null +++ b/0026_remove_duplicates_from_sorted_array/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test rm_dup.c diff --git a/026_remove_duplicates_from_sorted_array/rm_dup.c b/0026_remove_duplicates_from_sorted_array/rm_dup.c similarity index 62% rename from 026_remove_duplicates_from_sorted_array/rm_dup.c rename to 0026_remove_duplicates_from_sorted_array/rm_dup.c index 092b457..1bc5764 100644 --- a/026_remove_duplicates_from_sorted_array/rm_dup.c +++ b/0026_remove_duplicates_from_sorted_array/rm_dup.c @@ -1,22 +1,17 @@ #include #include + static int removeDuplicates(int* nums, int numsSize) { - if (numsSize <= 1) { - return numsSize; - } - - int i = 0, j, count = 1; - while (i < numsSize) { - for (j = i + 1; j < numsSize && nums[i] == nums[j]; j++) {} - if (j < numsSize) { - nums[count++] = nums[j]; + int i, size = 0; + for (i = 1; i < numsSize; i++) { + if (nums[size] != nums[i]) { + nums[++size] = nums[i]; } - i = j; } - return count; + return size + 1; } int main(int argc, char **argv) diff --git a/0026_remove_duplicates_from_sorted_array/rm_dup.cc b/0026_remove_duplicates_from_sorted_array/rm_dup.cc new file mode 100644 index 0000000..ebfc556 --- /dev/null +++ b/0026_remove_duplicates_from_sorted_array/rm_dup.cc @@ -0,0 +1,17 @@ +#include + +using namespace std; + +class Solution { +public: + int removeDuplicates(vector& nums) { + int size = 0; + for (int i = 1; i < nums.size(); i++) { + if (nums[size] != nums[i]) { + nums[++size] = nums[i]; + } + } + + return size + 1; + } +}; diff --git a/0027_remove_element/Makefile b/0027_remove_element/Makefile new file mode 100644 index 0000000..8c8bea3 --- /dev/null +++ b/0027_remove_element/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test rm_elem.c 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/0027_remove_element/rm_elem.cc b/0027_remove_element/rm_elem.cc new file mode 100644 index 0000000..f6e25d1 --- /dev/null +++ b/0027_remove_element/rm_elem.cc @@ -0,0 +1,16 @@ +#include + +using namespace std; + +class Solution { +public: + int removeElement(vector& nums, int val) { + int count = 0; + for (int i = 0; i < nums.size(); i++) { + if (nums[i] != val) { + nums[count++] = nums[i]; + } + } + return count; + } +}; diff --git a/0028_implement_strstr/Makefile b/0028_implement_strstr/Makefile new file mode 100644 index 0000000..7fedca7 --- /dev/null +++ b/0028_implement_strstr/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test strstr.c diff --git a/028_implement_strstr/strstr.c b/0028_implement_strstr/strstr.c similarity index 79% rename from 028_implement_strstr/strstr.c rename to 0028_implement_strstr/strstr.c index b314b50..f8204ba 100644 --- a/028_implement_strstr/strstr.c +++ b/0028_implement_strstr/strstr.c @@ -74,32 +74,21 @@ int strStr(char *haystack, char *needle) static int strStr(char *haystack, char *needle) { - int i, j, found = 1; + int i, j; unsigned int hlen = strlen(haystack); unsigned int nlen = strlen(needle); - if (nlen == 0) { - return 0; - } + // when haystack is shorter than needle, should return -1 + if(hlen < nlen) + return -1; /* Brute force */ - for (i = 0; i < hlen; i++) { - if (haystack[i] == needle[0]) { - for (j = 1; j < nlen; j++) { - if (i + j < hlen) { - if (haystack[i + j] != needle[j]) { - found = 0; - break; - } - } else { - return -1; - } - } - if (found) { - return i; - } - } - found = 1; + /* Corner condition: imagine nlen = 1 and it equals i < hlen */ + for (i = 0; i < hlen - nlen + 1; i++) { + for (j = 0; j < nlen && haystack[i + j] == needle[j]; j++) {} + if (j == nlen) { + return i; + } } return -1; 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/0029_divide_two_integers/Makefile b/0029_divide_two_integers/Makefile new file mode 100644 index 0000000..2092b85 --- /dev/null +++ b/0029_divide_two_integers/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test divide.c diff --git a/0029_divide_two_integers/divide.c b/0029_divide_two_integers/divide.c new file mode 100644 index 0000000..081ab72 --- /dev/null +++ b/0029_divide_two_integers/divide.c @@ -0,0 +1,49 @@ +#include +#include +#include + +int divide(int dividend, int divisor) +{ + int signal = 1; + unsigned int dvd = dividend; + if (dividend < 0) { + signal *= -1; + dvd = ~dvd + 1; + } + + unsigned int dvs = divisor; + if (divisor < 0) { + signal *= -1; + dvs = ~dvs + 1; + } + + int shift = 0; + while (dvd > dvs << shift) { + shift++; + } + + unsigned int res = 0; + while (dvd >= dvs) { + while (dvd < dvs << shift) { + shift--; + } + res |= (unsigned int) 1 << shift; + dvd -= dvs << shift; + } + + if (signal == 1 && res >= INT_MAX) { + return INT_MAX; + } else { + return res * signal; + } +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./test dividend divisor\n"); + exit(-1); + } + printf("%d\n", divide(atoi(argv[1]), atoi(argv[2]))); + return 0; +} diff --git a/0029_divide_two_integers/divide.cc b/0029_divide_two_integers/divide.cc new file mode 100644 index 0000000..204811e --- /dev/null +++ b/0029_divide_two_integers/divide.cc @@ -0,0 +1,42 @@ +#include + +using namespace std; + +class Solution { +public: + int divide(int dividend, int divisor) { + int signal = 1; + unsigned int dvd = dividend; + if (dividend < 0) { + signal *= -1; + dvd = ~dvd + 1; + } + + unsigned int dvs = divisor; + if (divisor < 0) { + signal *= -1; + dvs = ~dvs + 1; + } + + int shift = 0; + while (dvd > dvs << shift) { + shift++; + } + + unsigned int res = 0; + while (dvd >= dvs) { + while (dvd < dvs << shift) { + shift--; + } + res |= (unsigned int) 1 << shift; + dvd -= dvs << shift; + } + + if (signal == 1 && res >= INT_MAX) { + return INT_MAX; + } else { + return res * signal; + } + } +}; + diff --git a/002_add_two_numbers/Makefile b/002_add_two_numbers/Makefile deleted file mode 100644 index 9270c00..0000000 --- a/002_add_two_numbers/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test add_two_numbers.c diff --git a/0030_substring_with_concatenation_of_all_words/Makefile b/0030_substring_with_concatenation_of_all_words/Makefile new file mode 100644 index 0000000..c0cbbfe --- /dev/null +++ b/0030_substring_with_concatenation_of_all_words/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test concatenation.c diff --git a/0030_substring_with_concatenation_of_all_words/concatenation.c b/0030_substring_with_concatenation_of_all_words/concatenation.c new file mode 100644 index 0000000..475cc45 --- /dev/null +++ b/0030_substring_with_concatenation_of_all_words/concatenation.c @@ -0,0 +1,176 @@ +#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_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; + int index; + 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 inline int BKDRHash(char *s, size_t size) +{ + int seed = 131; /* 131 1313 13131... */ + unsigned long hash = 0; + while (*s != '\0') { + hash = hash * seed + *s++; + } + return hash % size; +} + +static int find(char *word, struct list_head *heads, int size) +{ + struct word_node *wn; + int hash = BKDRHash(word, size); + list_for_each_entry(wn, &heads[hash], link) { + if (!strcmp(wn->word, word)) { + return wn->index; + } + } + return -1; +} + +static void add(char **words, int index, struct list_head *heads, int size, int *freqs) +{ + struct word_node *wn; + int hash = BKDRHash(words[index], size); + list_for_each_entry(wn, &heads[hash], link) { + if (!strcmp(wn->word, words[index])) { + freqs[wn->index]++; + return; + } + } + wn = malloc(sizeof(*wn)); + wn->word = words[index]; + wn->index = index; + list_add(&wn->link, &heads[hash]); + freqs[wn->index]++; +} + +/** + ** Return an array of size *returnSize. + ** Note: The returned array must be malloced, assume caller calls free(). + **/ +static int *findSubstring(char *s, char **words, int wordsSize, int *returnSize) +{ + if (*s == '\0' || wordsSize == 0) { + *returnSize = 0; + return NULL; + } + + int i, j, cap = 10000, count = 0; + int hash_size = wordsSize; + struct list_head *heads = malloc(hash_size * sizeof(*heads)); + for (i = 0; i < hash_size; i++) { + INIT_LIST_HEAD(&heads[i]); + } + + int *freqs = malloc(wordsSize * sizeof(int)); + memset(freqs, 0, wordsSize * sizeof(int)); + + for (i = 0; i < wordsSize; i++) { + add(words, i, heads, hash_size, freqs); + } + + int len = strlen(words[0]); + int length = len * wordsSize - 1; + char *word = malloc(len + 1); + word[len] = '\0'; + int *indexes = malloc(cap * sizeof(int)); + for (i = 0; s[i + len - 1] != '\0'; i++) { + memcpy(word, s + i, len); + indexes[i] = find(word, heads, hash_size); + } + + int *results = malloc(cap * sizeof(int)); + int *fqs = malloc(wordsSize * sizeof(int)); + for (i = 0; s[i + length] != '\0'; i++) { + memset(fqs, 0, wordsSize * sizeof(int)); + for (j = 0; j < wordsSize; j++) { + /* concatenation */ + int index = indexes[i + j * len]; + if (index < 0 || ++fqs[index] > freqs[index]) { + break; + } + } + if (j == wordsSize) { + results[count++] = i; + } + } + + *returnSize = count; + return results; +} + +int main(int argc, char **argv) +{ + if (argc < 3) { + fprintf(stderr, "Usage: ./test str w1 w2...\n"); + exit(-1); + } + + int i, count = 0; + int *results = findSubstring(argv[1], argv + 2, argc - 2, &count); + for (i = 0; i < count; i++) { + printf("%d ", results[i]); + } + printf("\n"); + return 0; +} diff --git a/0030_substring_with_concatenation_of_all_words/concatenation.cc b/0030_substring_with_concatenation_of_all_words/concatenation.cc new file mode 100644 index 0000000..ac9d85c --- /dev/null +++ b/0030_substring_with_concatenation_of_all_words/concatenation.cc @@ -0,0 +1,34 @@ +#include + +using namespace std; + +class Solution { +public: + vector findSubstring(string s, vector& words) { + vector res; + if (s.empty() || words.empty()) { + return res; + } + + unordered_map ht; + for (const auto& w : words) { + ht[w]++; + } + + int len = words[0].length(); + for (int i = 0, j = 0; i < s.length() - words.size() * len + 1; i++) { + unordered_map counting; + for (j = 0; j < words.size(); j++) { + string word = s.substr(i + j * len, len); + if (++counting[word] > ht[word]) { + break; + } + } + if (j == words.size()) { + res.push_back(i); + } + } + + return res; + } +}; diff --git a/0031_next_permutation/Makefile b/0031_next_permutation/Makefile new file mode 100644 index 0000000..cb26956 --- /dev/null +++ b/0031_next_permutation/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test next_permutation.c diff --git a/0031_next_permutation/next_permutation.c b/0031_next_permutation/next_permutation.c new file mode 100644 index 0000000..8cd3024 --- /dev/null +++ b/0031_next_permutation/next_permutation.c @@ -0,0 +1,64 @@ +#include +#include + +static inline void swap(int *a, int *b) +{ + int tmp = *a; + *a = *b; + *b = tmp; +} + +static void reverse(int *a, int size) +{ + int lo = 0; + int hi = size - 1; + while (lo < hi) { + swap(a + lo, a + hi); + lo++; + hi--; + } +} + +static void nextPermutation(int* nums, int numsSize) +{ + // 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]) { + j--; + } + swap(nums + i, nums + j); + } + + // reverse the subsequence into increasing one. + reverse(nums + i + 1, numsSize - i - 1); +} + +int main(int argc, char **argv) +{ + if (argc <= 1) { + fprintf(stderr, "Usage: ./test ...\n"); + exit(-1); + } + + int i; + int *nums = malloc(sizeof(int)); + for (i = 0; i < argc - 1; i++) { + nums[i] = atoi(argv[i + 1]); + } + + nextPermutation(nums, argc - 1); + + for (i = 0; i < argc - 1; i++) { + printf("%d ", nums[i]); + } + putchar('\n'); + + return 0; +} diff --git a/0031_next_permutation/next_permutation.cc b/0031_next_permutation/next_permutation.cc new file mode 100644 index 0000000..f12077d --- /dev/null +++ b/0031_next_permutation/next_permutation.cc @@ -0,0 +1,28 @@ +#include + +using namespace std; + +class Solution { +public: + void nextPermutation(vector& nums) { + // find the first smaller element in decreasing sequence from back to + // forth. + int i = nums.size() - 2; + while (i >= 0 && nums[i] >= nums[i + 1]) { + i--; + } + + // if found, find the first bigger element from back to forth and swap + // them. + if (i >= 0) { + int j = nums.size() - 1; + while (j >= 0 && nums[i] >= nums[j]) { + j--; + } + swap(nums[i], nums[j]); + } + + // reverse the subsequence into increasing one. + reverse(nums.begin() + i + 1, nums.end()); + } +}; diff --git a/0032_longest_valid_parentheses/Makefile b/0032_longest_valid_parentheses/Makefile new file mode 100644 index 0000000..4a73e93 --- /dev/null +++ b/0032_longest_valid_parentheses/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test valid_parentheses.c diff --git a/0032_longest_valid_parentheses/valid_parentheses.c b/0032_longest_valid_parentheses/valid_parentheses.c new file mode 100644 index 0000000..83c9f15 --- /dev/null +++ b/0032_longest_valid_parentheses/valid_parentheses.c @@ -0,0 +1,48 @@ +#include +#include + + +static inline int max(int a, int b) +{ + return a > b ? a : b; +} + +static int longestValidParentheses(char* s) +{ + int i, cap = 18000, invalid = -1; + int len = 0, max_len = 0; + int *stack = malloc(cap * sizeof(int)); + int *top = stack; + + /* We only restore index of '(' since restrain of space */ + for (i = 0; s[i] != '\0'; i++) { + if (s[i] == '(') { + *top++ = i; + } else { + if (top > stack) { + if (--top == stack) { + /* locate the remote ')' */ + max_len = max(i - invalid, max_len); + } else { + /* locate the remote '(' */ + max_len = max(i - *(top - 1), max_len); + } + } else { + /* record the index of the remote ')' and no push */ + invalid = i; + } + } + } + return max_len; +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test parathesis\n"); + exit(-1); + } + + printf("%d\n", longestValidParentheses(argv[1])); + return 0; +} diff --git a/0032_longest_valid_parentheses/valid_parentheses.cc b/0032_longest_valid_parentheses/valid_parentheses.cc new file mode 100644 index 0000000..37ae42f --- /dev/null +++ b/0032_longest_valid_parentheses/valid_parentheses.cc @@ -0,0 +1,32 @@ +#include + +using namespace std; + +class Solution { +public: + int longestValidParentheses(string s) { + stack stk; + int invalid = -1; + int len = 0, max_len = 0; + for (int i = 0; i < s.length(); i++) { + if (s[i] == '(') { + stk.push(i); + } else { + if (stk.empty()) { + invalid = i; + } else { + stk.pop(); + if (stk.empty()) { + /* locate the remote ')' */ + max_len = max(i - invalid, max_len); + } else { + /* locate the remote '(' */ + max_len = max(i - stk.top(), max_len); + } + } + } + } + + return max_len; + } +}; diff --git a/0033_search_in_rotated_sorted_array/Makefile b/0033_search_in_rotated_sorted_array/Makefile new file mode 100644 index 0000000..525f67a --- /dev/null +++ b/0033_search_in_rotated_sorted_array/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test rotated_array.c diff --git a/0033_search_in_rotated_sorted_array/rotated_array.c b/0033_search_in_rotated_sorted_array/rotated_array.c new file mode 100644 index 0000000..07d508c --- /dev/null +++ b/0033_search_in_rotated_sorted_array/rotated_array.c @@ -0,0 +1,47 @@ +#include +#include + + +static int search(int* nums, int numsSize, int target) +{ + int lo = 0; + int hi = numsSize - 1; + while (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; + } else { + lo = mid + 1; + } + } else { + if (nums[mid] < target && target <= nums[hi]) { + lo = mid + 1; + } else { + hi = mid - 1; + } + } + } + + return -1; +} + +int main(int argc, char **argv) +{ + int i; + int target = atoi(argv[1]); + int size = argc - 2; + int *nums = malloc(size * sizeof(int)); + + for (i = 0; i < argc - 2; i++) { + nums[i] = atoi(argv[i + 2]); + } + printf("%d\n", search(nums, size, target)); + return 0; +} diff --git a/0033_search_in_rotated_sorted_array/rotated_array.cc b/0033_search_in_rotated_sorted_array/rotated_array.cc new file mode 100644 index 0000000..67d0ec8 --- /dev/null +++ b/0033_search_in_rotated_sorted_array/rotated_array.cc @@ -0,0 +1,36 @@ +#include + +using namespace std; + +class Solution { +public: + 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; + } else { + lo = mid + 1; + } + } else { + if (nums[mid] < target && target <= nums[hi]) { + lo = mid + 1; + } else { + hi = mid - 1; + } + } + } + + return -1; + } +}; diff --git a/0034_search_for_a_range/Makefile b/0034_search_for_a_range/Makefile new file mode 100644 index 0000000..8564929 --- /dev/null +++ b/0034_search_for_a_range/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test range_search.c diff --git a/034_search_for_a_range/range_search.c b/0034_search_for_a_range/range_search.c similarity index 55% rename from 034_search_for_a_range/range_search.c rename to 0034_search_for_a_range/range_search.c index 115c0e1..ddc89d5 100644 --- a/034_search_for_a_range/range_search.c +++ b/0034_search_for_a_range/range_search.c @@ -1,43 +1,43 @@ #include #include -static int binary_search_start(int *a, int size, int target) +static int binary_search_begin(int *a, int size, int target) { - int low = -1; - int high = size; - while (low + 1 < high) { - int mid = low + (high - low) / 2; + int lo = -1; + int hi = size; + while (lo + 1 < hi) { + int mid = lo + (hi - lo) / 2; if (target > a[mid]) { - low = mid; + lo = mid; } else { - high = mid; + hi = mid; } } - if (high == size || a[high] != target) { + if (hi == size || a[hi] != target) { return -1; } else { - return high; + return hi; } } static int binary_search_end(int *a, int size, int target) { - int low = -1; - int high = size; - while (low + 1 < high) { - int mid = low + (high - low) / 2; + int lo = -1; + int hi = size; + while (lo + 1 < hi) { + int mid = lo + (hi - lo) / 2; if (target < a[mid]) { - high = mid; + hi = mid; } else { - low = mid; + lo = mid; } } - if (low == -1 || a[low] != target) { + if (lo == -1 || a[lo] != target) { return -1; } else { - return low; + return lo; } } @@ -45,17 +45,12 @@ static int binary_search_end(int *a, int size, int target) ** Return an array of size *returnSize. ** Note: The returned array must be malloced, assume caller calls free(). **/ -int* searchRange(int* nums, int numsSize, int target, int* returnSize) { +static int* searchRange(int* nums, int numsSize, int target, int* returnSize) +{ int *range = malloc(2 * sizeof(int)); - - if (numsSize == 0) { - range[0] = range[1] = -1; - return range; - } - - range[0] = binary_search_start(nums, numsSize, target); - range[1] = binary_search_end(nums, numsSize, target); *returnSize = 2; + range[0] = binary_search_begin(nums, numsSize, target); + range[1] = binary_search_end(nums, numsSize, target); return range; } diff --git a/0034_search_for_a_range/range_search.cc b/0034_search_for_a_range/range_search.cc new file mode 100644 index 0000000..28565a3 --- /dev/null +++ b/0034_search_for_a_range/range_search.cc @@ -0,0 +1,54 @@ +#include + +using namespace std; + +class Solution { +public: + vector searchRange(vector& nums, int target) { + vector res; + res.push_back(binary_search_begin(nums, target)); + res.push_back(binary_search_end(nums, target)); + return res; + } + +private: + int binary_search_begin(vector nums, int target) + { + int lo = -1; + int hi = nums.size(); + while (lo + 1 < hi) { + int mid = lo + (hi - lo) / 2; + if (target > nums[mid]) { + lo = mid; + } else { + hi = mid; + } + } + + if (hi == nums.size() || nums[hi] != target) { + return -1; + } else { + return hi; + } + } + + int binary_search_end(vector nums, int target) + { + int lo = -1; + int hi = nums.size(); + while (lo + 1 < hi) { + int mid = lo + (hi - lo) / 2; + if (target < nums[mid]) { + hi = mid; + } else { + lo = mid; + } + } + + if (lo == -1 || nums[lo] != target) { + return -1; + } else { + return lo; + } + } +}; diff --git a/0035_search_insert_position/Makefile b/0035_search_insert_position/Makefile new file mode 100644 index 0000000..a86bd9f --- /dev/null +++ b/0035_search_insert_position/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test insert_position.c diff --git a/035_search_insert_position/insert_position.c b/0035_search_insert_position/insert_position.c similarity index 89% rename from 035_search_insert_position/insert_position.c rename to 0035_search_insert_position/insert_position.c index 2d6db79..7533bc4 100644 --- a/035_search_insert_position/insert_position.c +++ b/0035_search_insert_position/insert_position.c @@ -1,7 +1,8 @@ #include #include -static int searchInsert(int* nums, int numsSize, int target) { +static int searchInsert(int* nums, int numsSize, int target) +{ int low = -1; int high = numsSize; while (low + 1 < high) { diff --git a/0035_search_insert_position/insert_position.cc b/0035_search_insert_position/insert_position.cc new file mode 100644 index 0000000..947a0eb --- /dev/null +++ b/0035_search_insert_position/insert_position.cc @@ -0,0 +1,20 @@ +#include + +using namespace std; + +class Solution { +public: + int searchInsert(vector& nums, int target) { + int lo = -1; + int hi = nums.size(); + while (lo + 1 < hi) { + int mid = lo + (hi - lo) / 2; + if (target > nums[mid]) { + lo = mid; + } else { + hi = mid; + } + } + return hi; + } +}; diff --git a/0036_valid_sudoku/Makefile b/0036_valid_sudoku/Makefile new file mode 100644 index 0000000..8564020 --- /dev/null +++ b/0036_valid_sudoku/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test valid_sudoku.c diff --git a/0036_valid_sudoku/valid_sudoku.c b/0036_valid_sudoku/valid_sudoku.c new file mode 100644 index 0000000..aaf2962 --- /dev/null +++ b/0036_valid_sudoku/valid_sudoku.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include + + +static bool valid(char **board, char *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; +} + +bool isValidSudoku(char** board, int boardSize, int* boardColSize) +{ + int i, j, k; + + /* check row validity */ + for (i = 0; i < boardSize; i++) { + char mark[10] = { '\0' }; + for (j = 0; j < boardColSize[i]; j++) { + if (!valid(board, mark, i, j)) { + return false; + } + } + } + + /* check column validity */ + for (j = 0; j < boardColSize[0]; j++) { + char mark[10] = { '\0' }; + for (i = 0; i < boardSize; i++) { + if (!valid(board, mark, i, j)) { + return false; + } + } + } + + /* check sub-box validity */ + for (k = 0; k < boardSize; k++) { + int sr = k / 3 * 3; + int sc = (k % 3) * 3; + char mark[10] = { '\0' }; + for (i = sr; i < sr + 3; i++) { + for (j = sc; j < sc + 3; j++) { + if (!valid(board, mark, i, j)) { + return false; + } + } + } + } + + return true; +} + +int main(int argc, char **argv) +{ + int i, j; + char *str = argv[1]; + int *col_sizes = malloc(9 * sizeof(int)); + char **board = malloc(9 * sizeof(char *)); + for (i = 0; i < 9; i++) { + board[i] = malloc(10); + strcpy(board[i], str + i * 9); + for (j = 0; j < 9; j++) { + printf("%c ", board[i][j]); + } + col_sizes[i] = 9; + printf("\n"); + } + + printf("%s\n", isValidSudoku(board, 9, col_sizes) ? "true" : "false"); + for (i = 0; i < 9; i++) { + for (j = 0; j < 9; j++) { + printf("%c ", board[i][j]); + } + printf("\n"); + } + + return 0; +} 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/0037_sudoku_solver/Makefile b/0037_sudoku_solver/Makefile new file mode 100644 index 0000000..bdb9f00 --- /dev/null +++ b/0037_sudoku_solver/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test sudoku_solver.c diff --git a/037_sudoku_solver/sudoku_solver.c b/0037_sudoku_solver/sudoku_solver.c similarity index 53% rename from 037_sudoku_solver/sudoku_solver.c rename to 0037_sudoku_solver/sudoku_solver.c index c942bea..1c4aae9 100644 --- a/037_sudoku_solver/sudoku_solver.c +++ b/0037_sudoku_solver/sudoku_solver.c @@ -3,118 +3,85 @@ #include #include -struct stack { - int row; - int col; - int value; -}; - -static bool valid(char **board, int row, int col) +static bool valid(int num, int row, int col, int index, + bool **rows, bool **cols, bool **boxes) { - int i, j, k; - char mark[10]; - - for (i = 0; i <= row; i++) { - memset(mark, 0, 10); - /* check row validity */ - for (j = 0; j < 9; j++) { - if (board[i][j] != '.') { - int index = board[i][j] - '0'; - if (mark[index]) { - return false; - } else { - mark[index] = 1; - } - } - } - } - - /* check column validity */ - for (i = 0; i <= col; i++) { - memset(mark, 0, 10); - for (j = 0; j < 9; j++) { - if (board[j][i] != '.') { - int index = board[j][i] - '0'; - if (mark[index]) { - return false; - } else { - mark[index] = 1; - } - } - } - } + return !rows[row][num] && !cols[col][num] && !boxes[index][num]; +} - /* check sub-box validity */ - int count = row / 3 * 3 + col / 3 + 1; - for (k = 0; k < count; k++) { - int sr = k / 3 * 3; - int sc = (k % 3) * 3; - memset(mark, 0, 10); - for (i = sr; i < sr + 3; i++) { - for (j = sc; j < sc + 3; j++) { - if (board[i][j] != '.') { - int index = board[i][j] - '0'; - if (mark[index]) { - return false; - } else { - mark[index] = 1; +static bool dfs(char** board, int size, bool **rows, bool **cols, bool **boxes) +{ + if (size == 9 * 9) { + return true; + } else { + int i; + bool ok = false; + int row = size / 9; + int col = size % 9; + int index = row / 3 * 3 + col / 3; + if (board[row][col] == '.') { + for (i = 1; i <= 9; i++) { + if (valid(i, row, col, index, 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[index][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[index][i] = false; + board[row][col] = '.'; } } } + } else { + ok = dfs(board, size + 1, rows, cols, boxes); } + return ok; } - - return true; } -static void solveSudoku(char** board, int boardRowSize, int boardColSize) +void solveSudoku(char** board, int boardSize, int *boardColSize) { - if (boardRowSize != 9 || boardColSize != 9) { - return; + int i, j; + bool **rows = malloc(boardSize * sizeof(bool *)); + bool **cols = malloc(boardSize * sizeof(bool *)); + bool **boxes = malloc(boardSize * sizeof(bool *)); + + for (i = 0; i < boardSize; i++) { + rows[i] = malloc(10 * sizeof(bool)); + cols[i] = malloc(10 * sizeof(bool)); + boxes[i] = malloc(10 * sizeof(bool)); + memset(rows[i], false, 10 * sizeof(bool)); + memset(cols[i], false, 10 * sizeof(bool)); + memset(boxes[i], false, 10 * sizeof(bool)); } - int i = 0, j = 0, k = 1, num = 0; - struct stack stack[81]; - - while (i < boardRowSize) { - if (board[i][j] == '.') { - while (k <= 9) { - board[i][j] = k + '0'; - if (valid(board, i, j)) { - stack[num].row = i; - stack[num].col = j; - stack[num].value = k; - num++; - k = 1; - break; - } - k++; - } - if (k == 10) { - if (num == 0) { - return; - } - board[i][j] = '.'; - --num; - i = stack[num].row; - j = stack[num].col; - k = stack[num].value + 1; - board[i][j] = '.'; - continue; + /* Mark whether the grid is available for the number */ + for (i = 0; i < boardSize; i++) { + for (j = 0; j < boardColSize[i]; j++) { + if (board[i][j] != '.') { + int num = board[i][j] - '0'; + int index = i / 3 * 3 + j / 3; + rows[i][num] = true; + cols[j][num] = true; + boxes[index][num] = true; } } - /* next row */ - if (++j == boardColSize) { - j = 0; - i++; - } } + + dfs(board, 0, rows, cols, boxes); } int main(void) { int i, j; char **board = malloc(9 * sizeof(char *)); + int *col_sizes = malloc(9 * sizeof(int)); + board[0] = malloc(10); board[0][0] = '5'; board[0][1] = '3'; @@ -126,6 +93,7 @@ int main(void) board[0][7] = '.'; board[0][8] = '.'; board[0][9] = '\0'; + col_sizes[0] = 9; board[1] = malloc(10); board[1][0] = '6'; @@ -138,6 +106,7 @@ int main(void) board[1][7] = '.'; board[1][8] = '.'; board[1][9] = '\0'; + col_sizes[1] = 9; board[2] = malloc(10); board[2][0] = '.'; @@ -150,6 +119,7 @@ int main(void) board[2][7] = '6'; board[2][8] = '.'; board[2][9] = '\0'; + col_sizes[2] = 9; board[3] = malloc(10); board[3][0] = '8'; @@ -162,6 +132,7 @@ int main(void) board[3][7] = '.'; board[3][8] = '3'; board[3][9] = '\0'; + col_sizes[3] = 9; board[4] = malloc(10); board[4][0] = '4'; @@ -174,6 +145,7 @@ int main(void) board[4][7] = '.'; board[4][8] = '1'; board[4][9] = '\0'; + col_sizes[4] = 9; board[5] = malloc(10); board[5][0] = '7'; @@ -186,6 +158,7 @@ int main(void) board[5][7] = '.'; board[5][8] = '6'; board[5][9] = '\0'; + col_sizes[5] = 9; board[6] = malloc(10); board[6][0] = '.'; @@ -198,6 +171,7 @@ int main(void) board[6][7] = '8'; board[6][8] = '.'; board[6][9] = '\0'; + col_sizes[6] = 9; board[7] = malloc(10); board[7][0] = '.'; @@ -210,6 +184,7 @@ int main(void) board[7][7] = '.'; board[7][8] = '5'; board[7][9] = '\0'; + col_sizes[7] = 9; board[8] = malloc(10); board[8][0] = '.'; @@ -222,6 +197,7 @@ int main(void) board[8][7] = '7'; board[8][8] = '9'; board[8][9] = '\0'; + col_sizes[8] = 9; for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { @@ -230,12 +206,14 @@ int main(void) printf("\n"); } printf("\n"); - solveSudoku(board, 9, 9); + + solveSudoku(board, 9, col_sizes); for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { printf("%c ", board[i][j]); } printf("\n"); } - return; + + return 0; } 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/0038_count_and_say/Makefile b/0038_count_and_say/Makefile new file mode 100644 index 0000000..14c94b0 --- /dev/null +++ b/0038_count_and_say/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test count_and_say.c 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/0039_combination_sum/Makefile b/0039_combination_sum/Makefile new file mode 100644 index 0000000..dafaf31 --- /dev/null +++ b/0039_combination_sum/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test combination_sum.c diff --git a/0039_combination_sum/combination_sum.c b/0039_combination_sum/combination_sum.c new file mode 100644 index 0000000..0fcb96b --- /dev/null +++ b/0039_combination_sum/combination_sum.c @@ -0,0 +1,65 @@ +#include +#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) { + return; + } else if (target == 0) { + results[*count] = malloc(len * sizeof(int)); + memcpy(results[*count], stack, len * sizeof(int)); + column_sizes[*count] = len; + (*count)++; + } else { + for (i = start; i < size; i++) { + stack[len] = nums[i]; + /* 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); + } + } +} + +/** + ** 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** combinationSum(int* candidates, int candidatesSize, int target, int* returnSize, int **returnColumnSizes) +{ + int cap = 200; + int *stack = malloc(cap * sizeof(int)); + int **results = malloc(cap * sizeof(int *)); + *returnColumnSizes = malloc(cap * sizeof(int)); + *returnSize = 0; + dfs(candidates, candidatesSize, 0, target, stack, 0, results, returnSize, *returnColumnSizes); + return results; +} + +int main(int argc, char **argv) +{ + if (argc < 3) { + fprintf(stderr, "Usage: ./test target n1 n2...\n"); + exit(-1); + } + + int i, j, count = 0; + int target = atoi(argv[1]); + int *nums = malloc((argc - 2) * sizeof(int)); + for (i = 0; i < argc - 2; i++) { + nums[i] = atoi(argv[i + 2]); + } + + int *sizes; + int **lists = combinationSum(nums, argc - 2, target, &count, &sizes); + for (i = 0; i < count; i++) { + for (j = 0; j < sizes[i]; j++) { + printf("%d ", lists[i][j]); + } + printf("\n"); + } + return 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/Makefile b/003_longest_substring_without_repeat/Makefile deleted file mode 100644 index b5dda9e..0000000 --- a/003_longest_substring_without_repeat/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test longest_substring_without_repeat.c 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 52284b3..0000000 --- a/003_longest_substring_without_repeat/longest_substring_without_repeat.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include -#include - -static int lengthOfLongestSubstring(char *s) { - int offset[128]; - int max_len = 0; - char *p, *q; - int len = 0; - memset(offset, 0xff, sizeof(offset)); - for (p = s; *p != '\0'; p++) { - for (q = p; *q != '\0'; q++) { - if (offset[*q] == -1) { - offset[*q] = q - s; - if (++len > max_len) { - max_len = len; - } - } else { - len = 0; - p = offset[*q] + s; - memset(offset, 0xff, sizeof(offset)); - break; - } - } - } - return max_len; -} - -int main(int argc, char **argv) -{ - printf("%d\n", lengthOfLongestSubstring(argv[1])); - return 0; -} diff --git a/0040_combination_sum_ii/Makefile b/0040_combination_sum_ii/Makefile new file mode 100644 index 0000000..dafaf31 --- /dev/null +++ b/0040_combination_sum_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test combination_sum.c diff --git a/0040_combination_sum_ii/combination_sum.c b/0040_combination_sum_ii/combination_sum.c new file mode 100644 index 0000000..4623149 --- /dev/null +++ b/0040_combination_sum_ii/combination_sum.c @@ -0,0 +1,78 @@ +#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, int **results, int *count, int *col_sizes) +{ + int i; + if (target < 0) { + return; + } else if (target == 0) { + results[*count] = malloc(len * sizeof(int)); + memcpy(results[*count], solution, len * sizeof(int)); + col_sizes[*count] = len; + (*count)++; + } else { + int last = INT_MIN; + for (i = start; i < size; i++) { + if (last != nums[i]) { + /* No duplicate combinations in the same level position */ + solution[len] = nums[i]; + /* i + 1 limits the candidate range in next levels */ + dfs(nums, size, i + 1, target - nums[i], solution, len + 1, results, count, col_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 *returnColumnSizes array must be malloced, assume caller calls free(). + **/ +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 *)); + *returnColumnSizes = malloc(100 * sizeof(int)); + *returnSize = 0; + dfs(candidates, candidatesSize, 0, target, solution, 0, results, returnSize, *returnColumnSizes); + return results; +} + +int main(int argc, char **argv) +{ + if (argc < 3) { + fprintf(stderr, "Usage: ./test target n1 n2...\n"); + exit(-1); + } + + int i, j, count = 0; + int target = atoi(argv[1]); + int *nums = malloc((argc - 2) * sizeof(int)); + for (i = 0; i < argc - 2; i++) { + nums[i] = atoi(argv[i + 2]); + } + + int *sizes; + int **lists = combinationSum(nums, argc - 2, target, &count, &sizes); + for (i = 0; i < count; i++) { + for (j = 0; j < sizes[i]; j++) { + printf("%d ", lists[i][j]); + } + printf("\n"); + } + return 0; +} 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/0041_first_missing_positive/Makefile b/0041_first_missing_positive/Makefile new file mode 100644 index 0000000..d536d9b --- /dev/null +++ b/0041_first_missing_positive/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test missing_positive.c diff --git a/041_first_missing_positive/missing_positive.c b/0041_first_missing_positive/missing_positive.c similarity index 64% rename from 041_first_missing_positive/missing_positive.c rename to 0041_first_missing_positive/missing_positive.c index 4e23b3f..974263d 100644 --- a/041_first_missing_positive/missing_positive.c +++ b/0041_first_missing_positive/missing_positive.c @@ -1,21 +1,24 @@ #include #include -static void swap(int *a, int *b) +static inline void swap(int *a, int *b) { int tmp = *a; *a = *b; *b = tmp; } -static int firstMissingPositive(int* nums, int numsSize) { - if (numsSize < 1) { +static int firstMissingPositive(int* nums, int numsSize) +{ + if (numsSize == 0) { return 1; } int i = 0; while (i < numsSize) { - if (nums[i] != i + 1 && nums[i] > 0 && nums[i] <= numsSize && nums[i] != nums[nums[i] - 1]) { + /* 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]) { + /* let nums[nums[i] - 1] = nums[i] */ swap(nums + i, nums + nums[i] - 1); } else { i++; @@ -23,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/0042_trapping_rain_water/Makefile b/0042_trapping_rain_water/Makefile new file mode 100644 index 0000000..79f7d1f --- /dev/null +++ b/0042_trapping_rain_water/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test trap_water.c 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/0043_multiply_strings/Makefile b/0043_multiply_strings/Makefile new file mode 100644 index 0000000..237fde9 --- /dev/null +++ b/0043_multiply_strings/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test multiply_strings.c 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..0ca6c59 --- /dev/null +++ b/0043_multiply_strings/multiply_strings.cc @@ -0,0 +1,33 @@ +#include + +using namespace std; + +class Solution { +public: + string multiply(string num1, string num2) { + vector v(num1.length() + num2.length()); + for (int i = num2.length() - 1; i >= 0; i--) { + for (int j = num1.length() - 1; j >= 0; j--) { + int a = num2[j] - '0'; + int b = num1[i] - '0'; + v[i + j + 1] = a * b; + } + } + + int i, carry = 0; + string res(v.size(), '0'); + for (i = v.size() - 1; i >= 0; i--) { + carry += v[i]; + res[i] += carry % 10; + carry /= 10; + } + + for (i = 0; i < res.length() - 1; i++) { + if (res[i] != '0') { + break; + } + } + + return res.substr(i); + } +}; diff --git a/0044_wildcard_matching/Makefile b/0044_wildcard_matching/Makefile new file mode 100644 index 0000000..8283d7f --- /dev/null +++ b/0044_wildcard_matching/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test wildcard_matching.c 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/0045_jump_game_ii/Makefile b/0045_jump_game_ii/Makefile new file mode 100644 index 0000000..d1332e7 --- /dev/null +++ b/0045_jump_game_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test jump_game.c 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/0046_permutations/Makefile b/0046_permutations/Makefile new file mode 100644 index 0000000..ba5645a --- /dev/null +++ b/0046_permutations/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test permutations.c diff --git a/0046_permutations/permutations.c b/0046_permutations/permutations.c new file mode 100644 index 0000000..49b0b73 --- /dev/null +++ b/0046_permutations/permutations.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include + +#if 0 +static void swap(int *a, int *b) +{ + int tmp = *a; + *a = *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) +{ + int i; + if (len == size) { + results[*count] = malloc(size * sizeof(int)); + memcpy(results[*count], stack, size * sizeof(int)); + col_size[*count] = size; + (*count)++; + 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; + } + } +} + +/** + * 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** permute(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) +{ + int count = 0, cap = 5000; + int **results = malloc(cap * sizeof(int *)); + bool *used = malloc(numsSize * sizeof(bool)); + int *stack = malloc(numsSize * sizeof(int)); + *returnSize = 0; + *returnColumnSizes = malloc(cap * sizeof(int)); + memset(used, false, numsSize * sizeof(bool)); + dfs(nums, numsSize, used, stack, 0, results, returnSize, *returnColumnSizes); + return results; +} + +int main(int argc, char **argv) +{ + if (argc <= 1) { + fprintf(stderr, "Usage: ./test ...\n"); + exit(-1); + } + + int i, j, count = argc - 1; + int *nums = malloc(count * sizeof(int)); + for (i = 0; i < count; i++) { + nums[i] = atoi(argv[i + 1]); + } + + int *col_sizes; + int **lists = permute(nums, argc - 1, &count, &col_sizes); + for (i = 0; i < count; i++) { + for (j = 0; j < col_sizes[i]; j++) { + printf("%d", lists[i][j]); + } + putchar('\n'); + } + + return 0; +} 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/0047_permutations_ii/Makefile b/0047_permutations_ii/Makefile new file mode 100644 index 0000000..ba5645a --- /dev/null +++ b/0047_permutations_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test permutations.c diff --git a/0047_permutations_ii/permutations.c b/0047_permutations_ii/permutations.c new file mode 100644 index 0000000..612867b --- /dev/null +++ b/0047_permutations_ii/permutations.c @@ -0,0 +1,85 @@ +#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, 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)++; + 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; + } + } +} + +/** + * 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 **permute(int* nums, int numsSize, int* returnSize, int **returnColumnSize) +{ + qsort(nums, numsSize, sizeof(int), compare); + + int count = 0, cap = 10000; + int *stack = malloc(numsSize * sizeof(int)); + int **results = malloc(cap * sizeof(int *)); + 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); + return results; +} + +int main(int argc, char **argv) +{ + if (argc <= 1) { + fprintf(stderr, "Usage: ./test ...\n"); + exit(-1); + } + + int i, j, count = argc - 1; + int *nums = malloc(count * sizeof(int)); + for (i = 0; i < count; i++) { + nums[i] = atoi(argv[i + 1]); + } + + int *col_sizes; + int **lists = permute(nums, argc - 1, &count, &col_sizes); + for (i = 0; i < count; i++) { + for (j = 0; j < col_sizes[i]; j++) { + printf("%d", lists[i][j]); + } + putchar('\n'); + } + + return 0; +} 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/0048_rotate_image/Makefile b/0048_rotate_image/Makefile new file mode 100644 index 0000000..ab13146 --- /dev/null +++ b/0048_rotate_image/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test rotate.c 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/0049_group_anagrams/Makefile b/0049_group_anagrams/Makefile new file mode 100644 index 0000000..ce82d29 --- /dev/null +++ b/0049_group_anagrams/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test anagrams.c diff --git a/0049_group_anagrams/anagrams.c b/0049_group_anagrams/anagrams.c new file mode 100644 index 0000000..fb9765f --- /dev/null +++ b/0049_group_anagrams/anagrams.c @@ -0,0 +1,84 @@ +#include +#include +#include + + +struct word_hash { + char *word; + int num; + int indexes[10]; +}; + +static int compare(const void *a, const void *b) +{ + return *(char *) a - *(char *) b; +} + +static inline int BKDRHash(char *s, size_t size) +{ + int seed = 31; /* 131 1313 13131... */ + unsigned long hash = 0; + while (*s != '\0') { + hash = hash * seed + *s++; + } + return hash % size; +} + +/** + ** 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(). + **/ +char*** groupAnagrams(char** strs, int strsSize, int* returnSize, int** returnColumnSizes) +{ + int i, j, count = 0; + int hash_size = strsSize; + struct word_hash *ht = calloc(hash_size, sizeof(*ht)); + + char **words = malloc(strsSize * sizeof(char *)); + for (i = 0; i < strsSize; i++) { + int len = strlen(strs[i]); + words[i] = malloc(len + 1); + strcpy(words[i], strs[i]); + 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 + 1) % hash_size) {} + if (ht[j].num == 0) { + ht[j].word = words[i]; + count++; + } + ht[j].indexes[ht[j].num++] = i; + } + + int k = 0; + char ***lists = malloc(count * sizeof(char **)); + *returnColumnSizes = malloc(count * sizeof(int)); + for (i = 0; i < hash_size; i++) { + if (ht[i].num > 0) { + (*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]; + lists[k][j] = strs[index]; + } + k++; + } + } + + *returnSize = count; + return lists; +} + +int main(int argc, char **argv) +{ + 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 < col_sizes[i]; j++) { + printf("%s ", lists[i][j]); + } + printf("\n"); + } + return 0; +} 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/004_median_of_two_sorted_array/Makefile b/004_median_of_two_sorted_array/Makefile deleted file mode 100644 index 6fb3d51..0000000 --- a/004_median_of_two_sorted_array/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test median_of_two_sorted_array.c diff --git a/0050_pow/Makefile b/0050_pow/Makefile new file mode 100644 index 0000000..f5d61b6 --- /dev/null +++ b/0050_pow/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test pow.c diff --git a/0050_pow/pow.c b/0050_pow/pow.c new file mode 100644 index 0000000..065e92f --- /dev/null +++ b/0050_pow/pow.c @@ -0,0 +1,31 @@ +#include +#include +#include + + +double fast_pow(double x, int n) +{ + if (n == 0) { return 1.0; } + if (n == 1) { return x; } + double t = fast_pow(x, n / 2); + return n & 1 ? t * t * x : t * t; +} + +double my_pow(double x, int n) +{ + if (n == INT_MIN) { + double t = 1 / fast_pow(x, -(n / 2)); + return t * t; + } + return n < 0 ? 1 / fast_pow(x, -n) : fast_pow(x, n); +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./test x n\n"); + exit(-1); + } + printf("%lf\n", my_pow(atoi(argv[1]), atoi(argv[2]))); + return 0; +} 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/0051_n_queens/Makefile b/0051_n_queens/Makefile new file mode 100644 index 0000000..008246e --- /dev/null +++ b/0051_n_queens/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test n_queens.c diff --git a/051_n_queens/n_queens.c b/0051_n_queens/n_queens.c similarity index 64% rename from 051_n_queens/n_queens.c rename to 0051_n_queens/n_queens.c index f01dc63..5892c12 100644 --- a/051_n_queens/n_queens.c +++ b/0051_n_queens/n_queens.c @@ -1,18 +1,18 @@ +#include #include #include #include -static inline int conflict(int *stack, int i, int j) +static inline int conflict(int *stack, int row, int col) { - int k; - for (k = 0; k < i; k++) { + int i; + for (i = 0; i < row; i++) { /* If occupied or in one line */ - if (j == stack[k] || abs(i - k) == abs(j - stack[k])) { - return 1; + if (col == stack[i] || abs(row - i) == abs(col - stack[i])) { + return true; } } - - return 0; + return false; } static inline void push(int *stack, int row, int col) @@ -35,11 +35,10 @@ static inline int top(int *stack, int n) return row; } } - return 0; } -static char **solution(int *stack, int n) +static char **solute(int *stack, int n) { int row, col; char **solution = malloc(n * sizeof(char *)); @@ -54,23 +53,49 @@ static char **solution(int *stack, int n) return solution; } +static void dfs(int n, int row, int *stack, char ***solutions, int *count, int *col_sizes) +{ + int col; + if (row == n) { + solutions[*count] = solute(stack, n); + col_sizes[*count] = n; + (*count)++; + } else { + for (col = 0; col < n; col++) { + if (row == 0 || !conflict(stack, row, col)) { + stack[row] = col; + dfs(n, row + 1, stack, solutions, count, col_sizes); + } + } + } +} + /** - ** Return an array of arrays of size *returnSize. - ** Note: The returned array must be malloced, assume caller calls free(). - **/ -char*** solveNQueens(int n, 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(). + */ +char *** solveNQueens(int n, int* returnSize, int** returnColumnSizes) +{ int row = 0, col = 0, sum = 0; char ***solutions = malloc(1000 * sizeof(char **)); - + *returnColumnSizes = malloc(1000 * sizeof(int)); int *stack = malloc(n * sizeof(int)); + +#if 1 + *returnSize = 0; + dfs(n, 0, stack, solutions, returnSize, *returnColumnSizes); + return solutions; +#else for (row = 0; row < n; row++) { stack[row] = -1; } if (n == 1) { stack[0] = 0; - solutions[0] = solution(stack, n); + solutions[0] = solute(stack, n); *returnSize = 1; + *returnColumnSizes[0] = 1; return solutions; } @@ -82,7 +107,6 @@ char*** solveNQueens(int n, int *returnSize) { /* No other positions in this row and therefore backtracking */ if (--row < 0) { /* All solution provided */ - free(stack); *returnSize = sum; return solutions; } @@ -100,7 +124,9 @@ char*** solveNQueens(int n, int *returnSize) { /* Full stack, a new complete solution */ row = top(stack, n); if (row == n - 1) { - solutions[sum++] = solution(stack, n); + solutions[sum] = solute(stack, n); + (*returnColumnSizes)[sum] = n; + sum++; } /* Move on to find if there are still other solutions */ @@ -109,6 +135,7 @@ char*** solveNQueens(int n, int *returnSize) { } assert(0); +#endif } int main(int argc, char **argv) @@ -121,7 +148,8 @@ int main(int argc, char **argv) } n = atoi(argv[1]); - char ***solutions = solveNQueens(n, &num_of_solution); + int *col_sizes; + char ***solutions = solveNQueens(n, &num_of_solution, &col_sizes); for (i = 0; i < num_of_solution; i++) { char **solution = solutions[i]; for (row = 0; row < n; row++) { 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/0052_n_queens_ii/Makefile b/0052_n_queens_ii/Makefile new file mode 100644 index 0000000..008246e --- /dev/null +++ b/0052_n_queens_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test n_queens.c diff --git a/052_n_queens/n_queens.c b/0052_n_queens_ii/n_queens.c similarity index 73% rename from 052_n_queens/n_queens.c rename to 0052_n_queens_ii/n_queens.c index e093550..17f387b 100644 --- a/052_n_queens/n_queens.c +++ b/0052_n_queens_ii/n_queens.c @@ -1,16 +1,19 @@ +#include #include #include #include -static inline int conflict(int *stack, int i, int j) + + +static inline int conflict(int *stack, int row, int col) { - int k; - for (k = 0; k < i; k++) { + int i; + for (i = 0; i < row; i++) { /* If occupied or in one line */ - if (j == stack[k] || abs(i - k) == abs(j - stack[k])) { - return 1; + if (col == stack[i] || abs(row - i) == abs(col - stack[i])) { + return true; } } - return 0; + return false; } static inline void push(int *stack, int row, int col) @@ -36,7 +39,28 @@ static inline int top(int *stack, int n) return 0; } +static void dfs(int n, int row, int *stack, int *count) +{ + int col; + if (row == n) { + (*count)++; + } else { + for (col = 0; col < n; col++) { + if (row == 0 || !conflict(stack, row, col)) { + stack[row] = col; + dfs(n, row + 1, stack, count); + } + } + } +} + int totalNQueens(int n) { +#if 1 + int count = 0; + int *stack = malloc(n * sizeof(int)); + dfs(n, 0, stack, &count); + return count; +#else int row = 0, col = 0, sum = 0, cap = 1; int *stack = malloc(n * sizeof(int)); for (row = 0; row < n; row++) { @@ -79,6 +103,7 @@ int totalNQueens(int n) { col = pop(stack, row); col++; } +#endif } int main(int argc, char **argv) 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/0053_maximum_subarray/Makefile b/0053_maximum_subarray/Makefile new file mode 100644 index 0000000..7eae3f9 --- /dev/null +++ b/0053_maximum_subarray/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test max_subarray.c diff --git a/053_maximum_subarray/max_subarray.c b/0053_maximum_subarray/max_subarray.c similarity index 69% rename from 053_maximum_subarray/max_subarray.c rename to 0053_maximum_subarray/max_subarray.c index fe4b3ba..885ce6b 100644 --- a/053_maximum_subarray/max_subarray.c +++ b/0053_maximum_subarray/max_subarray.c @@ -2,15 +2,15 @@ #include #include -static int recursive(int *nums, int lo, int hi) +static int partition(int *nums, int lo, int hi) { if (lo == hi) { return nums[lo]; } int ce = (hi - lo) / 2; - int left_max = recursive(nums, lo, lo + ce); - int right_max = recursive(nums, hi - ce, hi); + int left_max = partition(nums, lo, lo + ce); + int right_max = partition(nums, hi - ce, hi); int i; int left_border = 0, left_border_max = INT_MIN; @@ -37,18 +37,20 @@ static int recursive(int *nums, int lo, int hi) static int maxSubArray(int* nums, int numsSize) { #if 1 - int i, len = 0, max = INT_MIN; + int i, sum = 0, max = INT_MIN; for (i = 0; i < numsSize; i++) { - len += nums[i]; - /* Calculate maximum each time in loop */ - max = len > max ? len : max; - if (len < 0) { - len = 0; + /* dp indicates the optimical result of nums[0...i] + * dp[i] = max(dp[i-1], 0) + nums[i] */ + if (sum < 0) { + sum = nums[i]; + } else { + sum += nums[i]; } + max = sum > max ? sum : max; } return max; #else - return recursive(nums, 0, numsSize - 1); + return partition(nums, 0, numsSize - 1); #endif } 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/0054_spiral_matrix/Makefile b/0054_spiral_matrix/Makefile new file mode 100644 index 0000000..1f55502 --- /dev/null +++ b/0054_spiral_matrix/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test spiral_matrix.c diff --git a/054_spiral_matrix/spiral_matrix.c b/0054_spiral_matrix/spiral_matrix.c similarity index 69% rename from 054_spiral_matrix/spiral_matrix.c rename to 0054_spiral_matrix/spiral_matrix.c index 65e8ed1..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("%d ", mat[i][j]); } -printf("\n"); + 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/0055_jump_game/Makefile b/0055_jump_game/Makefile new file mode 100644 index 0000000..d1332e7 --- /dev/null +++ b/0055_jump_game/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test jump_game.c diff --git a/0055_jump_game/jump_game.c b/0055_jump_game/jump_game.c new file mode 100644 index 0000000..66e454b --- /dev/null +++ b/0055_jump_game/jump_game.c @@ -0,0 +1,34 @@ +#include +#include +#include + +static inline int max(int a, int b) +{ + return a > b ? a : b; +} + +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. */ + pos = max(i + nums[i], pos); + } + + return pos >= numsSize - 1; +} + +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("%s\n", canJump(nums, count) ? "true" : "false"); + return 0; +} diff --git a/0056_merge_intervals/Makefile b/0056_merge_intervals/Makefile new file mode 100644 index 0000000..ff7462d --- /dev/null +++ b/0056_merge_intervals/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test merge_intervals.c diff --git a/0056_merge_intervals/merge_intervals.c b/0056_merge_intervals/merge_intervals.c new file mode 100644 index 0000000..133a778 --- /dev/null +++ b/0056_merge_intervals/merge_intervals.c @@ -0,0 +1,78 @@ +#include +#include +#include + + +static int compare(const void *a, const void *b) +{ + return ((int *) a)[0] - ((int *) b)[0]; +} + +/** + * 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** merge(int** intervals, int intervalsSize, int* intervalsColSize, int* returnSize, int** returnColumnSizes) +{ + if (intervalsSize == 0) { + *returnSize = 0; + return intervals; + } + + int i, len = 0; + int *tmp = malloc(intervalsSize * 2 * sizeof(int)); + for (i = 0; i < intervalsSize; i++) { + tmp[i * 2] = intervals[i][0]; + tmp[i * 2 + 1] = intervals[i][1]; + } + qsort(tmp, intervalsSize, 2 * sizeof(int), compare); + + intervals[0][0] = tmp[0]; + intervals[0][1] = tmp[1]; + for (i = 1; i < intervalsSize; i++) { + if (tmp[i * 2] > intervals[len][1]) { + len++; + 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]; + } + } + + len += 1; + *returnSize = len; + *returnColumnSizes = malloc(len * sizeof(int)); + for (i = 0; i < len; i++) { + (*returnColumnSizes)[i] = 2; + } + + return intervals; +} + +int main(int argc, char **argv) +{ + if (argc < 1|| argc % 2 == 0) { + fprintf(stderr, "Usage: ./test s0 e0 s1 e1..."); + exit(-1); + } + + int i, count = 0; + int *sizes = malloc((argc - 1) / 2 * sizeof(int)); + int **intervals = malloc((argc - 1) / 2 * sizeof(int *)); + for (i = 0; i < (argc - 1) / 2; i++) { + sizes[i] = 2; + intervals[i] = malloc(2 * sizeof(int)); + intervals[i][0] = atoi(argv[i * 2 + 1]); + intervals[i][1] = atoi(argv[i * 2 + 2]); + } + + int *col_sizes; + int **results = merge(intervals, (argc - 1) / 2, sizes, &count, &col_sizes); + for (i = 0; i < count; i++) { + printf("[%d,%d]\n", results[i][0], results[i][1]); + } + + return 0; +} diff --git a/0057_insert_interval/Makefile b/0057_insert_interval/Makefile new file mode 100644 index 0000000..ce67b1c --- /dev/null +++ b/0057_insert_interval/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test insert_interval.c diff --git a/0057_insert_interval/insert_interval.c b/0057_insert_interval/insert_interval.c new file mode 100644 index 0000000..b97da9a --- /dev/null +++ b/0057_insert_interval/insert_interval.c @@ -0,0 +1,81 @@ +#include +#include + + +static int compare(const void *a, const void *b) +{ + return ((int *) a)[0] - ((int *) b)[0]; +} + +/** + * 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** 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)); + for (i = 0; i < intervalsSize; i++) { + tmp[i * 2] = intervals[i][0]; + tmp[i * 2 + 1] = intervals[i][1]; + } + tmp[i * 2] = newInterval[0]; + tmp[i * 2 + 1] = newInterval[1]; + qsort(tmp, intervalsSize + 1, 2 * sizeof(int), compare); + + int **results = malloc((intervalsSize + 1) * sizeof(int *)); + results[0] = malloc(2 * sizeof(int)); + results[0][0] = tmp[0]; + results[0][1] = tmp[1]; + for (i = 1; i < intervalsSize + 1; i++) { + results[i] = malloc(2 * sizeof(int)); + if (tmp[i * 2] > results[len][1]) { + len++; + 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]; + } + } + + len += 1; + *returnSize = len; + *returnColumnSizes = malloc(len * sizeof(int)); + for (i = 0; i < len; i++) { + (*returnColumnSizes)[i] = 2; + } + + return results; +} + +int main(int argc, char **argv) +{ + if (argc < 3 || argc % 2 == 0) { + fprintf(stderr, "Usage: ./test new_s new_e s0 e0 s1 e1..."); + exit(-1); + } + + int new_interv[2]; + new_interv[0] = atoi(argv[1]); + new_interv[1] = atoi(argv[2]); + + int i, count = 0; + int *size = malloc((argc - 3) / 2 * sizeof(int)); + int **intervals = malloc((argc - 3) / 2 * sizeof(int *)); + for (i = 0; i < (argc - 3) / 2; i++) { + intervals[i] = malloc(2 * sizeof(int)); + intervals[i][0] = atoi(argv[i * 2 + 3]); + intervals[i][1] = atoi(argv[i * 2 + 4]); + } + + int *col_sizes; + int **results = insert(intervals, (argc - 3) / 2, size, new_interv, 2, &count, &col_sizes); + for (i = 0; i < count; i++) { + printf("[%d,%d]\n", results[i][0], results[i][1]); + } + + return 0; +} diff --git a/0058_length_of_last_word/Makefile b/0058_length_of_last_word/Makefile new file mode 100644 index 0000000..f31104a --- /dev/null +++ b/0058_length_of_last_word/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test word_length.c 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/0059_spiral_matrix_ii/Makefile b/0059_spiral_matrix_ii/Makefile new file mode 100644 index 0000000..1f55502 --- /dev/null +++ b/0059_spiral_matrix_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test spiral_matrix.c 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/005_longest_palindromic_substring/Makefile b/005_longest_palindromic_substring/Makefile deleted file mode 100644 index d2434e6..0000000 --- a/005_longest_palindromic_substring/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test longest_palindromic_substring.c diff --git a/005_longest_palindromic_substring/longest_palindromic_substring.c b/005_longest_palindromic_substring/longest_palindromic_substring.c deleted file mode 100644 index 540a9cb..0000000 --- a/005_longest_palindromic_substring/longest_palindromic_substring.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include - -static void find(char *s, int len, int low, int high, int *max_size, char *palindrome) { - while (low >= 0 && high < len && s[low] == s[high]) { - low--; - high++; - } - low++; - high--; - - if (high - low + 1 > *max_size) { - *max_size = high - low + 1; - memcpy(palindrome, s + low, *max_size); - } -} - -static char *longestPalindrom(char *s) { - int i; - if (s == NULL) { - return NULL; - } - - int len = strlen(s); - if (len <= 1) { - return s; - } - - char *palindrome = malloc(1000); - memset(palindrome, 0, sizeof(palindrome)); - - int max_size = 0; - for (i = 0; i < len; i++) { - /* start from the middle and scan both two sides */ - find(s, len, i, i, &max_size, palindrome); - find(s, len, i, i + 1, &max_size, palindrome); - } - - return palindrome; -} - -int main(int argc, char **argv) -{ - if (argc != 2) { - fprintf(stderr, "Usage: ./test string\n"); - exit(-1); - } - printf("%s\n", longestPalindrom(argv[1])); - return 0; -} diff --git a/0060_permutation_sequence/Makefile b/0060_permutation_sequence/Makefile new file mode 100644 index 0000000..59ea6ed --- /dev/null +++ b/0060_permutation_sequence/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test permutation_sequence.c diff --git a/0060_permutation_sequence/permutation_sequence.c b/0060_permutation_sequence/permutation_sequence.c new file mode 100644 index 0000000..2b17558 --- /dev/null +++ b/0060_permutation_sequence/permutation_sequence.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include + +static char* getPermutation(int n, int k) +{ + int i; + char *result = malloc(n + 1); + bool *used = malloc(n * sizeof(bool)); + memset(used, false, n * sizeof(bool)); + + int total = 1; + for (i = 1; i <= n; i++) { + total *= i; /* n! */ + } + + k = k - 1; /* Begin with 0 */ + for (i = 0; i < n; i++) { + /* Total elements in each group */ + total /= (n - i); + int gid = k / total; + k %= total; + + int x = -1; + int count = 0; + /* Search in the remaining numbers */ + while (count <= gid) { + x = (x + 1) % n; + if (!used[x]) { + count++; + } + } + used[x] = true; + result[i] = x + 1 + '0'; + } + + result[n] = '\0'; + return result; +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./test n, k\n"); + exit(-1); + } + + printf("%s\n", getPermutation(atoi(argv[1]), atoi(argv[2]))); + return 0; +} diff --git a/0061_rotate_list/Makefile b/0061_rotate_list/Makefile new file mode 100644 index 0000000..cff17df --- /dev/null +++ b/0061_rotate_list/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test rotate_list.c diff --git a/061_rotate_list/rotate_list.c b/0061_rotate_list/rotate_list.c similarity index 58% rename from 061_rotate_list/rotate_list.c rename to 0061_rotate_list/rotate_list.c index 5e84ef5..ae77398 100644 --- a/061_rotate_list/rotate_list.c +++ b/0061_rotate_list/rotate_list.c @@ -1,71 +1,65 @@ #include #include + struct ListNode { int val; struct ListNode *next; }; -static struct ListNode* rotateRight(struct ListNode* head, int k) { - if (head == NULL || k <= 0) { +struct ListNode* rotateRight(struct ListNode* head, int k) +{ + if (head == NULL) { return head; } + int len = 0; struct ListNode dummy; dummy.next = head; + struct ListNode *tail = &dummy; + while (tail->next != NULL) { + tail = tail->next; + len++; + } + struct ListNode *prev = &dummy; - struct ListNode *last = &dummy; struct ListNode *p = head; - int count = k; - while (k > 0) { - if (p == NULL) { - int length = count - k; - prev = &dummy; - p = head; - k = count % length; - if (k == 0) break; - } + len = len - (k % len); + while (len-- > 0) { prev = p; p = p->next; - k--; } - while (p != NULL) { - last = last->next; - prev = p; - p = p->next; + if (p != NULL) { + /* deletion */ + prev->next = NULL; + /* insertion */ + tail->next = head; + head = p; } - if (last != &dummy) { - prev->next = head; - dummy.next = last->next; - last->next = NULL; - } - 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++) { p = malloc(sizeof(*p)); int n = atoi(argv[i]); - printf("%d ", n); p->val = n; p->next = NULL; prev->next = p; prev = p; } - putchar('\n'); list = rotateRight(dummy.next, atoi(argv[1])); for (p = list; p != NULL; p = p->next) { 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/0062_unique_path/Makefile b/0062_unique_path/Makefile new file mode 100644 index 0000000..9cf8815 --- /dev/null +++ b/0062_unique_path/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test unique_path.c diff --git a/0062_unique_path/unique_path.c b/0062_unique_path/unique_path.c new file mode 100644 index 0000000..2a1a184 --- /dev/null +++ b/0062_unique_path/unique_path.c @@ -0,0 +1,30 @@ +#include +#include + +static int uniquePaths(int m, int n) +{ + int row, col; + int *grids = malloc(m * n * sizeof(int)); + for (col = 0; col < m; col++) { + grids[col] = 1; + } + for (row = 0; row < n; row++) { + grids[row * m] = 1; + } + for (row = 1; row < n; row++) { + for (col = 1; col < m; col++) { + grids[row * m + col] = grids[row * m + col - 1] + grids[(row - 1) * m + col]; + } + } + return grids[m * n - 1]; +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./test m n\n"); + exit(-1); + } + printf("%d\n", uniquePaths(atoi(argv[1]), atoi(argv[2]))); + return 0; +} diff --git a/0063_unique_paths_ii/Makefile b/0063_unique_paths_ii/Makefile new file mode 100644 index 0000000..9cf8815 --- /dev/null +++ b/0063_unique_paths_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test unique_path.c 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/0064_minumum_path_sum/Makefile b/0064_minumum_path_sum/Makefile new file mode 100644 index 0000000..71f593e --- /dev/null +++ b/0064_minumum_path_sum/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test minimum_path_sum.c diff --git a/064_minumum_path_sum/minimum_path_sum.c b/0064_minumum_path_sum/minimum_path_sum.c similarity index 83% rename from 064_minumum_path_sum/minimum_path_sum.c rename to 0064_minumum_path_sum/minimum_path_sum.c index 33777ae..ad807c5 100644 --- a/064_minumum_path_sum/minimum_path_sum.c +++ b/0064_minumum_path_sum/minimum_path_sum.c @@ -1,9 +1,14 @@ #include #include #include -#include -int minPathSum(int** grid, int gridRowSize, int gridColSize) { +static inline int min(int a, int b) +{ + return a < b ? a : b; +} + +int minPathSum(int** grid, int gridRowSize, int gridColSize) +{ int i, j; int **dp = malloc(gridRowSize * sizeof(int *)); for (i = 0; i < gridRowSize; i++) { @@ -23,11 +28,9 @@ int minPathSum(int** grid, int gridRowSize, int gridColSize) { dp[0][i] = sum; } - int min = INT_MAX; for (i = 1; i < gridRowSize; i++) { for (j = 1; j < gridColSize; j++) { - int n = dp[i - 1][j] < dp[i][j - 1] ? dp[i - 1][j] : dp[i][j - 1]; - dp[i][j] = n + grid[i][j]; + dp[i][j] = grid[i][j] + min(dp[i - 1][j], dp[i][j - 1]); } } diff --git a/0065_valid_number/Makefile b/0065_valid_number/Makefile new file mode 100644 index 0000000..0490ac2 --- /dev/null +++ b/0065_valid_number/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test valid_number.c diff --git a/0065_valid_number/valid_number.c b/0065_valid_number/valid_number.c new file mode 100644 index 0000000..76af82a --- /dev/null +++ b/0065_valid_number/valid_number.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include + +static bool isNumber(const char *s) +{ + while (*s == ' ') + ++s; + bool if_find_num = false; + if (*s == '-' || *s == '+') + ++s; + while (isdigit(*s)) { + if_find_num = true; + ++s; + } + if (*s == '.') + ++s; + while (isdigit(*s)) { + if_find_num = true; + ++s; + } + if (if_find_num == true && *s == 'e') { + ++s; + if (*s == '+' || *s == '-') + ++s; + if_find_num = false; + while (isdigit(*s)) { + if_find_num = true; + ++s; + } + } + while (*s == ' ') + ++s; + return *s == '\0' && if_find_num == true; +} + +int main(int argc, char** argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test number\n"); + exit(-1); + } + printf("%s\n", isNumber(argv[1]) ? "true" : "false"); + return 0; +} diff --git a/0066_plus_one/Makefile b/0066_plus_one/Makefile new file mode 100644 index 0000000..5b94a50 --- /dev/null +++ b/0066_plus_one/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test plus_one.c 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/0067_add_binary/Makefile b/0067_add_binary/Makefile new file mode 100644 index 0000000..7a598de --- /dev/null +++ b/0067_add_binary/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test add_binary.c 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/0068_text_justification/Makefile b/0068_text_justification/Makefile new file mode 100644 index 0000000..b61a02c --- /dev/null +++ b/0068_text_justification/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test justification.c 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/0069_sqrt/Makefile b/0069_sqrt/Makefile new file mode 100644 index 0000000..e7d7846 --- /dev/null +++ b/0069_sqrt/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test sqrt.c 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/006_zigzag_conversion/Makefile b/006_zigzag_conversion/Makefile deleted file mode 100644 index 44cf21b..0000000 --- a/006_zigzag_conversion/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test zigzag_conversion.c diff --git a/0070_climbing_stairs/Makefile b/0070_climbing_stairs/Makefile new file mode 100644 index 0000000..b91c664 --- /dev/null +++ b/0070_climbing_stairs/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test climb_stairs.c diff --git a/0070_climbing_stairs/climb_stairs.c b/0070_climbing_stairs/climb_stairs.c new file mode 100644 index 0000000..31b1904 --- /dev/null +++ b/0070_climbing_stairs/climb_stairs.c @@ -0,0 +1,47 @@ +#include +#include +#include + +static int dfs(int n, int *steps) +{ + if (n == 1) { + return 1; + } else if (n == 2) { + return 2; + } else if (steps[n] > 0) { + return steps[n]; + } else { + steps[n] += dfs(n - 1, steps); + steps[n] += dfs(n - 2, steps); + return steps[n]; + } +} + +static int climbStairs(int n) +{ +#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++) { + c = a + b; + a = b; + b = c; + } + return n == 1 ? a : (n == 2 ? b : c); +#endif +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test n\n"); + exit(-1); + } + + printf("%d\n", climbStairs(atoi(argv[1]))); + return 0; +} 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/0071_simplify_path/Makefile b/0071_simplify_path/Makefile new file mode 100644 index 0000000..ba88f3d --- /dev/null +++ b/0071_simplify_path/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test simplify_path.c diff --git a/071_simplify_path/simplify_path.c b/0071_simplify_path/simplify_path.c similarity index 97% rename from 071_simplify_path/simplify_path.c rename to 0071_simplify_path/simplify_path.c index b56a907..a6ac084 100644 --- a/071_simplify_path/simplify_path.c +++ b/0071_simplify_path/simplify_path.c @@ -2,7 +2,8 @@ #include #include -static char* simplifyPath(char* path) { +static char* simplifyPath(char* path) +{ int len = strlen(path); if (len == 0) { return path; diff --git a/0072_edit_distance/Makefile b/0072_edit_distance/Makefile new file mode 100644 index 0000000..328780a --- /dev/null +++ b/0072_edit_distance/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test edit_distance.c diff --git a/0072_edit_distance/edit_distance.c b/0072_edit_distance/edit_distance.c new file mode 100644 index 0000000..92f96a8 --- /dev/null +++ b/0072_edit_distance/edit_distance.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include + +/* + * word1="abb", word2="abccb" + * + * 1) Initialize the DP matrix as below: + * + * "" a b c c b + * "" 0 1 2 3 4 5 + * a 1 + * b 2 + * b 3 + * + * 2) Dynamic Programming + * + * "" a b c c b + * "" 0 1 2 3 4 5 + * a 1 0 1 2 3 4 + * b 2 1 0 1 2 3 + * b 3 2 1 1 2 2 + */ + +static inline int min(int a, int b) +{ + return a < b ? a : b; +} + +static int minDistance(char* word1, char* word2) +{ + int i, j; + 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); + } + + dp[0][0] = 0; + for (i = 1; i <= l2; i++) { + dp[0][i] = i; + } + for (i = 1; i <= l1; i++) { + dp[i][0] = i; + } + + 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 { + dp[i][j] = 1 + min(dp[i - 1][j - 1], min(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 word1 word2\n"); + exit(-1); + } + printf("%d\n", minDistance(argv[1], argv[2])); + return 0; +} 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/0073_set_matrix_zeroes/Makefile b/0073_set_matrix_zeroes/Makefile new file mode 100644 index 0000000..b4a437b --- /dev/null +++ b/0073_set_matrix_zeroes/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test set_zero.c 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/0074_search_a_2d_matrix/Makefile b/0074_search_a_2d_matrix/Makefile new file mode 100644 index 0000000..dd33b1e --- /dev/null +++ b/0074_search_a_2d_matrix/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test matrix_search.c 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/0075_sort_colors/Makefile b/0075_sort_colors/Makefile new file mode 100644 index 0000000..98448ea --- /dev/null +++ b/0075_sort_colors/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test sort_colors.c diff --git a/0075_sort_colors/sort_colors.c b/0075_sort_colors/sort_colors.c new file mode 100644 index 0000000..290c02d --- /dev/null +++ b/0075_sort_colors/sort_colors.c @@ -0,0 +1,48 @@ +#include +#include +#include + + +static inline void swap(int *a, int *b) +{ + int tmp = *a; + *a = *b; + *b = tmp; +} + +void sortColors(int* nums, int numsSize) +{ + int i, j = 0; + for (i = 0; i < numsSize; i++) { + if (nums[i] == 0) { + swap(nums + j, nums + i); + j++; + } + } + + for (i = j; i < numsSize; i++) { + if (nums[i] == 1) { + swap(nums + j, nums + i); + j++; + } + } +} + +int main(int argc, char **argv) +{ + if (argc < 2) { + fprintf(stderr, "Usage: ./test 2 0 2 1 1 0\n"); + exit(-1); + } + int i, count = argc - 1; + int *nums = malloc(count * sizeof(int)); + for (i = 0; i < count; i++) { + nums[i] = atoi(argv[i + 1]); + } + sortColors(nums, count); + for (i = 0; i < count; i++) { + printf("%d ", nums[i]); + } + printf("\n"); + return 0; +} diff --git a/0075_sort_colors/sort_colors.cc b/0075_sort_colors/sort_colors.cc new file mode 100644 index 0000000..0d8ab5b --- /dev/null +++ b/0075_sort_colors/sort_colors.cc @@ -0,0 +1,34 @@ +#include + +using namespace std; + +class Solution { +public: + void sortColors(vector& nums) { + int i = 0, j = nums.size() - 1; + while (i < j) { + if (nums[i] == 0) { + i++; + continue; + } + if (nums[j] != 0) { + j--; + continue; + } + swap(nums[i], nums[j]); + } + + j = nums.size() - 1; + while (i < j) { + if (nums[i] == 1) { + i++; + continue; + } + if (nums[j] != 1) { + j--; + continue; + } + swap(nums[i], nums[j]); + } + } +}; diff --git a/0076_minimum_window_substring/Makefile b/0076_minimum_window_substring/Makefile new file mode 100644 index 0000000..5cd507a --- /dev/null +++ b/0076_minimum_window_substring/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test window_substring.c diff --git a/0076_minimum_window_substring/window_substring.c b/0076_minimum_window_substring/window_substring.c new file mode 100644 index 0000000..cd7f525 --- /dev/null +++ b/0076_minimum_window_substring/window_substring.c @@ -0,0 +1,70 @@ +#include +#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]]++; + } + + while (r < slen) { + if (--count[s[r++]] >= 0) { + /* pattern found */ + len++; + } + + 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[l++]] > 0) { + len--; + } + } + } + + char *result; + if (min_len <= slen) { + result = malloc(min_len + 1); + memcpy(result, s + start, min_len); + result[min_len] = '\0'; + } else { + result = ""; + } + + return result; +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./test string pattern\n"); + exit(-1); + } + printf("Answer: %s\n", minWindow(argv[1], argv[2])); + return 0; +} 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/0077_combinations/Makefile b/0077_combinations/Makefile new file mode 100644 index 0000000..8c0689f --- /dev/null +++ b/0077_combinations/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test combinations.c diff --git a/0077_combinations/combinations.c b/0077_combinations/combinations.c new file mode 100644 index 0000000..2ef84f7 --- /dev/null +++ b/0077_combinations/combinations.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include + + +static void dfs(int n, int k, int start, int *stack, int len, + int **results, int *count, int *col_sizes) +{ + int i; + if (len == k) { + col_sizes[*count] = k; + results[*count] = malloc(k * sizeof(int)); + memcpy(results[*count], stack, k * sizeof(int)); + (*count)++; + } else { + for (i = start; i <= n; i++) { + stack[len] = i; + dfs(n, k, i + 1, stack, len + 1, results, count, 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 *returnColumnSizes array must be malloced, assume caller calls free(). + */ +int** combine(int n, int k, int* returnSize, int** returnColumnSizes) { + int capacity = 10000; + int **results = malloc(capacity * sizeof(int *)); + int *stack = malloc(k * sizeof(int)); + *returnColumnSizes = malloc(capacity * sizeof(int)); + dfs(n, k, 1, stack, 0, results, returnSize, *returnColumnSizes); + return results; +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./test n k\n"); + 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(n, k, &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/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/0078_subsets/Makefile b/0078_subsets/Makefile new file mode 100644 index 0000000..92ed3f7 --- /dev/null +++ b/0078_subsets/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test subsets.c diff --git a/078_subsets/subsets.c b/0078_subsets/subsets.c similarity index 51% rename from 078_subsets/subsets.c rename to 0078_subsets/subsets.c index dcdf3ec..aeb75b1 100644 --- a/078_subsets/subsets.c +++ b/0078_subsets/subsets.c @@ -2,34 +2,34 @@ #include #include -static void subset_recursive(int *nums, int size, int start, - int *buf, int len, - int **sets, int *sizes, int *count) + +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]; - subset_recursive(nums, size, i + 1, buf, len, sets, sizes, count); - len--; + 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 *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(). **/ -int** subsets(int* nums, int numsSize, int** columnSizes, int* returnSize) { +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)); - *columnSizes = malloc(capacity * sizeof(int)); + int *stack = malloc(numsSize * sizeof(int)); + *returnColumnSizes = malloc(capacity * sizeof(int)); *returnSize = 0; - subset_recursive(nums, numsSize, 0, buf, 0, sets, *columnSizes, returnSize); + dfs(nums, numsSize, 0, stack, 0, sets, returnSize, *returnColumnSizes); return sets; } @@ -47,7 +47,7 @@ int main(int argc, char **argv) } int *sizes; int count; - int **lists = subsets(nums, size, &sizes, &count); + int **lists = subsets(nums, size, &count, &sizes); for (i = 0; i < count; i++) { for (j = 0; j < sizes[i]; j++) { printf("%d ", lists[i][j]); 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/0079_word_search/Makefile b/0079_word_search/Makefile new file mode 100644 index 0000000..2eab6c6 --- /dev/null +++ b/0079_word_search/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test word_search.c diff --git a/079_word_search/word_search.c b/0079_word_search/word_search.c similarity index 71% rename from 079_word_search/word_search.c rename to 0079_word_search/word_search.c index 54cae5d..6394a19 100644 --- a/079_word_search/word_search.c +++ b/0079_word_search/word_search.c @@ -3,7 +3,8 @@ #include #include -static bool recursive(char *word, char **board, bool *used, int row, int col, int row_size, int col_size) +static bool dfs(char *word, char **board, bool *used, + int row, int col, int row_size, int col_size) { if (board[row][col] != *word) { return false; @@ -17,26 +18,27 @@ static bool recursive(char *word, char **board, bool *used, int row, int col, in bool result = false; if (row > 0 && !used[(row - 1) * col_size + col]) { - result = recursive(word + 1, board, used, row - 1, col, row_size, col_size); + result = dfs(word + 1, board, used, row - 1, col, row_size, col_size); } if (!result && row < row_size - 1 && !used[(row + 1) * col_size + col]) { - result = recursive(word + 1, board, used, row + 1, col, row_size, col_size); + result = dfs(word + 1, board, used, row + 1, col, row_size, col_size); } if (!result && col > 0 && !used[row * col_size + col - 1]) { - result = recursive(word + 1, board, used, row, col - 1, row_size, col_size); + result = dfs(word + 1, board, used, row, col - 1, row_size, col_size); } if (!result && col < col_size - 1 && !used[row * col_size + col + 1]) { - result = recursive(word + 1, board, used, row, col + 1, row_size, col_size); + result = dfs(word + 1, board, used, row, col + 1, row_size, col_size); } used[row * col_size + col] = false; return result; } -static bool exist(char** board, int boardRowSize, int boardColSize, char* word) { +static bool exist(char** board, int boardRowSize, int boardColSize, char* word) +{ int i, j; int len = strlen(word); if (len > boardRowSize * boardColSize) { @@ -46,7 +48,7 @@ static bool exist(char** board, int boardRowSize, int boardColSize, char* word) for (i = 0; i < boardRowSize; i++) { for (j = 0; j < boardColSize; j++) { memset(used, false, boardRowSize * boardColSize); - if (recursive(word, board, used, i, j, boardRowSize, boardColSize)) { + if (dfs(word, board, used, i, j, boardRowSize, boardColSize)) { return true; } } diff --git a/007_reverse_integer/Makefile b/007_reverse_integer/Makefile deleted file mode 100644 index cf50d4d..0000000 --- a/007_reverse_integer/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test reverse_integer.c diff --git a/0080_remove_duplicates_from_sorted_array_ii/Makefile b/0080_remove_duplicates_from_sorted_array_ii/Makefile new file mode 100644 index 0000000..a842a72 --- /dev/null +++ b/0080_remove_duplicates_from_sorted_array_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test rm_dups.c diff --git a/0080_remove_duplicates_from_sorted_array_ii/rm_dups.c b/0080_remove_duplicates_from_sorted_array_ii/rm_dups.c new file mode 100644 index 0000000..628761c --- /dev/null +++ b/0080_remove_duplicates_from_sorted_array_ii/rm_dups.c @@ -0,0 +1,43 @@ +#include +#include + +static int removeDuplicates(int* nums, int numsSize) +{ + if (numsSize == 0) { + return 0; + } + + int i; + int len = 0; + int count = 1; + for (i = 1; i < numsSize; i++) { + /* Find the start position to be replaced */ + if (nums[len] == nums[i]) { + if (count < 2) { + count++; + /* Replace in each iteration */ + nums[++len] = nums[i]; + } + } else { + /* Here there are more than 2 duplicates */ + count = 1; + nums[++len] = nums[i]; + } + } + + return len + 1; +} + +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]); + } + count = removeDuplicates(nums, count); + for (i = 0; i < count; i++) { + printf("%d ", nums[i]); + } + printf("\n"); +} diff --git a/0081_search_in_rotated_sorted_array_ii/Makefile b/0081_search_in_rotated_sorted_array_ii/Makefile new file mode 100644 index 0000000..8ab5ddc --- /dev/null +++ b/0081_search_in_rotated_sorted_array_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test search_rotated_array.c diff --git a/0081_search_in_rotated_sorted_array_ii/search_rotated_array.c b/0081_search_in_rotated_sorted_array_ii/search_rotated_array.c new file mode 100644 index 0000000..7d4e24e --- /dev/null +++ b/0081_search_in_rotated_sorted_array_ii/search_rotated_array.c @@ -0,0 +1,50 @@ +#include +#include +#include + + +static bool search(int* nums, int numsSize, int target) +{ + int lo = 0; + int hi = numsSize - 1; + while (lo <= hi) { + int mid = lo + (hi - lo) / 2; + if (nums[mid] == target) { + return true; + } + + if (nums[lo] == nums[mid] && nums[mid] == nums[hi]) { + /* Not sure which side contains the peak value, reduce search range */ + lo++; + hi--; + } else if (nums[lo] <= nums[mid]) { /* lo might be equal to mid */ + if (nums[lo] <= target && target < nums[mid]) { + hi = mid - 1; + } else { + lo = mid + 1; + } + } else { + if (nums[mid] < target && target <= nums[hi]) { + lo = mid + 1; + } else { + hi = mid - 1; + } + } + } + + return false; +} + +int main(int argc, char **argv) +{ + int i; + int target = atoi(argv[1]); + int size = argc - 2; + int *nums = malloc(size * sizeof(int)); + + for (i = 0; i < argc - 2; i++) { + nums[i] = atoi(argv[i + 2]); + } + printf("%d\n", search(nums, size, target)); + return 0; +} diff --git a/0082_remove_duplicates_from_sorted_list_ii/Makefile b/0082_remove_duplicates_from_sorted_list_ii/Makefile new file mode 100644 index 0000000..a4e0790 --- /dev/null +++ b/0082_remove_duplicates_from_sorted_list_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test rm_dup.c 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 75% rename from 082_remove_duplicates_from_sorted_list_ii/rm_dup.c rename to 0082_remove_duplicates_from_sorted_list_ii/rm_dup.c index c451d79..35e6324 100644 --- a/082_remove_duplicates_from_sorted_list_ii/rm_dup.c +++ b/0082_remove_duplicates_from_sorted_list_ii/rm_dup.c @@ -1,27 +1,29 @@ #include #include + struct ListNode { int val; struct ListNode *next; }; -struct ListNode* deleteDuplicates(struct ListNode* head) { +struct ListNode* deleteDuplicates(struct ListNode* head) +{ struct ListNode dummy; - struct ListNode *p, *next, *prev; + struct ListNode *p, *q, *prev; prev = &dummy; dummy.next = head; - p = next = head; + p = q = head; while (p != NULL) { - while (next != NULL && next->val == p->val) { - next = next->next; + while (q != NULL && q->val == p->val) { + q = q->next; } - if (p->next == next) { + if (p->next == q) { prev = p; } else { - prev->next = next; + prev->next = q; } - p = next; + p = q; } return dummy.next; } diff --git a/0083_remove_duplicates_from_sorted_list/Makefile b/0083_remove_duplicates_from_sorted_list/Makefile new file mode 100644 index 0000000..a4e0790 --- /dev/null +++ b/0083_remove_duplicates_from_sorted_list/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test rm_dup.c diff --git a/083_remove_duplicates_from_sorted_list/rm_dup.c b/0083_remove_duplicates_from_sorted_list/rm_dup.c similarity index 65% rename from 083_remove_duplicates_from_sorted_list/rm_dup.c rename to 0083_remove_duplicates_from_sorted_list/rm_dup.c index d5de716..e8d7d4a 100644 --- a/083_remove_duplicates_from_sorted_list/rm_dup.c +++ b/0083_remove_duplicates_from_sorted_list/rm_dup.c @@ -1,22 +1,28 @@ +#include #include #include + struct ListNode { int val; struct ListNode *next; }; -struct ListNode* deleteDuplicates(struct ListNode* head) { - struct ListNode *p, *next; - p = next = head; - while (p != NULL) { - while (next != NULL && next->val == p->val) { - next = next->next; +struct ListNode* deleteDuplicates(struct ListNode* head) +{ + 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 = next; - p = next; + 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/0084_largest_rectangle_in_histogram/Makefile b/0084_largest_rectangle_in_histogram/Makefile new file mode 100644 index 0000000..a8c4132 --- /dev/null +++ b/0084_largest_rectangle_in_histogram/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test rect_in_histogram.c diff --git a/0084_largest_rectangle_in_histogram/rect_in_histogram.c b/0084_largest_rectangle_in_histogram/rect_in_histogram.c new file mode 100644 index 0000000..4e302ad --- /dev/null +++ b/0084_largest_rectangle_in_histogram/rect_in_histogram.c @@ -0,0 +1,45 @@ +#include +#include + +static int largestRectangleArea(int* heights, int heightsSize) +{ + 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++) { + /* keep monotonous increasing stack */ + while (pos > 0 && heights[i] < heights[idx_stk[pos - 1]]) { + pos--; + } + lmax[i] = pos == 0 ? -1 : idx_stk[pos - 1]; + idx_stk[pos++] = i; + } + + pos = 0; + for (i = heightsSize - 1; i >= 0; i--) { + /* keep monotonous increasing stack */ + while (pos > 0 && heights[i] < heights[idx_stk[pos - 1]]) { + pos--; + } + 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] * (rmax[i] - lmax[i] - 1); + max_area = area > max_area ? area : max_area; + } + + return max_area; +} + +int main(void) +{ + int nums[] = { 2, 1, 5, 6, 2, 3 }; + int count = sizeof(nums) / sizeof(*nums); + printf("%d\n", largestRectangleArea(nums, count)); + return 0; +} diff --git a/0085_maximal_rectangle/Makefile b/0085_maximal_rectangle/Makefile new file mode 100644 index 0000000..c3439ab --- /dev/null +++ b/0085_maximal_rectangle/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test maximal_rectangle.c diff --git a/0085_maximal_rectangle/maximal_rectangle.c b/0085_maximal_rectangle/maximal_rectangle.c new file mode 100644 index 0000000..3f620c3 --- /dev/null +++ b/0085_maximal_rectangle/maximal_rectangle.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include + +static inline int max(int a, int b) +{ + return a > b ? a : b; +} + +static int area_calc(int *heights, int size) +{ + 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++) { + /* keep monotonous increasing maxograms */ + while (pos > 0 && heights[i] < heights[idx_stk[pos - 1]]) { + pos--; + } + lmax[i] = pos == 0 ? -1 : idx_stk[pos - 1]; + idx_stk[pos++] = i; + } + + pos = 0; + for (i = size - 1; i >= 0; i--) { + /* keep monotonous increasing maxograms */ + while (pos > 0 && heights[i] < heights[idx_stk[pos - 1]]) { + pos--; + } + 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] * (rmax[i] - lmax[i] - 1); + max_area = max(area, max_area); + } + + return max_area; +} + +static int maximalRectangle(char** matrix, int matrixSize, int* matrixColSize) +{ + int i, j, max_area = 0; + 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[i])); + } + return max_area; +} + +/* ./test 11111111 11111110 11111110 11111000 01111000 */ +int main(int argc, char **argv) +{ + if (argc < 2) { + fprintf(stderr, "Usage: ./test row1 row2...\n"); + exit(-1); + } + + 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, cols)); + return 0; +} diff --git a/0086_partition_list/Makefile b/0086_partition_list/Makefile new file mode 100644 index 0000000..abdad5b --- /dev/null +++ b/0086_partition_list/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test partition_list.c diff --git a/086_partition_list/partition_list.c b/0086_partition_list/partition_list.c similarity index 66% rename from 086_partition_list/partition_list.c rename to 0086_partition_list/partition_list.c index 8f262a9..090b469 100644 --- a/086_partition_list/partition_list.c +++ b/0086_partition_list/partition_list.c @@ -6,28 +6,37 @@ struct ListNode { struct ListNode *next; }; -struct ListNode* partition(struct ListNode* head, int x) { +struct ListNode* partition(struct ListNode* head, int x) +{ struct ListNode dummy; - struct ListNode *p = NULL, *start = &dummy, *pivot; + struct ListNode *prev1 = &dummy, *pivot; + dummy.next = head; for (pivot = head; pivot != NULL; pivot = pivot->next) { if (pivot->val >= x) { break; } - start = pivot; + prev1 = pivot; } - struct ListNode *prev; - for (p = pivot; p != NULL; p = p->next) { + struct ListNode *p = pivot->next; + struct ListNode *prev2 = pivot; + while (p != NULL) { if (p->val < x) { - prev->next = p->next; - p->next = start->next; - start->next = p; - start = p; - p = prev; + /* deletion */ + prev2->next = p->next; + /* insertion */ + p->next = prev1->next; + prev1->next = p; + /* iteration */ + prev1 = p; + p = prev2->next; + } else { + prev2 = p; + p = p->next; } - prev = p; } + return dummy.next; } diff --git a/0087_scramble_string/Makefile b/0087_scramble_string/Makefile new file mode 100644 index 0000000..e081260 --- /dev/null +++ b/0087_scramble_string/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test scramble_string.c diff --git a/087_scramble_string/scramble_string.c b/0087_scramble_string/scramble_string.c similarity index 83% rename from 087_scramble_string/scramble_string.c rename to 0087_scramble_string/scramble_string.c index 1eb5c8a..a595bf3 100644 --- a/087_scramble_string/scramble_string.c +++ b/0087_scramble_string/scramble_string.c @@ -12,8 +12,6 @@ * or * isScramble(s1[0..j], s2[n - j - 1, n]) && isScramble(s1[j+1..n], s2[0..n - j]) */ -#define N 128 - static bool scramble(char *s1, int low1, int high1, char *s2, int low2, int high2) { if (high1 - low1 != high2 - low2) { @@ -21,16 +19,14 @@ static bool scramble(char *s1, int low1, int high1, char *s2, int low2, int high } else if (!memcmp(s1 + low1, s2 + low2, high1 - low1 + 1)) { return true; } else { - int i, c1[N], c2[N]; - memset(c1, 0, N * sizeof(int)); - memset(c2, 0, N * sizeof(int)); + int i, c1[128] = { 0 }, c2[128] = { 0 }; for (i = low1; i <= high1; i++) { c1[s1[i]]++; } for (i = low2; i <= high2; i++) { c2[s2[i]]++; } - if (memcmp(c1, c2, N * sizeof(int))) { + if (memcmp(c1, c2, 128 * sizeof(int))) { return false; } else { int len = high1 - low1 + 1; @@ -49,10 +45,9 @@ static bool scramble(char *s1, int low1, int high1, char *s2, int low2, int high } } -static bool isScramble(char* s1, char* s2) { - int len1 = strlen(s1); - int len2 = strlen(s2); - return scramble(s1, 0, len1 - 1, s2, 0, len2 - 1); +static bool isScramble(char* s1, char* s2) +{ + return scramble(s1, 0, strlen(s1) - 1, s2, 0, strlen(s2) - 1); } int main(int argc, char **argv) diff --git a/0088_merge_sorted_array/Makefile b/0088_merge_sorted_array/Makefile new file mode 100644 index 0000000..8db1be1 --- /dev/null +++ b/0088_merge_sorted_array/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test merge_array.c diff --git a/0088_merge_sorted_array/merge_array.c b/0088_merge_sorted_array/merge_array.c new file mode 100644 index 0000000..ddfbc20 --- /dev/null +++ b/0088_merge_sorted_array/merge_array.c @@ -0,0 +1,34 @@ +#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) { + if (nums1[i] >= nums2[j]) { + nums1[k--] = nums1[i--]; + } else { + nums1[k--] = nums2[j--]; + } + } + + while (j >= 0) { + nums1[k--] = nums2[j--]; + } +} + +int main(int argc, char **argv) +{ + int i; + int nums1[] = { 1, 3, 5, 7, 9, 0, 0, 0, 0, 0 }; + int nums2[] = { 2, 4, 6, 8, 10 }; + int size1 = 5;//sizeof(nums1) / sizeof(*nums1); + int size2 = sizeof(nums2) / sizeof(*nums2); + merge(nums1, size1, nums2, size2); + for (i = 0; i < sizeof(nums1) / sizeof(*nums1); i++) { + printf("%d ", nums1[i]); + } + printf("\n"); + return 0; +} 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/0089_gray_code/Makefile b/0089_gray_code/Makefile new file mode 100644 index 0000000..6580690 --- /dev/null +++ b/0089_gray_code/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test gray_code.c 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/008_atoi/atoi.c b/008_atoi/atoi.c deleted file mode 100644 index 481c24d..0000000 --- a/008_atoi/atoi.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2015, Leo Ma - */ - -#include -#include -#include - -int main(int argc, char **argv) -{ - char *alpha, *s; - int n = 0, sign = 0; - - if (argc != 2) { - printf("Usage: ./atoi 123\n"); - exit(-1); - } - - alpha = argv[1]; - while (*alpha == ' ' || *alpha == '\t') { - alpha++; - } - - for (s = alpha; *s != '\0'; s++) { - if (isdigit(*s)) { - int d = *s - '0'; - if (sign) { - if (-n < (INT_MIN + d) / 10) { - n = INT_MIN; - break; - } - } else { - if (n > (INT_MAX - d) / 10) { - n = INT_MAX; - break; - } - } - n = n * 10 + d; - } else if (*s == '-' && isdigit(*(s + 1))) { - sign = 1; - } else if (*s == '+' && isdigit(*(s + 1))) { - sign = 0; - } else { - break; - } - } - - n = sign ? -n : n; - printf("n = %d %x\n", n, n); - - return 0; -} diff --git a/0090_subsets_ii/Makefile b/0090_subsets_ii/Makefile new file mode 100644 index 0000000..92ed3f7 --- /dev/null +++ b/0090_subsets_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test subsets.c diff --git a/0090_subsets_ii/subsets.c b/0090_subsets_ii/subsets.c new file mode 100644 index 0000000..4c3897d --- /dev/null +++ b/0090_subsets_ii/subsets.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include + +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, int **sets, int *count, int *sizes) +{ + 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 (last != nums[i]) { + /* No duplicate candidate elements at same level position */ + buf[level] = nums[i]; + /* 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 *returnColumnSizes array must be malloced, assume caller calls free(). + **/ +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)); + *returnColumnSizes = malloc(capacity * sizeof(int)); + *returnSize = 0; + dfs(nums, numsSize, 0, buf, 0, sets, returnSize, *returnColumnSizes); + return sets; +} + +int main(int argc, char **argv) +{ + int i, j; + if (argc <= 1) { + fprintf(stderr, "Usage: ./test array...\n"); + exit(-1); + } + int size = argc - 1; + int *nums = malloc(size * sizeof(int)); + for (i = 0; i < size; i++) { + nums[i] = atoi(argv[i + 1]); + } + int *sizes; + int count; + int **lists = subsets(nums, size, &count, &sizes); + for (i = 0; i < count; i++) { + for (j = 0; j < sizes[i]; j++) { + printf("%d ", lists[i][j]); + } + printf("\n"); + } + return 0; +} 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/0091_decode_ways/Makefile b/0091_decode_ways/Makefile new file mode 100644 index 0000000..c958fe7 --- /dev/null +++ b/0091_decode_ways/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test decode_ways.c diff --git a/0091_decode_ways/decode_ways.c b/0091_decode_ways/decode_ways.c new file mode 100644 index 0000000..05fc39d --- /dev/null +++ b/0091_decode_ways/decode_ways.c @@ -0,0 +1,38 @@ +#include +#include +#include + + +static int numDecodings(char* s) +{ + int len = strlen(s); + if (len == 0) { + return 0; + } + + 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++) { + c = s[i - 1] == '0' ? 0 : b; + int num = (s[i - 2] - '0') * 10 + (s[i - 1] - '0'); + if (num >= 10 && num <= 26) { + c += a; + } + a = b; + b = c; + } + + return c; +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test number\n"); + exit(-1); + } + printf("%d\n", numDecodings(argv[1])); + return 0; +} diff --git a/0092_reverse_linked_list_ii/Makefile b/0092_reverse_linked_list_ii/Makefile new file mode 100644 index 0000000..efe146e --- /dev/null +++ b/0092_reverse_linked_list_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test reverse_list.c diff --git a/092_reverse_linked_list_ii/reverse_list.c b/0092_reverse_linked_list_ii/reverse_list.c similarity index 79% rename from 092_reverse_linked_list_ii/reverse_list.c rename to 0092_reverse_linked_list_ii/reverse_list.c index a3d5815..aebcf44 100644 --- a/092_reverse_linked_list_ii/reverse_list.c +++ b/0092_reverse_linked_list_ii/reverse_list.c @@ -8,27 +8,25 @@ struct ListNode { static struct ListNode* reverseBetween(struct ListNode* head, int m, int n) { - int len = n - m + 1; - if (len == 1) { - return head; - } - + int i; struct ListNode dummy; - struct ListNode *p = head; struct ListNode *prev = &dummy; - prev->next = p; - while (--m > 0) { - prev = p; - p = p->next; + prev->next = head; + + for (i = 1; i < m; i++) { + prev = prev->next; } - struct ListNode *q = p->next; - while (--len > 0) { + struct ListNode *p = prev->next; + for (i = m; i < n; i++) { + struct ListNode *q = p->next; + /* deletion */ p->next = q->next; + /* insertion */ q->next = prev->next; prev->next = q; - q = p->next; } + return dummy.next; } diff --git a/0093_restore_ip_addresses/Makefile b/0093_restore_ip_addresses/Makefile new file mode 100644 index 0000000..e224a93 --- /dev/null +++ b/0093_restore_ip_addresses/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test ip_addr.c diff --git a/093_restore_ip_addresses/ip_addr.c b/0093_restore_ip_addresses/ip_addr.c similarity index 87% rename from 093_restore_ip_addresses/ip_addr.c rename to 0093_restore_ip_addresses/ip_addr.c index 38855ad..8f461a5 100644 --- a/093_restore_ip_addresses/ip_addr.c +++ b/0093_restore_ip_addresses/ip_addr.c @@ -19,7 +19,7 @@ static bool valid(char *ip, int len) #define WIDTH 4 -static void recursive(char *s, int start, char *stack, int num, char **results, int *count) +static void dfs(char *s, int start, char *stack, int num, char **results, int *count) { int i, j; if (num == 4) { @@ -45,7 +45,7 @@ static void recursive(char *s, int start, char *stack, int num, char **results, if (!valid(p, q - p)) { return; } - recursive(s, i + 1, stack, num + 1, results, count); + dfs(s, i + 1, stack, num + 1, results, count); if (num + 1 < 4) { memset(stack + (num + 1) * WIDTH, 0, WIDTH); } @@ -57,11 +57,12 @@ static void recursive(char *s, int start, char *stack, int num, char **results, ** Return an array of size *returnSize. ** Note: The returned array must be malloced, assume caller calls free(). **/ -static char** restoreIpAddresses(char* s, int* returnSize) { +static char** restoreIpAddresses(char* s, int* returnSize) +{ int count = 0; char **results = malloc(100 * sizeof(char *)); char addr[16] = { '\0' }; - recursive(s, 0, addr, 0, results, &count); + dfs(s, 0, addr, 0, results, &count); *returnSize = count; return results; } diff --git a/0094_binary_tree_inorder_traversal/Makefile b/0094_binary_tree_inorder_traversal/Makefile new file mode 100644 index 0000000..2e2f5f9 --- /dev/null +++ b/0094_binary_tree_inorder_traversal/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test bst_inorder_traversal.c diff --git a/094_binary_tree_inorder_traversal/bst_inorder_traversal.c b/0094_binary_tree_inorder_traversal/bst_inorder_traversal.c similarity index 51% rename from 094_binary_tree_inorder_traversal/bst_inorder_traversal.c rename to 0094_binary_tree_inorder_traversal/bst_inorder_traversal.c index 8730457..1c248c1 100644 --- a/094_binary_tree_inorder_traversal/bst_inorder_traversal.c +++ b/0094_binary_tree_inorder_traversal/bst_inorder_traversal.c @@ -1,31 +1,30 @@ #include #include - struct TreeNode { - int val; - struct TreeNode *left; - struct TreeNode *right; - }; +struct TreeNode { + int val; + struct TreeNode *left; + struct TreeNode *right; +}; static void traverse(struct TreeNode *node, int *result, int *count) { - if (node->left != NULL) { - traverse(node->left, result, count); + if (node == NULL) { + return; } - + + traverse(node->left, result, count); result[*count] = node->val; (*count)++; - - if (node->right != NULL) { - traverse(node->right, result, count); - } + traverse(node->right, result, count); } /** - * * Return an array of size *returnSize. - * * Note: The returned array must be malloced, assume caller calls free(). - * */ -int* inorderTraversal(struct TreeNode* root, int* returnSize) { + ** Return an array of size *returnSize. + ** Note: The returned array must be malloced, assume caller calls free(). + **/ +static int* inorderTraversal(struct TreeNode* root, int* returnSize) +{ if (root == NULL) { *returnSize = 0; return NULL; diff --git a/0095_unique_binary_search_trees_ii/Makefile b/0095_unique_binary_search_trees_ii/Makefile new file mode 100644 index 0000000..551f77b --- /dev/null +++ b/0095_unique_binary_search_trees_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test unique_bst.c diff --git a/095_unique_binary_search_trees_ii/unique_bst.c b/0095_unique_binary_search_trees_ii/unique_bst.c similarity index 90% rename from 095_unique_binary_search_trees_ii/unique_bst.c rename to 0095_unique_binary_search_trees_ii/unique_bst.c index 0cbf3d1..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 @@ -52,7 +52,7 @@ struct TreeNode { struct TreeNode *right; }; -static struct TreeNode *sub_tree_generate(int low, int high, int *count) +static struct TreeNode *dfs(int low, int high, int *count) { int i, j, k; if (low > high) { @@ -72,8 +72,8 @@ static struct TreeNode *sub_tree_generate(int low, int high, int *count) for (i = low; i <= high; i++) { /* Possibilities of roots with different values */ int left_cnt, right_cnt; - struct TreeNode *left_subs = sub_tree_generate(low, i - 1, &left_cnt); - struct TreeNode *right_subs = sub_tree_generate(i + 1, high, &right_cnt); + struct TreeNode *left_subs = dfs(low, i - 1, &left_cnt); + struct TreeNode *right_subs = dfs(i + 1, high, &right_cnt); /* Total number = left sub possibilities * right sub possibilities */ if (left_cnt == 0) left_cnt = 1; if (right_cnt == 0) right_cnt = 1; @@ -103,7 +103,7 @@ static struct TreeNode *sub_tree_generate(int low, int high, int *count) static struct TreeNode** generateTrees(int n, int* returnSize) { int i, count = 0; - struct TreeNode *roots = sub_tree_generate(1, n, &count); + struct TreeNode *roots = dfs(1, n, &count); struct TreeNode **results = malloc(count * sizeof(struct TreeNode *)); for (i = 0; i < count; i++) { results[i] = &roots[i]; diff --git a/0096_unique_binary_search_trees/Makefile b/0096_unique_binary_search_trees/Makefile new file mode 100644 index 0000000..551f77b --- /dev/null +++ b/0096_unique_binary_search_trees/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test unique_bst.c diff --git a/096_unique_binary_search_trees/unique_bst.c b/0096_unique_binary_search_trees/unique_bst.c similarity index 91% rename from 096_unique_binary_search_trees/unique_bst.c rename to 0096_unique_binary_search_trees/unique_bst.c index 507a64b..913e90a 100644 --- a/096_unique_binary_search_trees/unique_bst.c +++ b/0096_unique_binary_search_trees/unique_bst.c @@ -21,7 +21,7 @@ static int numTrees(int n) { int main(int argc, char **argv) { if (argc != 2) { - fprintf(stderr, "Usage: ./test n"); + fprintf(stderr, "Usage: ./test n\n"); exit(-1); } printf("%d\n", numTrees(atoi(argv[1]))); 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/0097_interleaving_string/Makefile b/0097_interleaving_string/Makefile new file mode 100644 index 0000000..81bd21a --- /dev/null +++ b/0097_interleaving_string/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test interleaving_string.c diff --git a/097_interleaving_string/interleaving_string.c b/0097_interleaving_string/interleaving_string.c similarity index 94% rename from 097_interleaving_string/interleaving_string.c rename to 0097_interleaving_string/interleaving_string.c index e274c6a..70e9d96 100644 --- a/097_interleaving_string/interleaving_string.c +++ b/0097_interleaving_string/interleaving_string.c @@ -20,6 +20,11 @@ static bool isInterleave(char* s1, char* s2, char* s3) int i, j; int len1 = strlen(s1); int len2 = strlen(s2); + int len3 = strlen(s3); + if (len1 + len2 != len3) { + return false; + } + bool *table = malloc((len1 + 1) * (len2 + 1) * sizeof(bool)); bool **dp = malloc((len1 + 1) * sizeof(bool *)); for (i = 0; i < len1 + 1; i++) { diff --git a/0098_validate_binary_search_tree/Makefile b/0098_validate_binary_search_tree/Makefile new file mode 100644 index 0000000..860620b --- /dev/null +++ b/0098_validate_binary_search_tree/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test valid_bst.c diff --git a/0098_validate_binary_search_tree/valid_bst.c b/0098_validate_binary_search_tree/valid_bst.c new file mode 100644 index 0000000..e03289e --- /dev/null +++ b/0098_validate_binary_search_tree/valid_bst.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include + + +struct TreeNode { + int val; + struct TreeNode *left; + struct TreeNode *right; +}; + +bool isValidBST(struct TreeNode* root) +{ + 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) +{ + struct TreeNode root; + struct TreeNode left; + struct TreeNode right; + root.val = 1; + root.left = &left; + root.right = NULL; + left.val = 1; + left.left = NULL; + left.right = NULL; + right.val = 1; + right.left = NULL; + right.right = NULL; + printf("%s\n", isValidBST(&root) ? "true" : "false"); + return 0; +} 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/0099_recover_binary_search_tree/Makefile b/0099_recover_binary_search_tree/Makefile new file mode 100644 index 0000000..2072b00 --- /dev/null +++ b/0099_recover_binary_search_tree/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test recover_bst.c diff --git a/0099_recover_binary_search_tree/recover_bst.c b/0099_recover_binary_search_tree/recover_bst.c new file mode 100644 index 0000000..5274c88 --- /dev/null +++ b/0099_recover_binary_search_tree/recover_bst.c @@ -0,0 +1,67 @@ +#include +#include +#include + + +struct TreeNode { + int val; + struct TreeNode *left; + struct TreeNode *right; +}; + +static void dfs(struct TreeNode *node, struct TreeNode **prev, + struct TreeNode **p1, struct TreeNode **p2, int *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; + } + } + *prev = node; + + dfs(node->right, prev, p1, p2, wrong); +} + +static void recoverTree(struct TreeNode* root) +{ + 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) +{ + struct TreeNode root; + struct TreeNode left; + struct TreeNode right; + root.val = 2; + root.left = &left; + root.right = &right; + left.val = 3; + left.left = NULL; + left.right = NULL; + right.val = 1; + right.left = NULL; + right.right = NULL; + recoverTree(&root); + printf("%d %d %d\n", root.val, left.val, right.val); + return 0; +} 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/009_palindrome_number/Makefile b/009_palindrome_number/Makefile deleted file mode 100644 index 5036f09..0000000 --- a/009_palindrome_number/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test palindrome_number.c diff --git a/0100_same_tree/Makefile b/0100_same_tree/Makefile new file mode 100644 index 0000000..c3ddded --- /dev/null +++ b/0100_same_tree/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test same_tree.c 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/0101_symmetric_tree/Makefile b/0101_symmetric_tree/Makefile new file mode 100644 index 0000000..2ecc74a --- /dev/null +++ b/0101_symmetric_tree/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test symmetric_tree.c 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/0102_binary_tree_level_order_traversal/Makefile b/0102_binary_tree_level_order_traversal/Makefile new file mode 100644 index 0000000..e07b89e --- /dev/null +++ b/0102_binary_tree_level_order_traversal/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test bst_bfs.c diff --git a/102_binary_tree_level_order_traversal/bst_bfs.c b/0102_binary_tree_level_order_traversal/bst_bfs.c similarity index 53% rename from 102_binary_tree_level_order_traversal/bst_bfs.c rename to 0102_binary_tree_level_order_traversal/bst_bfs.c index af2f81c..9275ffe 100644 --- a/102_binary_tree_level_order_traversal/bst_bfs.c +++ b/0102_binary_tree_level_order_traversal/bst_bfs.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)->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 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; @@ -36,7 +36,7 @@ static inline void INIT_LIST_HEAD(struct list_head *list) static inline int list_empty(const struct list_head *head) { - return (head->next == head); + return head->next == head; } static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) @@ -69,58 +69,31 @@ 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, - 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; - list_for_each(p, parents) { - struct bfs_node *new; - struct bfs_node *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)); - list_for_each_safe(p, n, parents) { - struct bfs_node *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 *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 int** levelOrder(struct TreeNode* root, int** columnSizes, int* returnSize) +static int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes) { if (root == NULL) { *returnSize = 0; @@ -128,25 +101,39 @@ static int** levelOrder(struct TreeNode* root, int** columnSizes, int* returnSiz } 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 *)); - *columnSizes = malloc(BST_MAX_LEVEL * sizeof(int)); - memset(*columnSizes, 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, &free_list, results, *columnSizes, level); - } else { - queue(&q0, &q1, &free_list, results, *columnSizes, level); + *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++; } @@ -186,7 +173,7 @@ int main(void) node2[3].right = NULL; int i, j, count = 0, *col_sizes; - int **lists = levelOrder(&root, &col_sizes, &count); + 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]); 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/0103_binary_tree_zigzag_level_order_traversal/Makefile b/0103_binary_tree_zigzag_level_order_traversal/Makefile new file mode 100644 index 0000000..7e68f18 --- /dev/null +++ b/0103_binary_tree_zigzag_level_order_traversal/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test bst_zigzag.c 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 52% 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 fae68dc..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,68 +68,31 @@ 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 *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 int** zigzagLevelOrder(struct TreeNode* root, int** columnSizes, int* returnSize) +static int** zigzagLevelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes) { if (root == NULL) { *returnSize = 0; @@ -144,25 +100,43 @@ static int** zigzagLevelOrder(struct TreeNode* root, int** columnSizes, int* ret } 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 *)); - *columnSizes = malloc(BST_MAX_LEVEL * sizeof(int)); - memset(*columnSizes, 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, *columnSizes, level); - } else { - queue(&q0, &q1, 0, &free_list, results, *columnSizes, level); + *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); + 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++; } @@ -223,7 +197,7 @@ int main(void) node2[3].right = NULL; int i, j, count = 0, *col_sizes; - int **lists = zigzagLevelOrder(&root, &col_sizes, &count); + int **lists = zigzagLevelOrder(&root, &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/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/0104_maximum_depth_of_binary_tree/Makefile b/0104_maximum_depth_of_binary_tree/Makefile new file mode 100644 index 0000000..43333d6 --- /dev/null +++ b/0104_maximum_depth_of_binary_tree/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test bst_depth.c 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/0105_construct_binary_tree_from_preorder_and_inorder_traversal/Makefile b/0105_construct_binary_tree_from_preorder_and_inorder_traversal/Makefile new file mode 100644 index 0000000..737631e --- /dev/null +++ b/0105_construct_binary_tree_from_preorder_and_inorder_traversal/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test binary_tree_build.c diff --git a/0105_construct_binary_tree_from_preorder_and_inorder_traversal/binary_tree_build.c b/0105_construct_binary_tree_from_preorder_and_inorder_traversal/binary_tree_build.c new file mode 100644 index 0000000..53d4916 --- /dev/null +++ b/0105_construct_binary_tree_from_preorder_and_inorder_traversal/binary_tree_build.c @@ -0,0 +1,138 @@ +#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 struct TreeNode *dfs(int *preorder, int pre_low, int pre_high, int *inorder, + int in_low, int in_high, struct list_head *in_heads, int size) +{ + if (in_low > in_high || pre_low > pre_high) { + return NULL; + } + struct TreeNode *tn = malloc(sizeof(*tn)); + tn->val = preorder[pre_low]; + int index = find(preorder[pre_low], size, in_heads); + tn->left = dfs(preorder, pre_low + 1, pre_low + (index - in_low), inorder, in_low, index - 1, in_heads, size); + tn->right = dfs(preorder, pre_high - (in_high - index - 1), pre_high, inorder, index + 1, in_high, in_heads, size); + return tn; +} + +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]); +} + +struct TreeNode *buildTree(int *preorder, int preorderSize, int *inorder, int inorderSize) +{ + 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(preorder, 0, preorderSize - 1, inorder, 0, inorderSize - 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 preorder[] = { 8,4,2,1,3,6,5,7,12,10,9,11,14,13,15 }; + //int inorder[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 }; + int preorder[] = { 7,-10,-4,3,-1,2,-8,11 }; + int inorder[] = { -4,-10,3,-1,7,11,-8,2 }; + //int preorder[] = { 3,2,1 }; + //int preorder[] = { 3,1,2 }; + //int preorder[] = { 2,1,3 }; + //int preorder[] = { 1,3,2 }; + //int preorder[] = { 1,2,3 }; + //int inorder[] = { 1,2,3 }; + int pre_size = sizeof(preorder) / sizeof(*preorder); + int in_size = sizeof(inorder) / sizeof(*inorder); + struct TreeNode *root = buildTree(preorder, pre_size, inorder, in_size); + dump(root); + printf("\n"); + return 0; +} 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/0106_construct_binary_tree_from_inorder_and_postorder_traversal/Makefile b/0106_construct_binary_tree_from_inorder_and_postorder_traversal/Makefile new file mode 100644 index 0000000..737631e --- /dev/null +++ b/0106_construct_binary_tree_from_inorder_and_postorder_traversal/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test binary_tree_build.c 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/0107_binary_tree_level_order_traversal_ii/Makefile b/0107_binary_tree_level_order_traversal_ii/Makefile new file mode 100644 index 0000000..e07b89e --- /dev/null +++ b/0107_binary_tree_level_order_traversal_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test bst_bfs.c diff --git a/0107_binary_tree_level_order_traversal_ii/bst_bfs.c b/0107_binary_tree_level_order_traversal_ii/bst_bfs.c new file mode 100644 index 0000000..2464fbf --- /dev/null +++ b/0107_binary_tree_level_order_traversal_ii/bst_bfs.c @@ -0,0 +1,100 @@ +#include +#include +#include + + +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 *returnColumnSizes array must be malloced, assume caller calls free(). + **/ +int** levelOrderBottom(struct TreeNode* root, int* returnSize, int** returnColumnSizes) +{ + if (root == NULL) { + *returnSize = 0; + return NULL; + } + + int size = 1; + *returnSize = 0; + 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; + for (i = 0, j = *returnSize - 1; i < j; i++, j--) { + int *ptmp = results[i]; + results[i] = results[j]; + results[j] = ptmp; + int tmp = (*returnColumnSizes)[i]; + (*returnColumnSizes)[i] = (*returnColumnSizes)[j]; + (*returnColumnSizes)[j] = tmp; + } + + 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 = levelOrderBottom(&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/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/0108_convert_sorted_array_to_binary_search_tree/Makefile b/0108_convert_sorted_array_to_binary_search_tree/Makefile new file mode 100644 index 0000000..cbb552d --- /dev/null +++ b/0108_convert_sorted_array_to_binary_search_tree/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test bst_convert.c diff --git a/0108_convert_sorted_array_to_binary_search_tree/bst_convert.c b/0108_convert_sorted_array_to_binary_search_tree/bst_convert.c new file mode 100644 index 0000000..1399058 --- /dev/null +++ b/0108_convert_sorted_array_to_binary_search_tree/bst_convert.c @@ -0,0 +1,38 @@ +#include +#include + + +struct TreeNode { + int val; + struct TreeNode *left; + struct TreeNode *right; +}; + +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 = partition(nums, lo, mid - 1); + node->right = partition(nums, mid + 1, hi); + return node; +} + +static struct TreeNode* sortedArrayToBST(int* nums, int numsSize) +{ + return partition(nums, 0, numsSize - 1); +} + +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]); + } + sortedArrayToBST(nums, count); + return 0; +} 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/0109_convert_sorted_list_to_binary_search_tree/Makefile b/0109_convert_sorted_list_to_binary_search_tree/Makefile new file mode 100644 index 0000000..cbb552d --- /dev/null +++ b/0109_convert_sorted_list_to_binary_search_tree/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test bst_convert.c 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/010_regular_expression_matching/Makefile b/010_regular_expression_matching/Makefile deleted file mode 100644 index e012347..0000000 --- a/010_regular_expression_matching/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test regular_expression.c diff --git a/010_regular_expression_matching/regular_expression.c b/010_regular_expression_matching/regular_expression.c deleted file mode 100644 index 37c62cd..0000000 --- a/010_regular_expression_matching/regular_expression.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include -#include - -bool isMatch(char* s, char* p) { - if (*p == '\0') { - return *s == '\0'; - } - /* p's length 1 is special case */ - if (*(p + 1) == '\0' || *(p + 1) != '*') { - if (*s == '\0' || ( *p != '.' && *s != *p)) { - return false; - } else { - return isMatch(s + 1, p + 1); - } - } - int len = strlen(s); - int i = -1; - while (i < len && (i < 0 || *p == '.' || *p == *(s + i))) { - if (isMatch(s + i + 1, p + 2)) { - return true; - } - i++; - } - return false; -} - -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/0110_balanced_binary_tree/Makefile b/0110_balanced_binary_tree/Makefile new file mode 100644 index 0000000..5c6b35d --- /dev/null +++ b/0110_balanced_binary_tree/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test balanced_bst.c 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/0111_minimum_depth_of_binary_tree/Makefile b/0111_minimum_depth_of_binary_tree/Makefile new file mode 100644 index 0000000..43333d6 --- /dev/null +++ b/0111_minimum_depth_of_binary_tree/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test bst_depth.c 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/0112_path_sum/Makefile b/0112_path_sum/Makefile new file mode 100644 index 0000000..6f978a5 --- /dev/null +++ b/0112_path_sum/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test path_sum.c 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/0113_path_sum_ii/Makefile b/0113_path_sum_ii/Makefile new file mode 100644 index 0000000..6f978a5 --- /dev/null +++ b/0113_path_sum_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test path_sum.c diff --git a/113_path_sum_ii/path_sum.c b/0113_path_sum_ii/path_sum.c similarity index 61% rename from 113_path_sum_ii/path_sum.c rename to 0113_path_sum_ii/path_sum.c index 9f07251..cb52c2f 100644 --- a/113_path_sum_ii/path_sum.c +++ b/0113_path_sum_ii/path_sum.c @@ -2,33 +2,36 @@ #include #include + struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; -static void recursive(struct TreeNode *node, int sum, int *stack, int len, int **results, int *sizes, int *count) +static void dfs(struct TreeNode *node, int sum, int *stack, int len, int **results, int *sizes, int *count) { if (node == NULL) { return; - } - - sum -= node->val; - if (node->left == NULL && node->right == NULL && sum == 0) { + } else if (node->left == NULL && node->right == NULL && sum == node->val) { results[*count] = malloc((len + 1) * sizeof(int)); memcpy(results[*count], stack, len * sizeof(int)); results[*count][len] = node->val; sizes[*count] = len + 1; (*count)++; - return; + } else { + stack[len] = node->val; + dfs(node->left, sum - node->val, stack, len + 1, results, sizes, count); + dfs(node->right, sum - node->val, stack, len + 1, results, sizes, count); } - stack[len] = node->val; - recursive(node->left, sum, stack, len + 1, results, sizes, count); - recursive(node->right, sum, stack, len + 1, results, sizes, count); } -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; @@ -38,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)); - recursive(root, sum, stack, 0, results, *columnSizes, returnSize); + *returnColumnSizes = malloc(cap * sizeof(int)); + dfs(root, sum, stack, 0, results, *returnColumnSizes, returnSize); return results; } @@ -79,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/0114_flatten_binary_tree_to_linked_list/Makefile b/0114_flatten_binary_tree_to_linked_list/Makefile new file mode 100644 index 0000000..2c1b4b2 --- /dev/null +++ b/0114_flatten_binary_tree_to_linked_list/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test flatten.c diff --git a/114_flatten_binary_tree_to_linked_list/flatten.c b/0114_flatten_binary_tree_to_linked_list/flatten.c similarity index 88% rename from 114_flatten_binary_tree_to_linked_list/flatten.c rename to 0114_flatten_binary_tree_to_linked_list/flatten.c index 58072f6..ddad243 100644 --- a/114_flatten_binary_tree_to_linked_list/flatten.c +++ b/0114_flatten_binary_tree_to_linked_list/flatten.c @@ -8,7 +8,7 @@ struct TreeNode { struct TreeNode *right; }; -static struct TreeNode *recursive(struct TreeNode *node) +static struct TreeNode *partition(struct TreeNode *node) { if (node == NULL) { return NULL; @@ -18,8 +18,8 @@ static struct TreeNode *recursive(struct TreeNode *node) return node; } - struct TreeNode *right_last = recursive(node->right); - struct TreeNode *left_last = recursive(node->left); + struct TreeNode *right_last = partition(node->right); + struct TreeNode *left_last = partition(node->left); if (left_last != NULL) { left_last->right = node->right; @@ -32,7 +32,7 @@ static struct TreeNode *recursive(struct TreeNode *node) static void flatten(struct TreeNode *root) { - recursive(root); + partition(root); } int main(void) diff --git a/0115_distinct_subsequences/Makefile b/0115_distinct_subsequences/Makefile new file mode 100644 index 0000000..03f027e --- /dev/null +++ b/0115_distinct_subsequences/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test distinct_subseq.c diff --git a/115_distinct_subsequences/distinct_subseq.c b/0115_distinct_subsequences/distinct_subseq.c similarity index 94% rename from 115_distinct_subsequences/distinct_subseq.c rename to 0115_distinct_subsequences/distinct_subseq.c index 9ab6849..a367df4 100644 --- a/115_distinct_subsequences/distinct_subseq.c +++ b/0115_distinct_subsequences/distinct_subseq.c @@ -30,6 +30,7 @@ static int numDistinct(char* s, char* t) dp[0][i] = 0; } + /* I guess it, just dump the dp table and you will find the rule... */ for (i = 1; i < s_len - start; i++) { dp[i][0] = dp[i - 1][0]; if (s[start + i] == t[0]) { diff --git a/0116_populating_next_right_pointers_in_each_node/Makefile b/0116_populating_next_right_pointers_in_each_node/Makefile new file mode 100644 index 0000000..d856c85 --- /dev/null +++ b/0116_populating_next_right_pointers_in_each_node/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test connect.c 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 9ff181f..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,29 +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) { - struct TreeLinkNode *head = root; + if (root == NULL) { + return 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/0117_populating_next_right_pointers_in_each_node_ii/Makefile b/0117_populating_next_right_pointers_in_each_node_ii/Makefile new file mode 100644 index 0000000..d856c85 --- /dev/null +++ b/0117_populating_next_right_pointers_in_each_node_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test connect.c 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/0118_pascal_triangle/Makefile b/0118_pascal_triangle/Makefile new file mode 100644 index 0000000..309f7fe --- /dev/null +++ b/0118_pascal_triangle/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test pascal_triangle.c 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/0119_pascal_triangle_ii/Makefile b/0119_pascal_triangle_ii/Makefile new file mode 100644 index 0000000..309f7fe --- /dev/null +++ b/0119_pascal_triangle_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test pascal_triangle.c 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/011_container_with_most_water/Makefile b/011_container_with_most_water/Makefile deleted file mode 100644 index cfc4a90..0000000 --- a/011_container_with_most_water/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test container.c diff --git a/0120_triangle/Makefile b/0120_triangle/Makefile new file mode 100644 index 0000000..7b0c42e --- /dev/null +++ b/0120_triangle/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test triangle.c diff --git a/120_triangle/triangle.c b/0120_triangle/triangle.c similarity index 54% rename from 120_triangle/triangle.c rename to 0120_triangle/triangle.c index 430c425..bcf9875 100644 --- a/120_triangle/triangle.c +++ b/0120_triangle/triangle.c @@ -3,35 +3,35 @@ #include #include -static int recursive(int** triangle, int row_size, int *col_sizes, - int row, int col, int **sums, bool **passes) + +static int dfs(int** triangle, int row_size, int *col_sizes, + 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 = recursive(triangle, row_size, col_sizes, row + 1, col, sums, passes); - int s2 = recursive(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 recursive(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/0121_best_time_to_buy_and_sell_stock/Makefile b/0121_best_time_to_buy_and_sell_stock/Makefile new file mode 100644 index 0000000..5d7d4bd --- /dev/null +++ b/0121_best_time_to_buy_and_sell_stock/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test stock.c 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/0122_best_time_to_buy_and_sell_stock_ii/Makefile b/0122_best_time_to_buy_and_sell_stock_ii/Makefile new file mode 100644 index 0000000..5d7d4bd --- /dev/null +++ b/0122_best_time_to_buy_and_sell_stock_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test stock.c 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/0123_best_time_to_buy_and_sell_stock_iii/Makefile b/0123_best_time_to_buy_and_sell_stock_iii/Makefile new file mode 100644 index 0000000..5d7d4bd --- /dev/null +++ b/0123_best_time_to_buy_and_sell_stock_iii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test stock.c 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 63% 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 86d0f95..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 @@ -1,6 +1,34 @@ +#include #include #include + +#if 0 +static inline max(int a, int b) +{ + return a > b ? a : b; +} + +static int maxProfit(int* prices, int pricesSize) +{ + int i; + int s1 = INT_MIN; /* first buy state */ + int s2 = 0; /* first sell state */ + int s3 = INT_MIN; /* second buy state */ + int s4 = 0; /* second sell state */ + + for (i = 0; i < pricesSize; i++) { + /* state transition */ + s1 = max(s1, 0 - prices[i]); + s2 = max(s2, s1 + prices[i]); + s3 = max(s3, s2 - prices[i]); + s4 = max(s4, s3 + prices[i]); + } + + return max(s2, s4); +} +#else + static int maxProfit(int* prices, int pricesSize) { if (pricesSize == 0) { @@ -9,6 +37,7 @@ static int maxProfit(int* prices, int pricesSize) int i, tmp, diff = 0, min = prices[0]; int *left_profit = malloc(pricesSize * sizeof(int)); + left_profit[0] = 0; for (i = 1; i < pricesSize; i++) { if (prices[i] < min) { min = prices[i]; @@ -24,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; @@ -35,6 +64,7 @@ static int maxProfit(int* prices, int pricesSize) return total; } +#endif int main(int argc, char **argv) { 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/0124_binary_tree_maximum_path_sum/Makefile b/0124_binary_tree_maximum_path_sum/Makefile new file mode 100644 index 0000000..e973351 --- /dev/null +++ b/0124_binary_tree_maximum_path_sum/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test bst_max_path.c 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 74% 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 31f9ac0..ff35b9a 100644 --- a/124_binary_tree_maximum_path_sum/bst_max_path.c +++ b/0124_binary_tree_maximum_path_sum/bst_max_path.c @@ -8,36 +8,36 @@ struct TreeNode { struct TreeNode *right; }; -static int recursive(struct TreeNode *node, int *max) +static inline int maximum(int a, int b) { - int left_max = 0; - int right_max = 0; + return a > b ? a : b; +} - if (node->left != NULL) { - left_max = recursive(node->left, max); +static int dfs(struct TreeNode *root, int *max) +{ + if (root == NULL) { + return 0; } - if (node->right != NULL) { - right_max = recursive(node->right, max); - } + /* In case of negative node value */ + int subl = maximum(dfs(root->left, max), 0); + int subr = maximum(dfs(root->right, max), 0); - int sum = node->val + left_max + right_max; + int sum = root->val + subl + subr; if (sum > *max) { *max = sum; } - int path_sum = node->val + (right_max > left_max ? right_max : left_max); - return path_sum > 0 ? path_sum : 0; + /* The return value does not equal the sum value + * since we need to return path through the root node + */ + return root->val + maximum(subl, subr); } static int maxPathSum(struct TreeNode* root) { - if (root == NULL) { - return 0; - } - int max = INT_MIN; - recursive(root, &max); + dfs(root, &max); return max; } 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/0125_valid_palindrome/Makefile b/0125_valid_palindrome/Makefile new file mode 100644 index 0000000..a28cb86 --- /dev/null +++ b/0125_valid_palindrome/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test valid_palindrome.c 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/0126_word_ladder_ii/Makefile b/0126_word_ladder_ii/Makefile new file mode 100644 index 0000000..0485a4b --- /dev/null +++ b/0126_word_ladder_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test word_ladder.c diff --git a/0126_word_ladder_ii/word_ladder.c b/0126_word_ladder_ii/word_ladder.c new file mode 100644 index 0000000..9efc70f --- /dev/null +++ b/0126_word_ladder_ii/word_ladder.c @@ -0,0 +1,262 @@ +#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_first_entry(ptr, type, field) list_entry((ptr)->next, 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)) + +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; +} + +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 int BKDRHash(char* str, int size) +{ + int seed = 131; // 31 131 1313 13131 131313 etc.. + unsigned int hash = 0 ; + while (*str != '\0') { + hash = hash * seed + (*str++); + } + return hash % size; +} + +static struct word_node *find(char *word, struct list_head *dict, int size, int step) +{ + struct word_node *node; + int hash = BKDRHash(word, size); + list_for_each_entry(node, &dict[hash], node) { + if (!strcmp(node->word, word)) { + if (node->step == 0 || node->step == step) { + return node; + } + } + } + return NULL; +} + +/** + ** 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(). + **/ +char*** findLadders(char* beginWord, char* endWord, char** wordList, int wordListSize, int* returnSize, int** returnColumnSizes) +{ + int i, word_len = strlen(beginWord); + int hashsize = wordListSize * 2; + char *word = malloc(word_len + 1); + + struct list_head *dict = malloc(hashsize * sizeof(*dict)); + for (i = 0; i < hashsize; i++) { + INIT_LIST_HEAD(dict + i); + } + + struct list_head *level_caches = malloc(wordListSize * sizeof(*level_caches)); + for (i = 0; i < wordListSize; i++) { + INIT_LIST_HEAD(&level_caches[i]); + } + + /* Word dictionary */ + *returnSize = 0; + bool found = false; + struct word_node *node, *wn; + for (i = 0; i < wordListSize; i++) { + node = malloc(sizeof(*node)); + node->word = wordList[i]; + node->step = 0; + int hash = BKDRHash(wordList[i], hashsize); + list_add(&node->node, &dict[hash]); + if (!strcmp(endWord, wordList[i])) { + found = true; + } + } + if (!found) { + return NULL; + } + + /* FIFO */ + struct list_head queue; + INIT_LIST_HEAD(&queue); + + /* Build tree structure for BFS */ + struct word_node *root = malloc(sizeof(*root) + sizeof(void *)); + root->word = beginWord; + root->step = 1; + root->par_num = 1; + root->parents[0] = NULL; + list_add_tail(&root->sibling, &level_caches[0]); + node = find(beginWord, dict, hashsize, 1); + if (node != NULL) { + node->step = 1; + } + + /* 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 < 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, dict, hashsize, first->step + 1); + if (node != NULL) { + int enqueue = 1; + /* 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 */ + wn->parents[wn->par_num++] = first; + break; + } + } + + if (enqueue) { + /* new level cache and enqueue */ + node->step = first->step + 1; + struct word_node *new = malloc(sizeof(*new) + 15 * sizeof(void *)); + new->word = node->word; + new->step = node->step; + new->par_num = 0; + list_add_tail(&new->sibling, &level_caches[first->step]); + list_add_tail(&new->link, &queue); + new->parents[new->par_num++] = first; + } + } + } + word[i] = o; + } + + if (list_empty(&queue)) { + return NULL; + } else { + /* dequeue */ + first = list_first_entry(&queue, struct word_node, link); + list_del(&first->link); + } + } + + int size = first->step; + char ***results = malloc(1000 * sizeof(char **)); + int *indexes = malloc(size * sizeof(int)); + memset(indexes, 0, size * sizeof(int)); + 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; + 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 (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; + } + } + + (*returnSize)++; + } + } + } + + *returnColumnSizes = malloc(*returnSize * sizeof(int)); + for (i = 0; i < *returnSize; i++) { + (*returnColumnSizes)[i] = size; + } + return results; +} + +int main(int argc, char **argv) +{ + if (argc < 3) { + fprintf(stderr, "Usage: ./test begin end dict...\n"); + exit(-1); + } + + int i, j, *sizes, count = 0; + char ***lists = findLadders(argv[1], argv[2], argv + 3, argc - 3, &count, &sizes); + for (i = 0; i < count; i++) { + for (j = 0; j < sizes[i]; j++) { + printf("%s ", lists[i][j]); + } + printf("\n"); + } + + return 0; +} diff --git a/0127_word_ladder/Makefile b/0127_word_ladder/Makefile new file mode 100644 index 0000000..0485a4b --- /dev/null +++ b/0127_word_ladder/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test word_ladder.c diff --git a/127_word_ladder/word_ladder.c b/0127_word_ladder/word_ladder.c similarity index 59% rename from 127_word_ladder/word_ladder.c rename to 0127_word_ladder/word_ladder.c index 3059ae9..f057487 100644 --- a/127_word_ladder/word_ladder.c +++ b/0127_word_ladder/word_ladder.c @@ -1,54 +1,36 @@ #include #include +#include #include -struct hlist_node; - -struct hlist_head { - struct hlist_node *first; -}; - -struct hlist_node { - struct hlist_node *next, **pprev; -}; +#define container_of(ptr, type, member) \ + ((type *)((char *)(ptr) - (size_t)&(((type *)0)->member))) -static inline void INIT_HLIST_HEAD(struct hlist_head *h) { - h->first = NULL; -} +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) -static inline void INIT_HLIST_NODE(struct hlist_node *n) { - n->next = NULL; - n->pprev = NULL; -} +#define list_first_entry(ptr, type, field) list_entry((ptr)->next, type, field) -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; }; -static inline void -INIT_LIST_HEAD(struct list_head *list) +static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list->prev = list; } -static inline int -list_empty(const struct list_head *head) +static inline int list_empty(const struct list_head *head) { return (head->next == head); } -static inline void -__list_add(struct list_head *new, struct list_head *prev, struct list_head *next) +static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { next->prev = new; new->next = next; @@ -56,57 +38,32 @@ __list_add(struct list_head *new, struct list_head *prev, struct list_head *next prev->next = new; } -static inline void -list_add(struct list_head *_new, struct list_head *head) +static inline void list_add(struct list_head *_new, struct list_head *head) { __list_add(_new, head, head->next); } -static inline void -list_add_tail(struct list_head *_new, struct list_head *head) +static inline void list_add_tail(struct list_head *_new, struct list_head *head) { __list_add(_new, head->prev, head); } -static inline void -__list_del(struct list_head *entry) +static inline void __list_del(struct list_head *entry) { entry->next->prev = entry->prev; entry->prev->next = entry->next; } -static inline void -list_del(struct list_head *entry) +static inline void list_del(struct list_head *entry) { __list_del(entry); entry->next = entry->prev = NULL; } -#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(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 word_node { int step; char *word; - struct hlist_node node; + struct list_head node; struct list_head link; }; @@ -120,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; } @@ -140,25 +96,34 @@ 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 */ INIT_LIST_HEAD(&queue); struct word_node *first = malloc(sizeof(*node)); first->word = beginWord; first->step = 1; + /* BFS with FIFO for shortest path */ while (strcmp(first->word, endWord)) { strcpy(word, first->word); for (i = 0; i < len; i++) { @@ -167,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; } @@ -179,6 +145,7 @@ static int ladderLength(char* beginWord, char* endWord, char** wordList, int wor if (list_empty(&queue)) { return 0; } else { + /* dequeue */ first = list_first_entry(&queue, struct word_node, link); list_del(&first->link); } diff --git a/0127_word_ladder/word_ladder.cc b/0127_word_ladder/word_ladder.cc new file mode 100644 index 0000000..f88eaa6 --- /dev/null +++ b/0127_word_ladder/word_ladder.cc @@ -0,0 +1,53 @@ +#include + +using namespace std; + +class Solution { +public: + int ladderLength(string beginWord, string endWord, vector& wordList) { + unordered_set dict(wordList.begin(), wordList.end()); + if (!dict.count(endWord)) { + return 0; + } + + // double BFS + int step = 1; + unordered_set s1, s2, tmp, visited; + s1.insert(beginWord); + s2.insert(endWord); + while (!s1.empty() && !s2.empty()) { + if (s1.size() > s2.size()) { + tmp = s1; + s1 = s2; + s2 = tmp; + } + tmp.clear(); + + for (auto str : s1) { + if (s2.count(str)) { + return step; + } + if (!visited.count(str)) { + visited.insert(str); + } + + for (int i = 0; i < str.length(); i++) { + char o = str[i]; + for (char c = 'a'; c <= 'z'; c++) { + if (c == o) continue; + str[i] = c; + if (dict.count(str) && !visited.count(str)) { + tmp.insert(str); + } + } + str[i] = o; + } + } + + // update + s1 = tmp; + step++; + } + return 0; + } +}; diff --git a/0128_longest_consecutive_sequence/Makefile b/0128_longest_consecutive_sequence/Makefile new file mode 100644 index 0000000..687920c --- /dev/null +++ b/0128_longest_consecutive_sequence/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test consec_seq.c 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/0129_sum_root_to_leaf_numbers/Makefile b/0129_sum_root_to_leaf_numbers/Makefile new file mode 100644 index 0000000..3b4d94c --- /dev/null +++ b/0129_sum_root_to_leaf_numbers/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test sum_tree.c diff --git a/129_sum_root_to_leaf_numbers/sum_tree.c b/0129_sum_root_to_leaf_numbers/sum_tree.c similarity index 64% rename from 129_sum_root_to_leaf_numbers/sum_tree.c rename to 0129_sum_root_to_leaf_numbers/sum_tree.c index c06d7ca..8580e8b 100644 --- a/129_sum_root_to_leaf_numbers/sum_tree.c +++ b/0129_sum_root_to_leaf_numbers/sum_tree.c @@ -1,38 +1,38 @@ #include #include + struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; -static void recursive(struct TreeNode* node, int sum, int *total) +static int dfs(struct TreeNode* node, int sum) { + /* 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) { - *total += sum; - } - - if (node->left != NULL) { - recursive(node->left, sum, total); - } - - if (node->right != NULL) { - recursive(node->right, sum, total); + return sum; + } else { + int total = 0; + if (node->left != NULL) { + total += dfs(node->left, sum); + } + if (node->right != NULL) { + total += dfs(node->right, sum); + } + return total; } } -static int sumNumbers(struct TreeNode* root) +int sumNumbers(struct TreeNode* root) { if (root == NULL) { return 0; } - - int total = 0; - recursive(root, 0, &total); - return total; + return dfs(root, 0); } int main(void) 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/012_roman_numeral/Makefile b/012_roman_numeral/Makefile deleted file mode 100644 index b38195c..0000000 --- a/012_roman_numeral/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o roman_numeral roman_numeral.c diff --git a/0130_surrounded_regions/Makefile b/0130_surrounded_regions/Makefile new file mode 100644 index 0000000..9cc7f01 --- /dev/null +++ b/0130_surrounded_regions/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test surrounded_regions.c diff --git a/130_surrounded_regions/surrounded_regions.c b/0130_surrounded_regions/surrounded_regions.c similarity index 70% rename from 130_surrounded_regions/surrounded_regions.c rename to 0130_surrounded_regions/surrounded_regions.c index 96f2ca4..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,32 +10,27 @@ 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; }; -static inline void -INIT_LIST_HEAD(struct list_head *list) +struct node { + int x, y; + 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) +static inline int list_empty(const struct list_head *head) { return (head->next == head); } -static inline void -__list_add(struct list_head *new, struct list_head *prev, struct list_head *next) +static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { next->prev = new; new->next = next; @@ -42,37 +38,28 @@ __list_add(struct list_head *new, struct list_head *prev, struct list_head *next prev->next = new; } -static inline void -list_add(struct list_head *_new, struct list_head *head) +static inline void list_add(struct list_head *_new, struct list_head *head) { __list_add(_new, head, head->next); } -static inline void -list_add_tail(struct list_head *_new, struct list_head *head) +static inline void list_add_tail(struct list_head *_new, struct list_head *head) { __list_add(_new, head->prev, head); } -static inline void -__list_del(struct list_head *entry) +static inline void __list_del(struct list_head *entry) { entry->next->prev = entry->prev; entry->prev->next = entry->next; } -static inline void -list_del(struct list_head *entry) +static inline void list_del(struct list_head *entry) { __list_del(entry); entry->next = entry->prev = NULL; } -struct node { - struct list_head link; - int x, y; -}; - static struct node *node_new(struct list_head *free_list) { struct node *new; @@ -130,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; @@ -139,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'; } } @@ -190,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'; @@ -224,16 +211,17 @@ int main(void) board[4][4] = 'X'; for (i = 0; i < row_size; i++) { - for (j = 0; j < col_size; j++) { + col_sizes[i] = row_size; + for (j = 0; j < col_sizes[i]; j++) { printf("%c ", board[i][j]); } printf("\n"); } printf("\n"); - solve(board, row_size, col_size); + solve(board, row_size, col_sizes); for (i = 0; i < row_size; i++) { - for (j = 0; j < col_size; j++) { + for (j = 0; j < col_sizes[i]; j++) { printf("%c ", board[i][j]); } printf("\n"); diff --git a/0131_palindrome_patitioning/Makefile b/0131_palindrome_patitioning/Makefile new file mode 100644 index 0000000..34cbc1a --- /dev/null +++ b/0131_palindrome_patitioning/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test palindrome_partition.c diff --git a/131_palindrome_patitioning/palindrome_partition.c b/0131_palindrome_patitioning/palindrome_partition.c similarity index 73% rename from 131_palindrome_patitioning/palindrome_partition.c rename to 0131_palindrome_patitioning/palindrome_partition.c index 25f2e88..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; @@ -19,9 +20,9 @@ static void collect(char *s, int len, int low, int high, struct palindrome *resu } } -static void recursive(struct palindrome *pal_set, int num, int start, - char *s, int len, struct palindrome **stack, int size, - char ***results, int *col_sizes, int *count) +static void dfs(struct palindrome *pal_set, int num, int start, + char *s, int len, struct palindrome **stack, int size, + char ***results, int *count, int *col_sizes) { int i; if (size > 0 && stack[size - 1]->high == len - 1) { @@ -40,7 +41,7 @@ static void recursive(struct palindrome *pal_set, int num, int start, if ((size == 0 && pal_set[i].low == 0) || (size > 0 && stack[size - 1]->high + 1 == pal_set[i].low)) { stack[size] = &pal_set[i]; - recursive(pal_set, num, i + 1, s, len, stack, size + 1, results, col_sizes, count); + dfs(pal_set, num, i + 1, s, len, stack, size + 1, results, count, col_sizes); } } } @@ -48,10 +49,11 @@ static void recursive(struct palindrome *pal_set, int num, int start, /** ** 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(). **/ -char ***partition(char* s, int** columnSizes, int* returnSize) { +char ***partition(char* s, int* returnSize, int** returnColumnSizes) +{ int len = strlen(s); if (len == 0) { *returnSize = 0; @@ -67,9 +69,8 @@ char ***partition(char* s, int** columnSizes, int* returnSize) { char ***results = malloc(cap * sizeof(char **)); struct palindrome **stack = malloc(count * sizeof(*stack)); - *columnSizes = malloc(cap * sizeof(int)); - recursive(pal_set, count, 0, s, len, stack, 0, results, *columnSizes, returnSize); - + *returnColumnSizes = malloc(cap * sizeof(int)); + dfs(pal_set, count, 0, s, len, stack, 0, results, returnSize, *returnColumnSizes); return results; } @@ -82,7 +83,7 @@ int main(int argc, char **argv) int i, j, count = 0; int *col_sizes; - char ***lists = partition(argv[1], &col_sizes, &count); + char ***lists = partition(argv[1], &count, &col_sizes); for (i = 0; i < count; i++) { char **list = lists[i]; for (j = 0; j < col_sizes[i]; j++) { diff --git a/0131_palindrome_patitioning/palindrome_partition.cc b/0131_palindrome_patitioning/palindrome_partition.cc new file mode 100644 index 0000000..9897ddb --- /dev/null +++ b/0131_palindrome_patitioning/palindrome_partition.cc @@ -0,0 +1,42 @@ +#include + +using namespace std; + +class Solution { +public: + vector> partition(string s) { + vector> res; + vector> isPalindrome(s.size(), vector(s.size(), true)); + + // From bottom to up + for (int i = s.length() - 1; i >= 0; i--) { + // From left to right + for (int j = i + 1; j < s.length(); j++) { + // notebook for palindrome substring judgement + isPalindrome[i][j] = s[i] == s[j] && isPalindrome[i + 1][j - 1]; + } + } + + dfs(s, 0, isPalindrome, res); + return res; + } + +private: + vector ans; + void dfs(const string& s, int start, vector>& isPalindrome, vector>& res) { + // DFS for combination. When the start index reaches to the end, all + // the substrings are collected. + if (start == s.length()) { + res.push_back(ans); + return; + } + + for (int i = start; i < s.length(); i++) { + if (isPalindrome[start][i]) { + ans.push_back(s.substr(start, i - start + 1)); + dfs(s, i + 1, isPalindrome, res); + ans.pop_back(); + } + } + } +}; diff --git a/0132_palindrome_patitioning_ii/Makefile b/0132_palindrome_patitioning_ii/Makefile new file mode 100644 index 0000000..34cbc1a --- /dev/null +++ b/0132_palindrome_patitioning_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test palindrome_partition.c 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/0133_clone_graph/Makefile b/0133_clone_graph/Makefile new file mode 100644 index 0000000..02b8339 --- /dev/null +++ b/0133_clone_graph/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test clone_graph.c diff --git a/0133_clone_graph/clone_graph.c b/0133_clone_graph/clone_graph.c new file mode 100644 index 0000000..1c18389 --- /dev/null +++ b/0133_clone_graph/clone_graph.c @@ -0,0 +1,124 @@ +#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 UndirectedGraphNode { + int label; + struct UndirectedGraphNode *neighbors[100]; + int neighborsCount; +}; + +struct label_node { + struct list_head link; + struct UndirectedGraphNode *gn; +}; + +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 struct UndirectedGraphNode *find(int label, int size, struct list_head *heads) +{ + struct label_node *ln; + int hash = (label < 0 ? -label : label) % size; + list_for_each_entry(ln, &heads[hash], link) { + if (ln->gn->label == label) { + return ln->gn; + } + } + return NULL; +} + +static struct UndirectedGraphNode *dfs(struct UndirectedGraphNode *graph, struct list_head *heads, int size) +{ + if (graph == NULL) { + return NULL; + } + + struct UndirectedGraphNode *node = find(graph->label, size, heads); + if (node != NULL) { + return node; + } + + node = malloc(sizeof(*node)); + node->label = graph->label; + node->neighborsCount = graph->neighborsCount; + struct label_node *ln = malloc(sizeof(*ln)); + ln->gn = node; + int hash = (node->label < 0 ? -node->label : node->label) % size; + list_add(&ln->link, &heads[hash]); + + int i; + for (i = 0; i < node->neighborsCount; i++) { + node->neighbors[i] = dfs(graph->neighbors[i], heads, size); + } + + return node; +} + +struct UndirectedGraphNode *cloneGraph(struct UndirectedGraphNode *graph) +{ + int i, cap = 1000; + struct list_head *heads = malloc(cap * sizeof(*heads)); + for (i = 0; i < cap; i++) { + INIT_LIST_HEAD(&heads[i]); + } + return dfs(graph, heads, cap); +} + +int main(void) +{ + struct UndirectedGraphNode n0, n1, n2; + n0.label = 0; + n1.label = 1; + n2.label = 2; + n0.neighborsCount = 2; + n1.neighborsCount = 1; + n2.neighborsCount = 1; + n0.neighbors[0] = &n1; + n0.neighbors[1] = &n2; + n1.neighbors[0] = &n2; + n2.neighbors[0] = &n2; + + struct UndirectedGraphNode *res = cloneGraph(&n0); + return 0; +} diff --git a/0133_clone_graph/clone_graph.cc b/0133_clone_graph/clone_graph.cc new file mode 100644 index 0000000..ca7d8e2 --- /dev/null +++ b/0133_clone_graph/clone_graph.cc @@ -0,0 +1,65 @@ +#include + +using namespace std; + +// Definition for a Node. +class Node { +public: + int val; + vector neighbors; + Node() { + val = 0; + neighbors = vector(); + } + Node(int _val) { + val = _val; + neighbors = vector(); + } + Node(int _val, vector _neighbors) { + val = _val; + neighbors = _neighbors; + } +}; + +class Solution { +public: + Node* cloneGraph(Node* node) { + if (node == nullptr) { + return node; + } +#if 1 // DFS + if (cloned.find(node) != cloned.end()) { + return cloned[node]; + } + + cloned[node] = new Node(node->val); + + for (auto& neighbor : node->neighbors) { + cloned[node]->neighbors.emplace_back(cloneGraph(neighbor)); + } +#else // BFS + queue q; + q.push(node); + cloned[node] = new Node(node->val); + + while (!q.empty()) { + int size = q.size(); + for (int i = 0; i < size; i++) { + auto n = q.front(); + q.pop(); + + for (auto& neighbor : n->neighbors) { + if (cloned.find(neighbor) == cloned.end()) { + cloned[neighbor] = new Node(neighbor->val); + q.push(neighbor); + } + cloned[n]->neighbors.emplace_back(cloned[neighbor]); + } + } + } +#endif + return cloned[node]; + } +private: + unordered_map cloned; +}; diff --git a/0134_gas_station/Makefile b/0134_gas_station/Makefile new file mode 100644 index 0000000..868fcf3 --- /dev/null +++ b/0134_gas_station/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test gas_station.c diff --git a/134_gas_station/gas_station.c b/0134_gas_station/gas_station.c similarity index 69% rename from 134_gas_station/gas_station.c rename to 0134_gas_station/gas_station.c index f9e1641..4c0e85e 100644 --- a/134_gas_station/gas_station.c +++ b/0134_gas_station/gas_station.c @@ -4,6 +4,10 @@ static int canCompleteCircuit(int* gas, int gasSize, int* cost, int costSize) { int i, j, store = 0, start = -1; + + /* the solution(start) is guaranteed to be + * unique for the purpose of this problem + */ for (i = 0; i < gasSize; i++) { if (start < 0) { start = i; @@ -14,14 +18,15 @@ static int canCompleteCircuit(int* gas, int gasSize, int* cost, int costSize) start = -1; } } - if (start > 0) { - for (i = 0; i < start; i++) { - store += gas[i] - cost[i]; - if (store < 0) { - return -1; - } + + /* if start == -1 just return */ + for (i = 0; i < start; i++) { + store += gas[i] - cost[i]; + if (store < 0) { + return -1; } } + return start; } diff --git a/0135_candy/Makefile b/0135_candy/Makefile new file mode 100644 index 0000000..44aae97 --- /dev/null +++ b/0135_candy/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test candy.c diff --git a/135_candy/candy.c b/0135_candy/candy.c similarity index 82% rename from 135_candy/candy.c rename to 0135_candy/candy.c index 25bee29..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; @@ -13,6 +15,7 @@ static int candy(int* ratings, int ratingsSize) if (ratings[i] > ratings[i - 1]) { candies[i] = candies[i - 1] + 1; } else { + /* Set as least so that it will be reset from the opposite side */ candies[i] = 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/0136_single_number/Makefile b/0136_single_number/Makefile new file mode 100644 index 0000000..ba4bb3e --- /dev/null +++ b/0136_single_number/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test single_number.c 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/0137_single_number_ii/Makefile b/0137_single_number_ii/Makefile new file mode 100644 index 0000000..ba4bb3e --- /dev/null +++ b/0137_single_number_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test single_number.c 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/0138_copy_list_with_random_pointer/Makefile b/0138_copy_list_with_random_pointer/Makefile new file mode 100644 index 0000000..7f02416 --- /dev/null +++ b/0138_copy_list_with_random_pointer/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test copy_list.c diff --git a/0138_copy_list_with_random_pointer/copy_list.c b/0138_copy_list_with_random_pointer/copy_list.c new file mode 100644 index 0000000..39c762d --- /dev/null +++ b/0138_copy_list_with_random_pointer/copy_list.c @@ -0,0 +1,84 @@ +#include +#include + +struct Node { + int val; + struct Node *next; + struct Node *random; +}; + +static struct Node *copyRandomList(struct Node *head) +{ + 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 = q->next) { + q = p->next; + q->random = p->random != NULL ? p->random->next : NULL; + } + + struct Node dummy; + struct Node *prev = &dummy; + 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; +} + +int main(int argc, char **argv) +{ + int i, count = argc - 1; + struct Node *head = NULL, *p, *prev; + for (i = 0; i < count; i++) { + p = malloc(sizeof(*p)); + p->val = atoi(argv[i + 1]); + p->next = NULL; + p->random = NULL; + if (head == NULL) { + head = p; + } else { + prev->next = p; + prev->random = p; + } + prev = p; + } + + struct Node *r = head; + struct Node *q = p = copyRandomList(head); + + for (r = head; r != NULL; r = r->next) { + printf("%d ", r->val); + } + printf("\n"); + + for (r = head; r != NULL; r = r->random) { + printf("%d ", r->val); + } + printf("\n"); + + for (; p != NULL; p = p->next) { + printf("%d ", p->val); + } + printf("\n"); + + for (; q != NULL; q = q->random) { + printf("%d ", q->val); + } + printf("\n"); + return 0; +} 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/0139_word_break/Makefile b/0139_word_break/Makefile new file mode 100644 index 0000000..0763077 --- /dev/null +++ b/0139_word_break/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test word_break.c 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/013_roman_to_integer/Makefile b/013_roman_to_integer/Makefile deleted file mode 100644 index c713a4f..0000000 --- a/013_roman_to_integer/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test roman_to_integer.c diff --git a/0140_word_break_ii/Makefile b/0140_word_break_ii/Makefile new file mode 100644 index 0000000..0763077 --- /dev/null +++ b/0140_word_break_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test word_break.c 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/0141_linked_list_cycle/Makefile b/0141_linked_list_cycle/Makefile new file mode 100644 index 0000000..695aff0 --- /dev/null +++ b/0141_linked_list_cycle/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test list_cycle.c 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/0142_linked_list_cycle_ii/Makefile b/0142_linked_list_cycle_ii/Makefile new file mode 100644 index 0000000..695aff0 --- /dev/null +++ b/0142_linked_list_cycle_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test list_cycle.c 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/0143_reorder_list/Makefile b/0143_reorder_list/Makefile new file mode 100644 index 0000000..c4009ef --- /dev/null +++ b/0143_reorder_list/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test reorder_list.c diff --git a/0143_reorder_list/reorder_list.c b/0143_reorder_list/reorder_list.c new file mode 100644 index 0000000..1377e3f --- /dev/null +++ b/0143_reorder_list/reorder_list.c @@ -0,0 +1,75 @@ +#include +#include + +struct ListNode { + int val; + struct ListNode *next; +}; + +static void reorderList(struct ListNode *head) +{ + if (head == NULL || head->next == NULL) { + return; + } + + int count = 0; + struct ListNode dummy; + struct ListNode *prev = &dummy; + struct ListNode *p, *q; + + /* locate half length */ + dummy.next = head; + for (p = head, q = head; q != NULL; q = q->next) { + if ((++count & 0x1) == 0) { + prev = p; + p = p->next; + } + } + + /* reverse latter half list */ + while (p->next != NULL) { + q = p->next; + /* deletion */ + p->next = q->next; + /* insertion */ + q->next = prev->next; + prev->next = q; + } + + /* insert each element interleavingly */ + struct ListNode *last = prev; + p = head; + while (p != last) { + q = last->next; + /* deletion */ + last->next = q->next; + /* insertion */ + q->next = p->next; + p->next = q; + p = q->next; + } +} + +int main(int argc, char **argv) +{ + int i, count = argc - 1; + struct ListNode *head = NULL, *p, *prev; + for (i = 0; i < count; i++) { + p = malloc(sizeof(*p)); + p->val = atoi(argv[i + 1]); + p->next = NULL; + if (head == NULL) { + head = p; + } else { + prev->next = p; + } + prev = p; + } + + reorderList(head); + for (p = head; p != NULL; p = p->next) { + printf("%d ", p->val); + } + printf("\n"); + return 0; +} diff --git a/0144_binary_tree_preorder_traversal/Makefile b/0144_binary_tree_preorder_traversal/Makefile new file mode 100644 index 0000000..0362c20 --- /dev/null +++ b/0144_binary_tree_preorder_traversal/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test bst_preorder.c diff --git a/144_binary_tree_preorder_traversal/bst_preorder.c b/0144_binary_tree_preorder_traversal/bst_preorder.c similarity index 70% rename from 144_binary_tree_preorder_traversal/bst_preorder.c rename to 0144_binary_tree_preorder_traversal/bst_preorder.c index 14e3f56..a5372fa 100644 --- a/144_binary_tree_preorder_traversal/bst_preorder.c +++ b/0144_binary_tree_preorder_traversal/bst_preorder.c @@ -11,7 +11,8 @@ struct TreeNode { ** Return an array of size *returnSize. ** Note: The returned array must be malloced, assume caller calls free(). **/ -static int* preorderTraversal(struct TreeNode* root, int* returnSize) { +static int* preorderTraversal(struct TreeNode* root, int* returnSize) +{ if (root == NULL) { return NULL; } @@ -20,18 +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; - - while (node != NULL || top != stack) { - if (node == NULL) { - node = *--top; - } - results[count++] = node->val; - if (node->right != NULL) { - *top++ = node->right; + /* root != NULL condition is just for the first iteration and + * never push NULL into the stack + */ + 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; } - 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/0145_binary_tree_postorder_traversal/Makefile b/0145_binary_tree_postorder_traversal/Makefile new file mode 100644 index 0000000..1a34f47 --- /dev/null +++ b/0145_binary_tree_postorder_traversal/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test bst_postorder.c diff --git a/145_binary_tree_postorder_traversal/bst_postorder.c b/0145_binary_tree_postorder_traversal/bst_postorder.c similarity index 52% rename from 145_binary_tree_postorder_traversal/bst_postorder.c rename to 0145_binary_tree_postorder_traversal/bst_postorder.c index f917af9..47f49d8 100644 --- a/145_binary_tree_postorder_traversal/bst_postorder.c +++ b/0145_binary_tree_postorder_traversal/bst_postorder.c @@ -18,35 +18,34 @@ struct node_backlog { **/ static int* postorderTraversal(struct TreeNode* root, int* returnSize) { - if (root == NULL) { - return NULL; - } - - int cap = 10000, count = 0; - int *results = malloc(cap * sizeof(int)); - struct node_backlog *stack = malloc(cap / 16 * sizeof(*stack)); + int count = 0; + int *results = malloc(100 * sizeof(int)); + struct node_backlog *stack = malloc(100 * sizeof(*stack)); struct node_backlog *top = stack; - struct TreeNode *node = root; - struct node_backlog nbl; - while (node != NULL || top != stack) { - if (node == NULL) { - nbl = *--top; - if (nbl.right != NULL) { - node = nbl.right; - nbl.right = NULL; - *top++ = nbl; + /* 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) { + /* switch to right child but not pop up the parent */ + root = (top - 1)->right; + /* avoid infinite loop */ + (top - 1)->right = NULL; } else { - node = nbl.parent; - results[count++] = node->val; - node = NULL; - continue; + root = (--top)->parent; + results[count++] = root->val; + /* we need to backtrace */ + root = NULL; } } - nbl.parent = node; - nbl.right = node->right; - *top++ = nbl; - node = node->left; } *returnSize = count; 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/0146_lru_cache/Makefile b/0146_lru_cache/Makefile new file mode 100644 index 0000000..30aa1f2 --- /dev/null +++ b/0146_lru_cache/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test lru_cache.c 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/0147_insertion_sort_list/Makefile b/0147_insertion_sort_list/Makefile new file mode 100644 index 0000000..f0c8610 --- /dev/null +++ b/0147_insertion_sort_list/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test insert_sort_list.c 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/0148_sort_list/Makefile b/0148_sort_list/Makefile new file mode 100644 index 0000000..0f4bed1 --- /dev/null +++ b/0148_sort_list/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test sort_list.c diff --git a/148_sort_list/sort_list.c b/0148_sort_list/sort_list.c similarity index 89% rename from 148_sort_list/sort_list.c rename to 0148_sort_list/sort_list.c index 90d34f4..9673199 100644 --- a/148_sort_list/sort_list.c +++ b/0148_sort_list/sort_list.c @@ -6,7 +6,7 @@ struct ListNode { struct ListNode *next; }; -static void recursive(struct ListNode *dummy, struct ListNode *end) +static void traverse(struct ListNode *dummy, struct ListNode *end) { if (dummy == NULL || dummy->next == end) { return; @@ -32,15 +32,15 @@ static void recursive(struct ListNode *dummy, struct ListNode *end) } } - recursive(dummy, pivot); - recursive(first, end); + traverse(dummy, pivot); + traverse(first, end); } static struct ListNode *sortList(struct ListNode *head) { struct ListNode dummy; dummy.next = head; - recursive(&dummy, NULL); + traverse(&dummy, NULL); return dummy.next; } diff --git a/0149_max_points_on_a_line/Makefile b/0149_max_points_on_a_line/Makefile new file mode 100644 index 0000000..fb4da58 --- /dev/null +++ b/0149_max_points_on_a_line/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test points_on_line.c 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 71% 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 25388f6..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,48 +3,6 @@ #include #include -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 INIT_HLIST_NODE(struct hlist_node *n) { - n->next = NULL; - n->pprev = 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; - } -} #define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - (size_t)&(((type *)0)->member))) @@ -52,11 +10,14 @@ static inline void hlist_del(struct hlist_node *n) #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 list_head { + struct list_head *next, *prev; +}; struct Point { int x, y; @@ -65,14 +26,41 @@ struct Point { struct point_node { int p1; int p2; - struct hlist_node node; + struct list_head link; }; -static bool can_insert(struct hlist_head *head, int p1, int p2) +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 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; @@ -107,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++) { @@ -144,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/014_longest_common_prefix/Makefile b/014_longest_common_prefix/Makefile deleted file mode 100644 index 1003ec6..0000000 --- a/014_longest_common_prefix/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test common_prefix.c diff --git a/014_longest_common_prefix/common_prefix.c b/014_longest_common_prefix/common_prefix.c deleted file mode 100644 index aa1c63a..0000000 --- a/014_longest_common_prefix/common_prefix.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include -#include - -static char* longestCommonPrefix(char** strs, int strsSize) -{ - int i, capacity = 50, count = 0; - char *result = malloc(50); - bool go_on = true; - while (strsSize > 0 && go_on) { - char temp = strs[0][count]; - for (i = 1; i < strsSize; i++) { - if (temp != strs[i][count]) break; - } - if (i == strsSize && temp != '\0') { - if (count + 1 + 1 >= capacity) { - capacity *= 2; - result = realloc(result, capacity + 1); - } - result[count++] = temp; - } else { - go_on = false; - } - } - result[count++] = '\0'; - return result; -} - -int main(int argc, char **argv) -{ - printf("%s\n", longestCommonPrefix(argv + 1, argc - 1)); - return 0; -} diff --git a/0150_evaluate_reverse_polish_notation/Makefile b/0150_evaluate_reverse_polish_notation/Makefile new file mode 100644 index 0000000..597b8ab --- /dev/null +++ b/0150_evaluate_reverse_polish_notation/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test eval_rpn.c 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/0151_reverse_words_in_a_string/Makefile b/0151_reverse_words_in_a_string/Makefile new file mode 100644 index 0000000..6d216b5 --- /dev/null +++ b/0151_reverse_words_in_a_string/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test reverse.c diff --git a/0151_reverse_words_in_a_string/reverse.c b/0151_reverse_words_in_a_string/reverse.c new file mode 100644 index 0000000..dab5480 --- /dev/null +++ b/0151_reverse_words_in_a_string/reverse.c @@ -0,0 +1,49 @@ +#include +#include +#include + +static reverse(char *s, int lo, int hi) +{ + while (lo < hi) { + char c = s[lo]; + s[lo] = s[hi]; + s[hi] = c; + lo++; + hi--; + } +} + +static void reverseWords(char *s) +{ + int i = 0, j = 0; + while (s[i] != '\0') { + while (s[i] == ' ') { + i++; + } + if (s[i] == '\0') break; + while (s[i] != '\0' && s[i] != ' ') { + s[j++] = s[i++]; + } + s[j++] = s[i]; + } + s[j] = '\0'; + s[--j] = '\0'; + reverse(s, 0, j - 1); + + for (i = 0, j = 0; s[i] != '\0';) { + for (j = i; s[j] != '\0' && s[j] != ' '; j++) {} + reverse(s, i, j - 1); + for (i = j; s[i] != '\0' && s[i] == ' '; i++) {} + } +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test string\n"); + exit(-1); + } + reverseWords(argv[1]); + printf("%s\n", argv[1]); + return 0; +} diff --git a/0152_maximum_product_subarray/Makefile b/0152_maximum_product_subarray/Makefile new file mode 100644 index 0000000..b216c6f --- /dev/null +++ b/0152_maximum_product_subarray/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test subarray.c diff --git a/0152_maximum_product_subarray/subarray.c b/0152_maximum_product_subarray/subarray.c new file mode 100644 index 0000000..3af1389 --- /dev/null +++ b/0152_maximum_product_subarray/subarray.c @@ -0,0 +1,42 @@ +#include +#include +#include + + +static inline int min(int a, int b) +{ + return a < b ? a : b; +} + +static inline int max(int a, int b) +{ + return a > b ? a : b; +} + +static int maxProduct(int* nums, int numsSize) +{ + int i, maximum = INT_MIN; + int dp_min = 1; + int dp_max = 1; + /* dp records the min or max result of subarray nums[0...i] */ + for (i = 0; i < numsSize; i++) { + int prev_min = dp_min; + int prev_max = dp_max; + dp_min = min(nums[i], min(prev_min * nums[i], prev_max * nums[i])); + dp_max = max(nums[i], max(prev_min * nums[i], prev_max * nums[i])); + maximum = max(dp_max, maximum); + } + + return maximum; +} + +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", maxProduct(nums, count)); + return 0; +} diff --git a/0153_find_minimum_in_rotated_sorted_array/Makefile b/0153_find_minimum_in_rotated_sorted_array/Makefile new file mode 100644 index 0000000..5cd0451 --- /dev/null +++ b/0153_find_minimum_in_rotated_sorted_array/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test minimum.c diff --git a/0153_find_minimum_in_rotated_sorted_array/minimum.c b/0153_find_minimum_in_rotated_sorted_array/minimum.c new file mode 100644 index 0000000..677d426 --- /dev/null +++ b/0153_find_minimum_in_rotated_sorted_array/minimum.c @@ -0,0 +1,29 @@ +#include +#include +#include + +static int findMin(int* nums, int numsSize) +{ + int lo = 0; + int hi = numsSize - 1; + while (lo < hi) { + int mid = lo + (hi - lo) / 2; + if (nums[mid] < nums[hi]) { + hi = mid; + } else { + lo = mid + 1; + } + } + return nums[lo]; +} + +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", findMin(nums, count)); + return 0; +} diff --git a/0154_find_minimum_in_rotated_sorted_array_ii/Makefile b/0154_find_minimum_in_rotated_sorted_array_ii/Makefile new file mode 100644 index 0000000..5cd0451 --- /dev/null +++ b/0154_find_minimum_in_rotated_sorted_array_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test minimum.c diff --git a/0154_find_minimum_in_rotated_sorted_array_ii/minimum.c b/0154_find_minimum_in_rotated_sorted_array_ii/minimum.c new file mode 100644 index 0000000..6e11f26 --- /dev/null +++ b/0154_find_minimum_in_rotated_sorted_array_ii/minimum.c @@ -0,0 +1,32 @@ +#include +#include + +static int findMin(int* nums, int numsSize) +{ + 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[lo]; +} + +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", findMin(nums, count)); + return 0; +} diff --git a/0155_min_stack/Makefile b/0155_min_stack/Makefile new file mode 100644 index 0000000..5dd72fe --- /dev/null +++ b/0155_min_stack/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test stack.c diff --git a/0155_min_stack/stack.c b/0155_min_stack/stack.c new file mode 100644 index 0000000..d21ba29 --- /dev/null +++ b/0155_min_stack/stack.c @@ -0,0 +1,74 @@ +#include +#include + +typedef struct { + int num; + int min_idx; + int stack[]; +} MinStack; + +/** initialize your data structure here. */ +static MinStack* minStackCreate(const int maxSize) +{ + MinStack* obj = malloc(sizeof(MinStack) + sizeof(int) * maxSize); + obj->num = 0; + obj->min_idx = 0; + return obj; +} + +static void minStackPush(MinStack* const obj, const int x) +{ + if (obj->num > 0 && x < obj->stack[obj->min_idx]) { + obj->min_idx = obj->num; + } + obj->stack[obj->num++] = x; +} + +static void minStackPop(MinStack* const obj) +{ + int i; + /* We records min index but not min value to save unnecessary operation */ + if (--obj->num == obj->min_idx) { + int min_idx = 0; + for (i = 1; i < obj->num; i++) { + if (obj->stack[i] < obj->stack[min_idx]) { + min_idx = i; + } + } + obj->min_idx = min_idx; + } +} + +static int minStackTop(MinStack* const obj) +{ + return obj->stack[obj->num - 1]; +} + +static int minStackGetMin(MinStack* const obj) +{ + return obj->stack[obj->min_idx]; +} + +static void minStackFree(MinStack* const obj) +{ + free(obj); +} + +int main(void) +{ + MinStack *obj = minStackCreate(5); + minStackPush(obj, 2); + minStackPush(obj, 0); + minStackPush(obj, 3); + minStackPush(obj, 0); + printf("Min:%d\n", minStackGetMin(obj)); + minStackPop(obj); + //printf("Top:%d\n", minStackTop(obj)); + printf("Min:%d\n", minStackGetMin(obj)); + minStackPop(obj); + printf("Min:%d\n", minStackGetMin(obj)); + minStackPop(obj); + printf("Min:%d\n", minStackGetMin(obj)); + minStackFree(obj); + return 0; +} diff --git a/015_three_sum/Makefile b/015_three_sum/Makefile deleted file mode 100644 index 81b0519..0000000 --- a/015_three_sum/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test three_sum.c diff --git a/0160_intersection_of_two_linked_list/Makefile b/0160_intersection_of_two_linked_list/Makefile new file mode 100644 index 0000000..e3e5099 --- /dev/null +++ b/0160_intersection_of_two_linked_list/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test intersection.c diff --git a/0160_intersection_of_two_linked_list/intersection.c b/0160_intersection_of_two_linked_list/intersection.c new file mode 100644 index 0000000..def9953 --- /dev/null +++ b/0160_intersection_of_two_linked_list/intersection.c @@ -0,0 +1,57 @@ +#include +#include +#include + +struct ListNode { + int val; + struct ListNode *next; +}; + +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; + + 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 slow; + } + } + + p->next = NULL; + return NULL; +} + +int main(int argc, char **argv) +{ + struct ListNode *headA = malloc(sizeof(*headA)); + struct ListNode *headB = malloc(sizeof(*headB)); + struct ListNode *common = malloc(sizeof(*common)); + + headA->val = 1; + headB->val = 2; + common->val = 4; + headA->next = common; + headB->next = common; + common->next = NULL; + + struct ListNode *p = getIntersectionNode(headA, headB); + if (p != NULL) { + printf("%d\n", p->val); + } + return 0; +} 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/0162_find_peak_element/Makefile b/0162_find_peak_element/Makefile new file mode 100644 index 0000000..2e3077e --- /dev/null +++ b/0162_find_peak_element/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test peak.c diff --git a/0162_find_peak_element/peak.c b/0162_find_peak_element/peak.c new file mode 100644 index 0000000..c936ae5 --- /dev/null +++ b/0162_find_peak_element/peak.c @@ -0,0 +1,25 @@ +#include +#include + + +int findPeakElement(int* nums, int numsSize) +{ + int i; + for (i = 1; i < numsSize; i++) { + if (nums[i] < nums[i - 1]) { + break; + } + } + return i - 1; +} + +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", findPeakElement(nums, count)); + return 0; +} 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/0164_maximum_gap/Makefile b/0164_maximum_gap/Makefile new file mode 100644 index 0000000..62fb524 --- /dev/null +++ b/0164_maximum_gap/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test max_gap.c diff --git a/0164_maximum_gap/max_gap.c b/0164_maximum_gap/max_gap.c new file mode 100644 index 0000000..4303a31 --- /dev/null +++ b/0164_maximum_gap/max_gap.c @@ -0,0 +1,77 @@ +#include +#include +#include + +static inline int gt(int a, int b) +{ + return a > b ? a : b; +} + +static inline int lt(int a, int b) +{ + return a < b ? a : b; +} + +static int maximumGap(int* nums, int numsSize) +{ + if (numsSize < 2) { + return 0; + } + + int i; + int min = INT_MAX; + int max = INT_MIN; + for (i = 0; i < numsSize; i++) { + min = lt(nums[i], min); + max = gt(nums[i], max); + } + + /* the max gap size must be larger than or equal to the average */ + double buck_size = 1.0 * (max - min) / (numsSize - 1); + /* In case of all elememnts are the same number */ + if (buck_size == 0) { + return 0; + } + + int buck_cnt = (max - min) / buck_size + 1; + int *max_buck = malloc(buck_cnt * sizeof(int)); + int *min_buck = malloc(buck_cnt * sizeof(int)); + for (i = 0; i < buck_cnt; i++) { + max_buck[i] = INT_MIN; + min_buck[i] = INT_MAX; + } + + for (i = 0; i < numsSize; i++) { + int id = (nums[i] - min) / buck_size; + max_buck[id] = gt(nums[i], max_buck[id]); + min_buck[id] = lt(nums[i], min_buck[id]); + } + + int max_gap = 0; + /* Must not be empty */ + int last_max = max_buck[0]; + for (i = 1; i < buck_cnt; i++) { + if (min_buck[i] != INT_MAX) { + /* What we care about is the difference between the last element + * in the last max bucket and the first element in the next min + * bucket since the max gap must be larger or equal than the average + * while the differences of elements in one bucket must less than + * the average */ + max_gap = gt(min_buck[i] - last_max, max_gap); + last_max = max_buck[i]; + } + } + + return max_gap; +} + +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", maximumGap(nums, count)); + return 0; +} 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/0165_compare_version_numbers/Makefile b/0165_compare_version_numbers/Makefile new file mode 100644 index 0000000..faf78bf --- /dev/null +++ b/0165_compare_version_numbers/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test version.c diff --git a/0165_compare_version_numbers/version.c b/0165_compare_version_numbers/version.c new file mode 100644 index 0000000..803fe8a --- /dev/null +++ b/0165_compare_version_numbers/version.c @@ -0,0 +1,50 @@ +#include +#include + +static int compareVersioin(char *v1, char *v2) +{ + int ret = 0; + while (*v1 != '\0' || *v2 != '\0') { + while (*v1 != '\0' && *v1 == '0') { + v1++; + } + while (*v2 != '\0' && *v2 == '0') { + v2++; + } + + int n1 = 0; + while (*v1 != '\0' && *v1 != '.') { + n1 = n1 * 10 + (*v1 - '0'); + v1++; + } + + int n2 = 0; + while (*v2 != '\0' && *v2 != '.') { + n2 = n2 * 10 + (*v2 - '0'); + v2++; + } + + ret = n1 - n2; + if (ret != 0) { + return ret > 0 ? 1 : -1; + } + + if (*v1 == '.') { + v1++; + } + if (*v2 == '.') { + v2++; + } + } + return ret; +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./test versioin1 version2\n"); + exit(-1); + } + printf("%d\n", compareVersioin(argv[1], argv[2])); + return 0; +} diff --git a/0166_fraction_to_recurring_decimal/Makefile b/0166_fraction_to_recurring_decimal/Makefile new file mode 100644 index 0000000..432c76c --- /dev/null +++ b/0166_fraction_to_recurring_decimal/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test fraction.c diff --git a/0166_fraction_to_recurring_decimal/fraction.c b/0166_fraction_to_recurring_decimal/fraction.c new file mode 100644 index 0000000..f1c90ff --- /dev/null +++ b/0166_fraction_to_recurring_decimal/fraction.c @@ -0,0 +1,185 @@ +#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_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 rem_node { + int key; + int index; + 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 int find(struct list_head *heads, int size, int key) +{ + struct rem_node *node; + int hash = key % size; + list_for_each_entry(node, &heads[hash], link) { + if (key == node->key) { + return node->index; + } + } + return -1; +} + +char* fractionToDecimal(int numerator, int denominator) +{ + int size = 1024; + char *result = malloc(size); + char *p = result; + + if (denominator == 0) { + result[0] = '\0'; + return result; + } + + if (numerator == 0) { + result[0] = '0'; + result[1] = '\0'; + return result; + } + + /* using long long type make sure there has no integer overflow */ + long long n = numerator; + long long d = denominator; + + /* deal with negtive cases */ + if (n < 0) { + n = -n; + } + if (d < 0) { + d = -d; + } + + bool sign = (float) numerator / denominator >= 0; + if (!sign){ + *p++ = '-'; + } + + long long remainder = n % d; + long long division = n / d; + + sprintf(p, "%ld", division > 0 ? (long) division : (long) -division); + if (remainder == 0) { + return result; + } + + p = result + strlen(result); + *p++ = '.'; + + /* Using a map to record all of reminders and their position. + * if the reminder appeared before, which means the repeated loop begin, + */ + + int i, j; + char *decimal = malloc(size); + memset(decimal, 0, size); + char *q = decimal; + + size = 1333; + struct list_head *heads = malloc(size * sizeof(*heads)); + for (i = 0; i < size; i++) { + INIT_LIST_HEAD(&heads[i]); + } + + i = 0; + while (remainder != 0) { + int pos = find(heads, size, remainder); + if (pos >= 0) { + while (pos-- > 0) { + *p++ = *decimal++; + } + *p++ = '('; + while (*decimal != '\0') { + *p++ = *decimal++; + } + *p++ = ')'; + *p = '\0'; + return result; + } + struct rem_node *node = malloc(sizeof(*node)); + node->key = remainder; + node->index = i; + + int hash = remainder % size; + list_add(&node->link, &heads[hash]); + + *q++ = (remainder * 10) / d + '0'; + remainder = (remainder * 10) % d; + i++; + } + + strcpy(p, decimal); + return result; +} + +int main(int argc, char** argv) +{ +#if 1 + if (argc != 3) { + fprintf(stderr, "Usage: ./test numerator denominator\n"); + exit(-1); + } + + printf("%s\n", fractionToDecimal(atoi(argv[1]), atoi(argv[2]))); +#else + printf("%s\n", fractionToDecimal(1, 6)); + printf("%s\n", fractionToDecimal(100, 6)); + printf("%s\n", fractionToDecimal(-1, 4)); + printf("%s\n", fractionToDecimal(1, -3)); + printf("%s\n", fractionToDecimal(-1, -6)); + printf("%s\n", fractionToDecimal(25, 99)); + printf("%s\n", fractionToDecimal(1, 7)); + printf("%s\n", fractionToDecimal(10, 7)); + printf("%s\n", fractionToDecimal(100, 7)); + printf("%s\n", fractionToDecimal(1, 17)); + printf("%s\n", fractionToDecimal(1, 1024)); + printf("%s\n", fractionToDecimal(-2147483648, -1999)); + printf("%s\n", fractionToDecimal(-1, -2147483648)); + +#endif + return 0; +} diff --git a/0167_two_sum_ii/Makefile b/0167_two_sum_ii/Makefile new file mode 100644 index 0000000..e896cb5 --- /dev/null +++ b/0167_two_sum_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test two_sum.c diff --git a/0167_two_sum_ii/two_sum.c b/0167_two_sum_ii/two_sum.c new file mode 100644 index 0000000..7478668 --- /dev/null +++ b/0167_two_sum_ii/two_sum.c @@ -0,0 +1,50 @@ +#include +#include + +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +static int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) +{ + int i = 0, j = numbersSize - 1; + while (i < j) { + int sum = numbers[i] + numbers[j]; + if (sum < target) { + i++; + } else if (sum > target) { + j--; + } else { + *returnSize = 2; + int *indexes = malloc(2 * sizeof(int)); + indexes[0] = i + 1; + indexes[1] = j + 1; + return indexes; + } + } + + *returnSize = 0; + return NULL; +} + +int main(int argc, char **argv) +{ + if (argc < 3) { + fprintf(stderr, "Usage: ./test target n1 n2..."); + exit(-1); + } + + int i, count = argc - 2; + int target = atoi(argv[1]); + int *nums = malloc(count * sizeof(int)); + for (i = 0; i < count; i++) { + nums[i] = atoi(argv[i + 2]); + } + + int number = 0; + int *indexes = twoSum(nums, count, target, &number); + if (indexes != NULL) { + printf("%d %d\n", indexes[0], indexes[1]); + } + return 0; +} 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/0168_excel_sheet_column_title/Makefile b/0168_excel_sheet_column_title/Makefile new file mode 100644 index 0000000..7a8047f --- /dev/null +++ b/0168_excel_sheet_column_title/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test sheet_column.c diff --git a/0168_excel_sheet_column_title/sheet_column.c b/0168_excel_sheet_column_title/sheet_column.c new file mode 100644 index 0000000..bc05ef8 --- /dev/null +++ b/0168_excel_sheet_column_title/sheet_column.c @@ -0,0 +1,36 @@ +#include +#include + +static char *convertToTitle(int n) +{ + if (n <= 0) { + return ""; + } + + char *result = malloc(1024); + int len = 0; + do { + result[len++] = ((n - 1) % 26) + 'A'; + n = (n - 1) / 26; + } while (n > 0); + result[len] = '\0'; + + int i, j; + for (i = 0, j = len - 1; i < j; i++, j--) { + char c = result[i]; + result[i] = result[j]; + result[j] = c; + } + return result; +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test n\n"); + exit(-1); + } + + printf("%s\n", convertToTitle(atoi(argv[1]))); + return 0; +} diff --git a/0169_majority_element/Makefile b/0169_majority_element/Makefile new file mode 100644 index 0000000..84ca762 --- /dev/null +++ b/0169_majority_element/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test majority.c diff --git a/0169_majority_element/majority.c b/0169_majority_element/majority.c new file mode 100644 index 0000000..95b5014 --- /dev/null +++ b/0169_majority_element/majority.c @@ -0,0 +1,35 @@ +#include +#include + +static int majorityElement(int* nums, int numsSize) +{ + int i, major, count = 0; + for (i = 0; i < numsSize; i++) { + if (count == 0) { + major = nums[i]; + count++; + } else if (major == nums[i]) { + count++; + } else { + count--; + } + } + return major; +} + +int main(int argc, char **argv) +{ + if (argc < 2) { + fprintf(stderr, "Usage: ./test target n1 n2...\n"); + exit(-1); + } + + 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", majorityElement(nums, count)); + return 0; +} 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/016_three_sum_closest/Makefile b/016_three_sum_closest/Makefile deleted file mode 100644 index 4e07f03..0000000 --- a/016_three_sum_closest/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test three_sum_closest.c -lm diff --git a/0171_excel_sheet_column_number/Makefile b/0171_excel_sheet_column_number/Makefile new file mode 100644 index 0000000..7a8047f --- /dev/null +++ b/0171_excel_sheet_column_number/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test sheet_column.c diff --git a/0171_excel_sheet_column_number/sheet_column.c b/0171_excel_sheet_column_number/sheet_column.c new file mode 100644 index 0000000..2df5623 --- /dev/null +++ b/0171_excel_sheet_column_number/sheet_column.c @@ -0,0 +1,24 @@ +#include +#include + +static int titleToNumber(char *s) +{ + int n = 0; + while (*s != '\0') { + n *= 26; + n += *s++ - 'A' + 1; + } + + return n; +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test ABC\n"); + exit(-1); + } + + printf("%d\n", titleToNumber(argv[1])); + return 0; +} diff --git a/0172_factorial_trailing_zeros/Makefile b/0172_factorial_trailing_zeros/Makefile new file mode 100644 index 0000000..54e68c3 --- /dev/null +++ b/0172_factorial_trailing_zeros/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test zeroes.c diff --git a/0172_factorial_trailing_zeros/zeroes.c b/0172_factorial_trailing_zeros/zeroes.c new file mode 100644 index 0000000..94b7f6b --- /dev/null +++ b/0172_factorial_trailing_zeros/zeroes.c @@ -0,0 +1,19 @@ +#include +#include + +static int trailingZeroes(int n) +{ + /* As 10 = 2 * 5 so we just count how many fives in it */ + return n == 0 ? 0 : n / 5 + trailingZeroes(n / 5); +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test n\n"); + exit(-1); + } + + printf("%d\n", trailingZeroes(atoi(argv[1]))); + return 0; +} 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/0173_binary_search_tree_iterator/Makefile b/0173_binary_search_tree_iterator/Makefile new file mode 100644 index 0000000..96cca66 --- /dev/null +++ b/0173_binary_search_tree_iterator/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test bst_iter.c diff --git a/0173_binary_search_tree_iterator/bst_iter.c b/0173_binary_search_tree_iterator/bst_iter.c new file mode 100644 index 0000000..2dead2f --- /dev/null +++ b/0173_binary_search_tree_iterator/bst_iter.c @@ -0,0 +1,112 @@ +#include +#include +#include + +struct TreeNode { + int val; + struct TreeNode *left; + struct TreeNode *right; +}; + +typedef struct { + int size; + int index; + int nums[10000]; +} BSTIterator; + +static void dfs(struct TreeNode* root, BSTIterator *obj) +{ + if (root == NULL) { + return; + } + + dfs(root->left, obj); + obj->nums[obj->size++] = root->val; + dfs(root->right, obj); +} + +static struct BSTIterator *bstIteratorCreate(struct TreeNode *root) +{ + struct BSTIterator *obj = malloc(sizeof(*obj)); + obj->index = 0; + obj->size = 0; + dfs(root, obj); + return iter; +} + +/** @return whether we have a next smallest number */ +static bool bstIteratorHasNext(struct BSTIterator *obj) +{ + return obj->index < obj->size; +} + +/** @return the next smallest number */ +static int bstIteratorNext(struct BSTIterator *obj) +{ + return obj->nums[obj->index++]; +} + +/** Deallocates memory iteriously allocated for the iterator */ +static void bstIteratorFree(struct BSTIterator *obj) +{ + free(obj); +} + +int main(void) +{ +#if 1 + struct TreeNode root; + root.val = 7; + + struct TreeNode node1[2]; + node1[0].val = 3; + node1[1].val = 15; + + struct TreeNode node2[4]; + node2[2].val = 9; + node2[3].val = 20; + + 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]; +#else + struct TreeNode root; + root.val = 1; + + struct TreeNode node1[2]; + node1[0].val = 2; + node1[1].val = 3; + + struct TreeNode node2[4]; + node2[0].val = 4; + node2[3].val = 5; + + root.left = &node1[0]; + root.right = &node1[1]; + + node1[0].left = &node2[0]; + node1[0].right = NULL; + node1[1].left = NULL; + node1[1].right = &node2[3]; +#endif + + 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; + + struct BSTIterator *i = bstIteratorCreate(&root); + while (bstIteratorHasNext(i)) { + printf("%d\n", bstIteratorNext(i)); + } + bstIteratorFree(i); + return 0; +} diff --git a/0174_dungeon_game/Makefile b/0174_dungeon_game/Makefile new file mode 100644 index 0000000..81bc0ed --- /dev/null +++ b/0174_dungeon_game/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test dungeon.c diff --git a/0174_dungeon_game/dungeon.c b/0174_dungeon_game/dungeon.c new file mode 100644 index 0000000..c1ab8a5 --- /dev/null +++ b/0174_dungeon_game/dungeon.c @@ -0,0 +1,72 @@ +#include +#include + +static int calculateMinimumHP(int** dungeon, int dungeonRowSize, int dungeonColSize) +{ + int i, j; + int **dp = malloc(dungeonRowSize * sizeof(int *)); + for (i = 0; i < dungeonRowSize; i++) { + dp[i] = malloc(dungeonColSize * sizeof(int)); + } + + int hp = 1 - dungeon[dungeonRowSize - 1][dungeonColSize - 1]; + dp[dungeonRowSize - 1][dungeonColSize - 1] = hp >= 1 ? hp : 1; + for (i = dungeonRowSize - 2; i >= 0; i--) { + hp = dp[i + 1][dungeonColSize - 1] - dungeon[i][dungeonColSize - 1]; + dp[i][dungeonColSize - 1] = hp >= 1 ? hp : 1; + } + + for (i = dungeonColSize - 2; i >= 0; i--) { + hp = dp[dungeonRowSize - 1][i + 1] - dungeon[dungeonRowSize - 1][i]; + dp[dungeonRowSize - 1][i] = hp >= 1 ? hp : 1; + } + + for (i = dungeonRowSize - 2; i >= 0; i--) { + for (j = dungeonColSize - 2; j >= 0; j--) { + int hp_r = dp[i][j + 1] - dungeon[i][j]; + int hp_d = dp[i + 1][j] - dungeon[i][j]; + hp_r = hp_r >= 1 ? hp_r : 1; + hp_d = hp_d >= 1 ? hp_d : 1; + dp[i][j] = hp_r < hp_d ? hp_r : hp_d; + } + } + + return dp[0][0]; +} + +int main(void) +{ + int row_size = 3, col_size = 3; + int i, j, **dungeon = malloc(row_size * sizeof(int *)); + for (i = 0; i < row_size; i++) { + dungeon[i] = malloc(col_size * sizeof(int)); + } +#if 1 + dungeon[0][0] = 1; + dungeon[0][1] = -3; + dungeon[0][2] = 3; + dungeon[1][0] = 0; + dungeon[1][1] = -2; + dungeon[1][2] = 0; + dungeon[2][0] = -3; + dungeon[2][1] = -3; + dungeon[2][2] = -3; +#else + dungeon[0][0] = 3; + dungeon[0][1] = -20; + dungeon[0][2] = 30; + dungeon[1][0] = -3; + dungeon[1][1] = 4; + dungeon[1][2] = 0; +#endif + + printf("dungeon:\n"); + for (i = 0; i < row_size; i++) { + for (j = 0; j < col_size; j++) { + printf("%d ", dungeon[i][j]); + } + printf("\n"); + } + printf("%d\n", calculateMinimumHP(dungeon, row_size, col_size)); + return 0; +} diff --git a/0179_largest_number/Makefile b/0179_largest_number/Makefile new file mode 100644 index 0000000..0d8eafc --- /dev/null +++ b/0179_largest_number/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test largest_number.c diff --git a/0179_largest_number/largest_number.c b/0179_largest_number/largest_number.c new file mode 100644 index 0000000..3dba0a8 --- /dev/null +++ b/0179_largest_number/largest_number.c @@ -0,0 +1,52 @@ +#include +#include +#include + +struct object { + char buf[16]; +}; + +static int compare(const void *o1, const void *o2) +{ + 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); + strcat(p2, ((struct object *) o1)->buf); + return strcmp(p1, p2); +} + +static char* largestNumber(int* nums, int numsSize) +{ + int i; + struct object *objs = malloc(numsSize * sizeof(*objs)); + memset(objs, 0, sizeof(*objs)); + for (i = 0; i < numsSize; i++) { + sprintf(objs[i].buf, "%d", nums[i]); + } + + qsort(objs, numsSize, sizeof(*objs), compare); + if (objs[numsSize - 1].buf[0] == '0') { + return "0"; + } + + char *result = malloc(numsSize * 16); + result[0] = '\0'; + for (i = numsSize - 1; i >= 0; i--) { + strcat(result, objs[i].buf); + } + + return result; +} + +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("%s\n", largestNumber(nums, count)); + return 0; +} 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/017_letter_combinations_of_a_phone_number/Makefile b/017_letter_combinations_of_a_phone_number/Makefile deleted file mode 100644 index 4016483..0000000 --- a/017_letter_combinations_of_a_phone_number/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o letter_combinations letter_combinations.c diff --git a/0188_best_time_to_buy_and_sell_stock_iv/Makefile b/0188_best_time_to_buy_and_sell_stock_iv/Makefile new file mode 100644 index 0000000..5d7d4bd --- /dev/null +++ b/0188_best_time_to_buy_and_sell_stock_iv/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test stock.c diff --git a/0188_best_time_to_buy_and_sell_stock_iv/stock.c b/0188_best_time_to_buy_and_sell_stock_iv/stock.c new file mode 100644 index 0000000..625ce78 --- /dev/null +++ b/0188_best_time_to_buy_and_sell_stock_iv/stock.c @@ -0,0 +1,103 @@ +#include +#include +#include + +static inline int max(int a, int b) +{ + return a > b ? a : b; +} + +static int maxProfit(int k, int* prices, int pricesSize) +{ + if (pricesSize == 0) { + return 0; + } + + int i, j; + if (k > pricesSize / 2) { + /* We can make transactions as many as we can */ + int total = 0; + for (i = 1; i < pricesSize; i++) { + if (prices[i] > prices[i - 1]) { + total += prices[i] - prices[i - 1]; + } + } + return total; + } else { +#if 1 + /* DP solution - O(kn) complexity + * dp[i, j] = max (dp[i, j-1], // same times transactions, but one days before. + * dp[i-1, t] + prices[j] - prices[t+1]) // for all of (0 <= t < j ) + * // this means find max profit from previous any of days + */ + int **dp = malloc((k + 1) * sizeof(int *)); + for (i = 0; i <= k; i++) { + dp[i] = malloc((pricesSize + 1) * sizeof(int)); + memset(dp[i], 0, (pricesSize + 1) * sizeof(int)); + } + + for (i = 1; i <= k; i++) { +//printf("i:%d\n", i); +//printf("\tprev_profit = %d - %d\n", dp[i - 1][0], prices[0]); + int prev_profit = dp[i - 1][0] - prices[0]; + for (j = 1; j <= pricesSize; j++) { +//printf("\tj:%d\n", j); + dp[i][j] = max(dp[i][j - 1], prev_profit + prices[j - 1]); /* prices[j - 1] means sell on Day j for dp[i][j] */ +//printf("\tdp[%d][%d] = max(%d, %d + %d)\n", i, j, dp[i][j - 1], prev_profit, prices[j - 1]); + if (j < pricesSize) { +//printf("\tprev_profit = max(%d, %d - %d)\n", prev_profit, dp[i - 1][j], prices[j]); + prev_profit = max(prev_profit, dp[i - 1][j] - prices[j]); + } + } + } +#if 0 + printf(" "); + for (i = 0; i < pricesSize; i++) { + printf("%d ", prices[i]); + } + printf("\n"); + for (i = 0; i <= k; i++) { + for (j = 0; j <= pricesSize; j++) { + printf("%d ", dp[i][j]); + } + printf("\n"); + } +#endif + + return dp[k][pricesSize]; +#else + /* local[i][j] j transactions at most and the last max profix until Day i */ + int *local = malloc((k + 1) * sizeof(int)); + /* global[i][j] j transactions at most until Day i */ + int *global = malloc((k + 1) * sizeof(int)); + memset(local, 0, (k + 1) * sizeof(int)); + memset(global, 0, (k + 1) * sizeof(int)); + for (i = 0; i < pricesSize - 1; i++) { + int diff = prices[i + 1] - prices[i]; + for (j = k; j >= 1; j--) { + int tmp1 = global[j - 1] + (diff > 0 ? diff : 0); + int tmp2 = local[j] + diff; + local[j] = tmp1 > tmp2 ? tmp1 : tmp2; + global[j] = global[j] > local[j] ? global[j] : local[j]; + } + } + return global[k]; +#endif + } +} + +int main(int argc, char **argv) +{ + if (argc < 2) { + 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", maxProfit(atoi(argv[1]), nums, count)); + return 0; +} diff --git a/0189_rotate_array/Makefile b/0189_rotate_array/Makefile new file mode 100644 index 0000000..adec477 --- /dev/null +++ b/0189_rotate_array/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test rotate_array.c diff --git a/0189_rotate_array/rotate_array.c b/0189_rotate_array/rotate_array.c new file mode 100644 index 0000000..354763c --- /dev/null +++ b/0189_rotate_array/rotate_array.c @@ -0,0 +1,49 @@ +#include +#include + +static void reverse(int *nums, int lo, int hi) +{ + while (lo < hi) { + int tmp = nums[lo]; + nums[lo] = nums[hi]; + nums[hi] = tmp; + lo++; + hi--; + } +} + +static void rotate(int* nums, int numsSize, int k) +{ + k %= numsSize; + if (k == 0) { + return; + } + + reverse(nums, 0, numsSize - 1 - k); + reverse(nums, numsSize - k, numsSize - 1); + reverse(nums, 0, numsSize - 1); +} + +int main(int argc, char **argv) +{ + if (argc < 2) { + fprintf(stderr, "Usage: ./test k n1 n2...\n"); + exit(-1); + } + + int k = atoi(argv[1]); + int i, count = argc - 2; + int *nums = malloc(count * sizeof(int)); + for (i = 0; i < count; i++) { + nums[i] = atoi(argv[i + 2]); + } + + rotate(nums, count, k); + + for (i = 0; i < count; i++) { + printf("%d ", nums[i]); + } + printf("\n"); + + return 0; +} 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/018_four_sum/Makefile b/018_four_sum/Makefile deleted file mode 100644 index f1a42a7..0000000 --- a/018_four_sum/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test four_sum.c diff --git a/018_four_sum/four_sum.c b/018_four_sum/four_sum.c deleted file mode 100644 index ec72733..0000000 --- a/018_four_sum/four_sum.c +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#include - -static void insert_sort(int *nums, int len) -{ - int i, j; - for (i = 1; i < len; i++) { - int tmp = nums[i]; - for (j = i - 1; j >= 0 && nums[j] > tmp; j--) { - nums[j + 1] = nums[j]; - } - nums[j + 1] = tmp; - } -} - -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 i; - if (k == 2) { - while (low < high) { - int diff = target - nums[low]; - if (diff > nums[high]) { - while (++low < high && nums[low] == nums[low - 1]) {} - } else if (diff < nums[high]) { - while (--high > low && nums[high] == nums[high + 1]) {} - } else { - stack[len++] = nums[low]; - stack[len++] = nums[high]; - results[*count] = malloc(total * sizeof(int)); - memcpy(results[*count], stack, total * sizeof(int)); - (*count)++; - len -= 2; - while (++low < high && nums[low] == nums[low - 1]) {} - while (--high > low && nums[high] == nums[high + 1]) {} - } - } - } else { - /* 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); - len--; - } - } -} - -/** - ** Return an array of arrays of size *returnSize. - ** Note: The returned array must be malloced, assume caller calls free(). - **/ -static int** fourSum(int* nums, int numsSize, int target, int* returnSize) { - if (numsSize < 4) { - return NULL; - } - insert_sort(nums, numsSize); - int i, j, count = 0, capacity = 50000; - int **results = malloc(capacity * sizeof(int *)); - int *stack = malloc(4 * sizeof(int)); - k_sum(nums, 0, numsSize - 1, target, 4, 4, stack, 0, results, &count); - *returnSize = count; - return results; -} - -int main(void) -{ - int i, count; - //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); - for (i = 0; i < count; i++) { - printf("%d %d %d %d\n", quadruplets[i][0], quadruplets[i][1], quadruplets[i][2], quadruplets[i][3]); - } - - return 0; -} diff --git a/0190_reverse_bits/Makefile b/0190_reverse_bits/Makefile new file mode 100644 index 0000000..ef041ad --- /dev/null +++ b/0190_reverse_bits/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test reverse_bits.c 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/0191_number_of_one_bits/Makefile b/0191_number_of_one_bits/Makefile new file mode 100644 index 0000000..fd6ea08 --- /dev/null +++ b/0191_number_of_one_bits/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test hamming_weight.c diff --git a/0191_number_of_one_bits/hamming_weight.c b/0191_number_of_one_bits/hamming_weight.c new file mode 100644 index 0000000..ec9a517 --- /dev/null +++ b/0191_number_of_one_bits/hamming_weight.c @@ -0,0 +1,24 @@ +#include +#include +#include + +static int hammingWeight(uint32_t n) +{ + int count = 0; + while (n > 0) { + n = n & (n - 1); + count++; + } + return count; +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test n\n"); + exit(-1); + } + + printf("%d\n", hammingWeight(atoi(argv[1]))); + return 0; +} diff --git a/0198_house_robber/Makefile b/0198_house_robber/Makefile new file mode 100644 index 0000000..16f41d2 --- /dev/null +++ b/0198_house_robber/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test robber.c diff --git a/0198_house_robber/robber.c b/0198_house_robber/robber.c new file mode 100644 index 0000000..82fa8ad --- /dev/null +++ b/0198_house_robber/robber.c @@ -0,0 +1,37 @@ +#include +#include +#include + +static inline int max(int a, int b) +{ + return a > b ? a : b; +} + +static int rob(int* nums, int numsSize) +{ + int i; + int taken = 0; + int untaken = 0; + /* Record max profits of nums[0...i] respectively */ + for (i = 0; i < numsSize; i++) { + int last_taken = taken; + /* Taken or untaken nums[i] */ + /* last taken + nums[i] */ + taken = untaken + nums[i]; + /* max(last untaken, last taken) */ + untaken = max(last_taken, untaken); + } + + return max(taken, untaken); +} + +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", rob(nums, count)); + return 0; +} 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/0199_binary_tree_right_side_view/Makefile b/0199_binary_tree_right_side_view/Makefile new file mode 100644 index 0000000..316f349 --- /dev/null +++ b/0199_binary_tree_right_side_view/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test bst_right.c diff --git a/0199_binary_tree_right_side_view/bst_right.c b/0199_binary_tree_right_side_view/bst_right.c new file mode 100644 index 0000000..2be03cd --- /dev/null +++ b/0199_binary_tree_right_side_view/bst_right.c @@ -0,0 +1,178 @@ +#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) +{ + /* Reusage in free node pool */ + 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); +} + +/** + ** The returned array must be malloced, assume caller calls free(). + **/ +static int* rightSideView(struct TreeNode* root, int* returnSize) +{ + if (root == NULL) { + *returnSize = 0; + return NULL; + } + + struct list_head q; + struct list_head free_list; + INIT_LIST_HEAD(&q); + INIT_LIST_HEAD(&free_list); + + int i, level = 0, level_size = 1; + *returnSize = 0; + int *results = malloc(BST_MAX_LEVEL * sizeof(int)); + + /* 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; +} + +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 = NULL;//&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, count = 0; + int *lists = rightSideView(&root, &count); + for (i = 0; i < count; i++) { + printf("%d ", lists[i]); + } + printf("\n"); + + return 0; +} 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/019_remove_nth_node_from_end_of_list/Makefile b/019_remove_nth_node_from_end_of_list/Makefile deleted file mode 100644 index 41a447c..0000000 --- a/019_remove_nth_node_from_end_of_list/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test remove_end.c diff --git a/0200_number_of_islands/Makefile b/0200_number_of_islands/Makefile new file mode 100644 index 0000000..aa9ae7a --- /dev/null +++ b/0200_number_of_islands/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test islands.c diff --git a/0200_number_of_islands/islands.c b/0200_number_of_islands/islands.c new file mode 100644 index 0000000..7ab40ad --- /dev/null +++ b/0200_number_of_islands/islands.c @@ -0,0 +1,59 @@ +#include +#include +#include + +static void dfs(char** grid, int row_size, int col_size, int row, int col) +{ + grid[row][col] = '0'; + + if (row > 0 && grid[row - 1][col] == '1') { + dfs(grid, row_size, col_size, row - 1, col); + } + + if (row < row_size - 1 && grid[row + 1][col] == '1') { + dfs(grid, row_size, col_size, row + 1, col); + } + + if (col > 0 && grid[row][col - 1] == '1') { + dfs(grid, row_size, col_size, row, col - 1); + } + + if (col < col_size - 1 && grid[row][col + 1] == '1') { + dfs(grid, row_size, col_size, row, col + 1); + } +} + +static int numIslands(char** grid, int gridRowSize, int gridColSize) +{ + int i, j, count = 0; + for (i = 0; i < gridRowSize; i++) { + for (j = 0; j < gridColSize; j++) { + if (grid[i][j] == '1') { + dfs(grid, gridRowSize, gridColSize, i, j); + count++; + } + } + } + + return count; +} + +int main(int argc, char **argv) +{ + if (argc < 2) { + fprintf(stderr, "Usage: ./test 11000 11000 00100 00011\n"); + exit(-1); + } + + int i, j; + int row_size = argc - 1; + int col_size = strlen(argv[1]); + char **grid = malloc(row_size * sizeof(char *)); + for (i = 0; i < row_size; i++) { + grid[i] = malloc(col_size); + memcpy(grid[i], argv[i + 1], col_size); + } + + printf("%d\n", numIslands(grid, row_size, col_size)); + return 0; +} diff --git a/0201_bitwise_and_of_numbers_range/Makefile b/0201_bitwise_and_of_numbers_range/Makefile new file mode 100644 index 0000000..7f8c06c --- /dev/null +++ b/0201_bitwise_and_of_numbers_range/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test and.c diff --git a/0201_bitwise_and_of_numbers_range/and.c b/0201_bitwise_and_of_numbers_range/and.c new file mode 100644 index 0000000..4cf2a8c --- /dev/null +++ b/0201_bitwise_and_of_numbers_range/and.c @@ -0,0 +1,28 @@ +#include +#include + +static int rangeBitwiseAnd(int m, int n) +{ + int i, res = 0; + for (i = 0; m > 0 && n > 0; i++) { + if (m == n && (m & 1)) { + res |= 1 << i; + } + + m = m >> 1; + n = n >> 1; + } + + return res; +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./test m n\n"); + exit(-1); + } + + printf("%d\n", rangeBitwiseAnd(atoi(argv[1]), atoi(argv[2]))); + return 0; +} diff --git a/0202_happy_number/Makefile b/0202_happy_number/Makefile new file mode 100644 index 0000000..c4394cc --- /dev/null +++ b/0202_happy_number/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test happy_number.c diff --git a/0202_happy_number/happy_number.c b/0202_happy_number/happy_number.c new file mode 100644 index 0000000..9e4d9e8 --- /dev/null +++ b/0202_happy_number/happy_number.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include + +static bool recursive(int n, bool *used, const int *sq) +{ + if (n == 1) return true; + if (n < 10000) { + if (used[n]) return false; + used[n] = true; + } + int sum = 0; + while (n > 0) { + sum += sq[n % 10]; + n /= 10; + } + return recursive(sum, used, sq); +} + +static bool isHappy(int n) +{ + bool used[10000] = { false }; + const static int sq[10] = { 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 }; + return recursive(n, used, sq); +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test n\n"); + exit(-1); + } + + printf("%s\n", isHappy(atoi(argv[1])) ? "true" : "false"); + return 0; +} diff --git a/0203_remove_linked_list_element/Makefile b/0203_remove_linked_list_element/Makefile new file mode 100644 index 0000000..8c8bea3 --- /dev/null +++ b/0203_remove_linked_list_element/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test rm_elem.c diff --git a/0203_remove_linked_list_element/rm_elem.c b/0203_remove_linked_list_element/rm_elem.c new file mode 100644 index 0000000..0834a82 --- /dev/null +++ b/0203_remove_linked_list_element/rm_elem.c @@ -0,0 +1,53 @@ +#include +#include + +struct ListNode { + int val; + struct ListNode *next; +}; + +static struct ListNode *removeElement(struct ListNode *head, int val) +{ + struct ListNode dummy; + dummy.next = head; + struct ListNode *prev = &dummy; + struct ListNode *p = head; + while (p != NULL) { + if (p->val == val) { + prev->next = p->next; + } else { + prev = p; + } + p = p->next; + } + return dummy.next; +} + +int main(int argc, char **argv) +{ + if (argc < 3) { + fprintf(stderr, "Usage: ./test value n1 n2 n3...\n"); + exit(-1); + } + + int value = atoi(argv[1]); + int i, count = argc - 2; + struct ListNode *head = NULL, *p, *prev; + for (i = 0; i < count; i++) { + p = malloc(sizeof(*p)); + p->val = atoi(argv[i + 2]); + p->next = NULL; + if (head == NULL) { + head = p; + } else { + prev->next = p; + } + prev = p; + } + + for (p = removeElement(head, value); p != NULL; p = p->next) { + printf("%d ", p->val); + } + printf("\n"); + return 0; +} diff --git a/0204_count_primes/Makefile b/0204_count_primes/Makefile new file mode 100644 index 0000000..db7f392 --- /dev/null +++ b/0204_count_primes/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test count_primes.c diff --git a/0204_count_primes/count_primes.c b/0204_count_primes/count_primes.c new file mode 100644 index 0000000..69b4bef --- /dev/null +++ b/0204_count_primes/count_primes.c @@ -0,0 +1,39 @@ +#include +#include +#include + + +int countPrimes(int n) +{ + if (n < 3) { + return 0; + } + + int i, j; + bool *marked = malloc(n); + memset(marked, false, n); + int count = n >> 1; + + for (i = 3; i * i <= n; i += 2) { + if (!marked[i]) { + for (j = i * i; j < n; j += (i << 1)) { + if (!marked[j]) { + marked[j] = true; + --count; + } + } + } + } + return count; +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test n\n"); + exit(-1); + } + + printf("%d\n", countPrimes(atoi(argv[1]))); + return 0; +} diff --git a/0204_count_primes/count_primes.cc b/0204_count_primes/count_primes.cc new file mode 100644 index 0000000..20b752c --- /dev/null +++ b/0204_count_primes/count_primes.cc @@ -0,0 +1,26 @@ +#include + +using namespace std; + +class Solution { +public: + int countPrimes(int n) { + if (n < 3) { + return 0; + } + + vector marked(n); + int count = n >> 1; + for (int i = 3; i * i <= n; i += 2) { + if (!marked[i]) { + for (int j = i * i; j < n; j += (i << 1)) { + if (!marked[j]) { + marked[j] = true; + --count; + } + } + } + } + return count; + } +}; diff --git a/0205_isomorphic_strings/Makefile b/0205_isomorphic_strings/Makefile new file mode 100644 index 0000000..e2eff8d --- /dev/null +++ b/0205_isomorphic_strings/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test isomorphic_strings.c diff --git a/0205_isomorphic_strings/isomorphic_strings.c b/0205_isomorphic_strings/isomorphic_strings.c new file mode 100644 index 0000000..692713a --- /dev/null +++ b/0205_isomorphic_strings/isomorphic_strings.c @@ -0,0 +1,32 @@ +#include +#include +#include + +static bool isIsomorphic(char *s, char *t) +{ + int i; + char smap[128] = { '\0' }; + char tmap[128] = { '\0' }; + while (*s != '\0' && *t != '\0') { + if ((smap[*s] != '\0' && smap[*s] != *t) || + (tmap[*t] != '\0' && tmap[*t] != *s)) { + return false; + } + smap[*s] = *t; + tmap[*t] = *s; + s++; + t++; + } + return *s == *t; +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./test s1 s2\n"); + exit(-1); + } + + printf("%s\n", isIsomorphic(argv[1], argv[2]) ? "true" : "false"); + return 0; +} diff --git a/0205_isomorphic_strings/isomorphic_strings.cpp b/0205_isomorphic_strings/isomorphic_strings.cpp new file mode 100644 index 0000000..5eb6551 --- /dev/null +++ b/0205_isomorphic_strings/isomorphic_strings.cpp @@ -0,0 +1,45 @@ +#include +using namespace std; + +class Solution +{ +public: + string mp(string s) + { + map m; + string ans = ""; + for (auto c : s) + { + if (m.find(c) == m.end()) + { + m[c] = m.size(); + } + ans += m[c]; + } + return ans; + } + bool isIsomorphic(string s, string t) + { + if (mp(s) == mp(t)) + { + return true; + } + return false; + } +}; + +int main() +{ + string s, t; + cout << "Enter 2 Strings : "; + cin >> s >> t; + Solution sol; + if (sol.isIsomorphic(s, t)) + { + cout << "True"; + } + else + { + cout << "False"; + } +} \ No newline at end of file diff --git a/0206_reverse_linked_list/Makefile b/0206_reverse_linked_list/Makefile new file mode 100644 index 0000000..efe146e --- /dev/null +++ b/0206_reverse_linked_list/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test reverse_list.c diff --git a/0206_reverse_linked_list/reverse_list.c b/0206_reverse_linked_list/reverse_list.c new file mode 100644 index 0000000..22c65bd --- /dev/null +++ b/0206_reverse_linked_list/reverse_list.c @@ -0,0 +1,67 @@ +#include +#include + + +struct ListNode { + int val; + struct ListNode *next; +}; + +static struct ListNode *recursive(struct ListNode *prev, struct ListNode *p) +{ + if (p == NULL) { + return prev; + } + + struct ListNode *q = p->next; + p->next = prev; + return recursive(p, q); +} + +struct ListNode *reverseList(struct ListNode *head) +{ + return recursive(NULL, head); +} + + +#if 0 +/* 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; + } + + return prev; +} +#endif + +int main(int argc, char **argv) +{ + int i, count = argc - 1; + struct ListNode *head = NULL, *p, *prev; + for (i = 0; i < count; i++) { + p = malloc(sizeof(*p)); + p->val = atoi(argv[i + 1]); + p->next = NULL; + if (head == NULL) { + head = p; + } else { + prev->next = p; + } + prev = p; + } + + for (p = reverseList(head); p != NULL; p = p->next) { + printf("%d ", p->val); + } + printf("\n"); + return 0; +} diff --git a/0206_reverse_linked_list/reverse_list.cc b/0206_reverse_linked_list/reverse_list.cc new file mode 100644 index 0000000..426a748 --- /dev/null +++ b/0206_reverse_linked_list/reverse_list.cc @@ -0,0 +1,30 @@ +#include + +using namespace std; + +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode() : val(0), next(nullptr) {} + * ListNode(int x) : val(x), next(nullptr) {} + * ListNode(int x, ListNode *next) : val(x), next(next) {} + * }; + */ +class Solution { +public: + ListNode* reverseList(ListNode* head) { + ListNode *prev = nullptr; + ListNode *p = head; + while (p != nullptr) { + // prev <- p <- q + ListNode *q = p->next; + p->next = prev; + // step + prev = p; + p = q; + } + return prev; + } +}; diff --git a/0207_course_schedule/Makefile b/0207_course_schedule/Makefile new file mode 100644 index 0000000..213bc14 --- /dev/null +++ b/0207_course_schedule/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test course_schedule.c diff --git a/0207_course_schedule/course_schedule.c b/0207_course_schedule/course_schedule.c new file mode 100644 index 0000000..cfd1727 --- /dev/null +++ b/0207_course_schedule/course_schedule.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include + + +struct graph_node { + int req_num; + int reqs[15]; + bool touched; + bool taken; +}; + +static bool dfs(struct graph_node *courses, int id) +{ + int i; + if (courses[id].touched) { + return true; + } else if (courses[id].taken) { + return false; + } else { + courses[id].taken = true; + for (i = 0; i < courses[id].req_num; i++) { + if (!dfs(courses, courses[id].reqs[i])) { + return 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 prerequisitesSize, int *prerequisitesColSize) +{ + int i; + struct graph_node *courses = malloc(numCourses * sizeof(*courses)); + + memset(courses, 0, numCourses * sizeof(*courses)); + 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)) { + return false; + } + } + + return true; +} + +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; + 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/0208_implement_trie/Makefile b/0208_implement_trie/Makefile new file mode 100644 index 0000000..81a10e7 --- /dev/null +++ b/0208_implement_trie/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test trie.c diff --git a/0208_implement_trie/trie.c b/0208_implement_trie/trie.c new file mode 100644 index 0000000..8a1a312 --- /dev/null +++ b/0208_implement_trie/trie.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include + +typedef struct Trie { + struct Trie *subs[27]; + char letters[27]; +} Trie; + +/** Initialize your data structure here. */ +static Trie* trieCreate() +{ + Trie *obj = malloc(sizeof(*obj)); + memset(obj->letters, 0xff, sizeof(obj->letters)); + memset(&obj->subs[0], 0, sizeof(obj->subs)); + return obj; +} + +/** Inserts a word into the trie. */ +static void trieInsert(Trie* obj, char* word) +{ + while (*word != '\0') { + int pos = *word - 'a' + 1; + obj->letters[pos] = *word++; + if (obj->subs[pos] == NULL) { + obj->subs[pos] = trieCreate(); + } + obj = obj->subs[pos]; + } + obj->letters[0] = '\0'; +} + +/** Returns if the word is in the trie. */ +static bool trieSearch(Trie* obj, char* word) +{ + while (obj != NULL) { + int pos = *word == '\0' ? 0 : *word - 'a' + 1; + if (obj->letters[pos] != *word) { + return false; + } + word++; + obj = obj->subs[pos]; + } + return true; +} + +/** Returns if there is any word in the trie that starts with the given prefix. */ +static bool trieStartsWith(Trie* obj, char* prefix) +{ + while (*prefix != '\0') { + int pos = *prefix - 'a' + 1; + if (pos < 0 || obj->letters[pos] != *prefix) { + return false; + } + if (*++prefix != '\0') { + if (obj->subs[pos] == NULL) { + return false; + } + obj = obj->subs[pos]; + } + } + return true; +} + +static void trieFree(Trie* obj) +{ + int i; + for (i = 0; i < sizeof(obj->letters); i++) { + if (obj->subs[i] != NULL) { + trieFree(obj->subs[i]); + } + } + free(obj); +} + +int main(void) +{ + char *word1 = "abc"; + char *word2 = "ab"; + + Trie* obj = trieCreate(); + trieInsert(obj, word1); + printf("%s\n", trieSearch(obj, word1) ? "true" : "false"); + printf("%s\n", trieSearch(obj, word2) ? "true" : "false"); + trieInsert(obj, word2); + printf("%s\n", trieSearch(obj, word2) ? "true" : "false"); + trieInsert(obj, word2); + printf("%s\n", trieStartsWith(obj, word2) ? "true" : "false"); + trieFree(obj); + return 0; +} diff --git a/0209_minimum_size_subarray_sum/Makefile b/0209_minimum_size_subarray_sum/Makefile new file mode 100644 index 0000000..bac59d5 --- /dev/null +++ b/0209_minimum_size_subarray_sum/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test mini_size.c diff --git a/0209_minimum_size_subarray_sum/mini_size.c b/0209_minimum_size_subarray_sum/mini_size.c new file mode 100644 index 0000000..303907f --- /dev/null +++ b/0209_minimum_size_subarray_sum/mini_size.c @@ -0,0 +1,40 @@ +#include +#include +#include + +static inline int min(int a, int b) +{ + return a < b ? a : b; +} + +static int minSubArrayLen(int s, int* nums, int numsSize) +{ + int i, sum = 0, len = INT_MAX, start = 0; + for (i = 0; i < numsSize; i++) { + sum += nums[i]; + while (sum >= s) { + /* sliding window */ + len = min(len, i - start + 1); + sum -= nums[start++]; + } + } + + return len == INT_MAX ? 0 : len; +} + +int main(int argc, char **argv) +{ + if (argc < 3) { + fprintf(stderr, "Usage: ./test sum n1 n2...\n"); + exit(-1); + } + + int i, count = argc - 2; + int sum = atoi(argv[1]); + int *nums = malloc(count * sizeof(int)); + for (i = 0; i < count; i++) { + nums[i] = atoi(argv[i + 2]); + } + printf("%d\n", minSubArrayLen(sum, nums, count)); + return 0; +} diff --git a/020_valid_parentheses/Makefile b/020_valid_parentheses/Makefile deleted file mode 100644 index 04fa256..0000000 --- a/020_valid_parentheses/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test valid_parentheses.c diff --git a/0210_course_schedule_ii/Makefile b/0210_course_schedule_ii/Makefile new file mode 100644 index 0000000..213bc14 --- /dev/null +++ b/0210_course_schedule_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test course_schedule.c diff --git a/0210_course_schedule_ii/course_schedule.c b/0210_course_schedule_ii/course_schedule.c new file mode 100644 index 0000000..d2d33b4 --- /dev/null +++ b/0210_course_schedule_ii/course_schedule.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include + + +struct graph_node { + int req_num; + int reqs[15]; + bool touched; + bool taken; +}; + +static bool dfs(struct graph_node *courses, int id, int *order, int *count) +{ + int i; + if (courses[id].touched) { + return true; + } else if (courses[id].taken) { + return false; + } else { + courses[id].taken = true; + for (i = 0; i < courses[id].req_num; i++) { + if (!dfs(courses, courses[id].reqs[i], order, count)) { + return false; + } + } + /* Record path in backtrace before DFS return */ + order[(*count)++] = id; + /* If paths overlapped, mark in backtracing for no need to traverse next time */ + courses[id].touched = true; + courses[id].taken = false; + return true; + } +} + +/** + * 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 prerequisitesSize, int *prerequisitesColSize, int *returnSize) +{ + int i; + int *order = malloc(numCourses * sizeof(int)); + struct graph_node *courses = malloc(numCourses * sizeof(*courses)); + + memset(courses, 0, numCourses * sizeof(*courses)); + for (i = 0; i < prerequisitesSize; i++) { + int id = prerequisites[i][0]; + int req = prerequisites[i][1]; + courses[id].reqs[courses[id].req_num++] = req; + } + + *returnSize = 0; + for (i = 0; i < numCourses; i++) { + if (!dfs(courses, i, order, returnSize)) { + *returnSize = 0; + return order; + } + } + + return order; +} + +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; + //pairs[1] = malloc(2 * sizeof(int)); + //pairs[1][0] = 2; + //pairs[1][1] = 1; + //pairs[2] = malloc(2 * sizeof(int)); + //pairs[2][0] = 3; + //pairs[2][1] = 2; + //pairs[3] = malloc(2 * sizeof(int)); + //pairs[3][0] = 4; + //pairs[3][1] = 0; + //pairs[4] = malloc(2 * sizeof(int)); + //pairs[4][0] = 0; + //pairs[4][1] = 5; + + int count = 0; + int *ids = findOrder(course_num, pairs, pair_num, col_sizes, &count); + for (i = 0; i < count; i++) { + printf("%d ", ids[i]); + } + printf("\n"); + return 0; +} diff --git a/0211_add_and_search_word/Makefile b/0211_add_and_search_word/Makefile new file mode 100644 index 0000000..5f82d6f --- /dev/null +++ b/0211_add_and_search_word/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test word_dict.c diff --git a/0211_add_and_search_word/word_dict.c b/0211_add_and_search_word/word_dict.c new file mode 100644 index 0000000..d989901 --- /dev/null +++ b/0211_add_and_search_word/word_dict.c @@ -0,0 +1,89 @@ +#include +#include +#include +#include + +typedef struct WordDictionary { + struct WordDictionary *subs[27]; + char letters[27]; +} WordDictionary; + +/** Initialize your data structure here. */ +static WordDictionary* wordDictionaryCreate() +{ + WordDictionary *obj = malloc(sizeof(*obj)); + memset(obj->letters, 0xff, sizeof(obj->letters)); + memset(&obj->subs[0], 0, sizeof(obj->subs)); + return obj; +} + +/** Inserts a word into the wordDictionary. */ +static void wordDictionaryInsert(WordDictionary* obj, char* word) +{ + while (*word != '\0') { + int pos = *word - 'a' + 1; + obj->letters[pos] = *word++; + if (obj->subs[pos] == NULL) { + obj->subs[pos] = wordDictionaryCreate(); + } + obj = obj->subs[pos]; + } + obj->letters[0] = '\0'; +} + +/** Returns if the word is in the wordDictionary. */ +static bool wordDictionarySearch(WordDictionary* obj, char* word) +{ + int i; + while (obj != NULL) { + if (*word == '.') { + bool found; + for (i = 1; i < sizeof(obj->letters); i++) { + if (obj->subs[i] != NULL) { + found = wordDictionarySearch(obj->subs[i], word + 1); + if (found) { + return true; + } + } + } + return false; + } else { + int pos = *word == '\0' ? 0 : *word - 'a' + 1; + if (obj->letters[pos] != *word) { + return false; + } + word++; + obj = obj->subs[pos]; + } + } + return true; +} + +static void wordDictionaryFree(WordDictionary* obj) +{ + int i; + for (i = 0; i < sizeof(obj->letters); i++) { + if (obj->subs[i] != NULL) { + wordDictionaryFree(obj->subs[i]); + } + } + free(obj); +} + +int main(void) +{ + char *word1 = "abc"; + char *word2 = "ab"; + char *word3 = "..."; + + WordDictionary* obj = wordDictionaryCreate(); + wordDictionaryInsert(obj, word1); + printf("%s\n", wordDictionarySearch(obj, word1) ? "true" : "false"); + printf("%s\n", wordDictionarySearch(obj, word2) ? "true" : "false"); + wordDictionaryInsert(obj, word2); + printf("%s\n", wordDictionarySearch(obj, word2) ? "true" : "false"); + wordDictionaryInsert(obj, word2); + printf("%s\n", wordDictionarySearch(obj, word3) ? "true" : "false"); + wordDictionaryFree(obj); + return 0; +} diff --git a/0212_word_search_ii/Makefile b/0212_word_search_ii/Makefile new file mode 100644 index 0000000..2eab6c6 --- /dev/null +++ b/0212_word_search_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test word_search.c diff --git a/0212_word_search_ii/word_search.c b/0212_word_search_ii/word_search.c new file mode 100644 index 0000000..54d78a1 --- /dev/null +++ b/0212_word_search_ii/word_search.c @@ -0,0 +1,196 @@ +#include +#include +#include +#include + +struct trie { + struct trie *subs[27]; + char letters[27]; + int num; +}; + +static struct trie* trie_create() +{ + struct trie *obj = malloc(sizeof(*obj)); + memset(obj->letters, 0xff, sizeof(obj->letters)); + memset(&obj->subs[0], 0, sizeof(obj->subs)); + obj->num = 0; + return obj; +} + +static void trie_insert(struct trie* obj, char* word) +{ + while (*word != '\0') { + int pos = *word - 'a' + 1; + obj->letters[pos] = *word++; + obj->num++; + if (obj->subs[pos] == NULL) { + obj->subs[pos] = trie_create(); + } + obj = obj->subs[pos]; + } + obj->letters[0] = '\0'; +} + +static void trie_remove(struct trie* obj, char* word) +{ + while (obj != NULL && *word != '\0') { + int pos = *word++ - 'a' + 1; + if (--obj->num == 0) { + obj->letters[pos] = 0xff; + } + obj = obj->subs[pos]; + } + if (obj != NULL) { + obj->letters[0] = 0xff; + } +} + +static void dfs(char **board, int row_size, int col_size, int row, int col, struct trie *node, + char *word, int len, bool *used, char **results, int *count, struct trie *root, int *wordsSize) +{ + char c = board[row][col]; + int index = c - 'a' + 1; + + if (node == NULL || node->letters[index] == -1) { + return; + } + + printf("%d %d\n", row, col); + word[len] = c; + + struct trie *sub = node->subs[index]; + if (sub != NULL && sub->letters[0] == '\0') { + word[len + 1] = '\0'; + results[*count] = malloc(len + 2); + strcpy(results[*count], word); + (*count)++; + trie_remove(root, word); + (*wordsSize)--; + printf("%s\n", word); + } + + used[row * col_size + col] = true; + + if (row > 0 && !used[(row - 1) * col_size + col]) { + dfs(board, row_size, col_size, row - 1, col, node->subs[index], word, len + 1, used, results, count, root, wordsSize); + } + + if (row < row_size - 1 && !used[(row + 1) * col_size + col]) { + dfs(board, row_size, col_size, row + 1, col, node->subs[index], word, len + 1, used, results, count, root, wordsSize); + } + + if (col > 0 && !used[row * col_size + col - 1]) { + dfs(board, row_size, col_size, row, col - 1, node->subs[index], word, len + 1, used, results, count, root, wordsSize); + } + + if (col < col_size - 1 && !used[row * col_size + col + 1]) { + dfs(board, row_size, col_size, row, col + 1, node->subs[index], word, len + 1, used, results, count, root, wordsSize); + } + + used[row * col_size + col] = false; +} + +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +static char **findWords(char** board, int boardRowSize, int boardColSize, char** words, int wordsSize, int* returnSize) +{ + int i, j, cap = 5000; + struct trie *root = trie_create(); + for (i = 0; i < wordsSize; i++) { + trie_insert(root, words[i]); + } + + *returnSize = 0; + char *word = malloc(boardRowSize * boardColSize + 1); + memset(word, 0, boardRowSize * boardColSize + 1); + char **results = malloc(cap * sizeof(char *)); + bool *used = malloc(boardRowSize * boardColSize); + memset(used, false, boardRowSize * boardColSize); + for (i = 0; i < boardRowSize; i++) { + for (j = 0; j < boardColSize; j++) { + if (wordsSize == 0) { + return results; + } + dfs(board, boardRowSize, boardColSize, i, j, root, word, 0, used, results, returnSize, root, &wordsSize); + } + } + return results; +} + +int main(void) +{ + int i; +#if 0 + int row = 4; + int col = 4; + char **board = malloc(row * sizeof(char *)); + board[0] = malloc(col); + board[0][0] = 'o'; + board[0][1] = 'a'; + board[0][2] = 'a'; + board[0][3] = 'n'; + board[1] = malloc(col); + board[1][0] = 'e'; + board[1][1] = 't'; + board[1][2] = 'a'; + board[1][3] = 'e'; + board[2] = malloc(col); + board[2][0] = 'i'; + board[2][1] = 'h'; + board[2][2] = 'k'; + board[2][3] = 'r'; + board[3] = malloc(col); + board[3][0] = 'i'; + board[3][1] = 'f'; + board[3][2] = 'l'; + board[3][3] = 'v'; + + int size = 4; + char **words = malloc(size * sizeof(char *)); + words[0] = malloc(5); + strcpy(words[0], "oath"); + words[1] = malloc(5); + strcpy(words[1], "pea"); + words[2] = malloc(5); + strcpy(words[2], "eat"); + words[3] = malloc(5); + strcpy(words[3], "rain"); +#else + int row = 2; + int col = 2; + char **board = malloc(row * sizeof(char *)); + board[0] = malloc(col); + board[0][0] = 'a'; + board[0][1] = 'b'; + board[1] = malloc(col); + board[1][0] = 'a'; + board[1][1] = 'a'; + + int size = 7; + char **words = malloc(size * sizeof(char *)); + words[0] = malloc(5); + words[1] = malloc(5); + words[2] = malloc(5); + words[3] = malloc(5); + words[4] = malloc(5); + words[5] = malloc(5); + words[6] = malloc(5); + strcpy(words[0], "aba"); + strcpy(words[1], "baa"); + strcpy(words[2], "bab"); + strcpy(words[3], "aaab"); + strcpy(words[4], "aaa"); + strcpy(words[5], "aaaa"); + strcpy(words[6], "aaba"); +#endif + + int count = 0; + char **lists = findWords(board, row, col, words, size, &count); + for (i = 0; i < count; i++) { + printf("%s\n", lists[i]); + } + return 0; +} diff --git a/0213_house_robber_ii/Makefile b/0213_house_robber_ii/Makefile new file mode 100644 index 0000000..16f41d2 --- /dev/null +++ b/0213_house_robber_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test robber.c diff --git a/0213_house_robber_ii/robber.c b/0213_house_robber_ii/robber.c new file mode 100644 index 0000000..ed54519 --- /dev/null +++ b/0213_house_robber_ii/robber.c @@ -0,0 +1,45 @@ +#include +#include +#include + +static inline int max(int a, int b) +{ + return a > b ? a : b; +} + +static int _rob(int* nums, int numsSize) +{ + int i; + int taken = 0; + int untaken = 0; + /* Record max profits of nums[0...i] respectively */ + for (i = 0; i < numsSize; i++) { + int tmp_taken = taken; + /* Taken or untaken nums[i] */ + taken = untaken + nums[i]; + untaken = max(tmp_taken, untaken); + } + + return max(taken, untaken); +} + +static int rob(int* nums, int numsSize) +{ + if (numsSize == 1) { + return nums[0]; + } else { + /* The first and the last element are adjacent */ + return max(_rob(nums + 1, numsSize - 1), _rob(nums, numsSize - 1)); + } +} + +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", rob(nums, count)); + return 0; +} 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/0214_shortest_palindrome/Makefile b/0214_shortest_palindrome/Makefile new file mode 100644 index 0000000..3e05ad5 --- /dev/null +++ b/0214_shortest_palindrome/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test shortest_palindrome.c diff --git a/0214_shortest_palindrome/shortest_palindrome.c b/0214_shortest_palindrome/shortest_palindrome.c new file mode 100644 index 0000000..3440488 --- /dev/null +++ b/0214_shortest_palindrome/shortest_palindrome.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include + +static inline char *rev_cpy(char *dst, char *src, int size) +{ + while (size-- > 0) { + *--dst = *src++; + } + return dst; +} + +static char *shortestPalindrome(char *s) +{ + int i, j, len = strlen(s); + char *result = malloc(2 * len + 2); + + strcpy(result, s); + result[len] = '#'; + rev_cpy(result + 2 * len + 1, s, len); + + int res_len = 2 * len + 1; + int *next = malloc(res_len * sizeof(int)); + memset(next, 0, res_len * sizeof(int)); + for (i = 1; i < res_len; i++) { + int j = next[i - 1]; + while (j > 0 && result[i] != result[j]) { + j = next[j - 1]; + } + j += result[i] == result[j]; + next[i] = j; + } + + for (i = 0; i < res_len; i++) { + printf("%d ", next[i]); + } + printf("\n"); + + memmove(result, result + len + 1, len + 1); + int start = len - next[res_len - 1]; + strcpy(result + start, s); + return result; +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test string\n"); + exit(-1); + } + + printf("%s\n", shortestPalindrome(argv[1])); + return 0; +} diff --git a/0215_kth_largest_element_in_an_array/Makefile b/0215_kth_largest_element_in_an_array/Makefile new file mode 100644 index 0000000..4caf991 --- /dev/null +++ b/0215_kth_largest_element_in_an_array/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test kth_elem.c 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/0216_combination_sum_iii/Makefile b/0216_combination_sum_iii/Makefile new file mode 100644 index 0000000..dafaf31 --- /dev/null +++ b/0216_combination_sum_iii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test combination_sum.c diff --git a/0216_combination_sum_iii/combination_sum.c b/0216_combination_sum_iii/combination_sum.c new file mode 100644 index 0000000..a51761a --- /dev/null +++ b/0216_combination_sum_iii/combination_sum.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include + +static void dfs(int *nums, int size, int start, int target, int k, + int *solution, int len, int **results, int *count, int *col_sizes) +{ + int i; + if (len == k) { + if (target == 0) { + results[*count] = malloc(len * sizeof(int)); + memcpy(results[*count], solution, len * sizeof(int)); + col_sizes[*count] = len; + (*count)++; + } + } else if (target > 0) { + for (i = start; i < size; i++) { + solution[len] = nums[i]; + dfs(nums, size, i + 1, target - nums[i], k, solution, len + 1, results, count, 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 *returnColumnSizes array must be malloced, assume caller calls free(). + **/ +static int** combinationSum3(int k, int n, int* returnSize, int** returnColumnSizes) +{ + int i, count = 9; + int *nums = malloc(count * sizeof(int)); + for (i = 0; i < count; i++) { + nums[i] = i + 1; + } + + int *solution = malloc(k * sizeof(int)); + int **results = malloc(100 * sizeof(int *)); + *returnColumnSizes = malloc(100 * sizeof(int)); + *returnSize = 0; + dfs(nums, count, 0, n, k, solution, 0, results, returnSize, *returnColumnSizes); + return results; +} + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./test k n\n"); + exit(-1); + } + + int i, j; + int k = atoi(argv[1]); + int n = atoi(argv[2]); + int *sizes, count = 0; + int **lists = combinationSum3(k, n, &count, &sizes); + for (i = 0; i < count; i++) { + for (j = 0; j < sizes[i]; j++) { + printf("%d ", lists[i][j]); + } + printf("\n"); + } + return 0; +} 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/021_merge_two_sorted_lists/Makefile b/021_merge_two_sorted_lists/Makefile deleted file mode 100644 index 9c7c9b0..0000000 --- a/021_merge_two_sorted_lists/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test merge_lists.c diff --git a/021_merge_two_sorted_lists/merge_lists.c b/021_merge_two_sorted_lists/merge_lists.c deleted file mode 100644 index 28ee2d3..0000000 --- a/021_merge_two_sorted_lists/merge_lists.c +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include - -struct ListNode { - int val; - struct ListNode *next; -}; - -static struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) -{ - struct ListNode dummy, *tail = &dummy; - dummy.next = NULL; - - while (l1 != NULL || l2 != NULL) { - struct ListNode *node = malloc(sizeof(*node)); - node->next = NULL; - tail->next = node; - tail = node; - if (l1 != NULL) { - if (l2 != NULL) { - if (l1->val < l2->val) { - node->val = l1->val; - l1 = l1->next; - } else { - node->val = l2->val; - l2 = l2->next; - } - } else { - node->val = l1->val; - l1 = l1->next; - } - } else { - node->val = l2->val; - l2 = l2->next; - } - } - - return dummy.next; -} - -int main(int argc, char **argv) -{ - struct ListNode l1; - l1.val = 2; - l1.next = NULL; - struct ListNode l2; - l2.val = 1; - l2.next = NULL; - struct ListNode * list = mergeTwoLists(&l1, &l2); - while (list != NULL) { - printf("%d ", list->val); - list = list->next; - } - printf("\n"); - return 0; -} diff --git a/0221_maximal_square/Makefile b/0221_maximal_square/Makefile new file mode 100644 index 0000000..f7a10f7 --- /dev/null +++ b/0221_maximal_square/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test maximal_square.c diff --git a/0221_maximal_square/maximal_square.c b/0221_maximal_square/maximal_square.c new file mode 100644 index 0000000..e21ec4b --- /dev/null +++ b/0221_maximal_square/maximal_square.c @@ -0,0 +1,69 @@ +#include +#include +#include + +static inline int min(int a, int b) +{ + return a < b ? a : b; +} + +static inline int max(int a, int b) +{ + return a > b ? a : b; +} + +static int maximalSquare(char** matrix, int matrixRowSize, int matrixColSize) +{ + int i, j, max_len = 0; + int **lens = malloc(matrixRowSize * sizeof(int *)); + for (i = 0; i < matrixRowSize; i++) { + lens[i] = malloc(matrixColSize * sizeof(int)); + } + + for (i = 0; i < matrixColSize; i++) { + lens[0][i] = matrix[0][i] == '1' ? 1 : 0; + max_len = matrix[0][i] == '1' ? 1 : max_len; + } + + for (i = 0; i < matrixRowSize; i++) { + lens[i][0] = matrix[i][0] == '1' ? 1 : 0; + max_len = matrix[i][0] == '1' ? 1 : max_len; + } + + for (i = 1; i < matrixRowSize; i++) { + for (j = 1; j < matrixColSize; j++) { + if (matrix[i][j] == '1') { + lens[i][j] = 1; + lens[i][j] += min(lens[i - 1][j - 1], min(lens[i - 1][j], lens[i][j - 1])); + } else { + lens[i][j] = 0; + } + max_len = max(max_len, lens[i][j]); + } + } + for (i = 0; i < matrixRowSize; i++) { + for (j = 0; j < matrixColSize; j++) { + printf("%d ", lens[i][j]); + } + printf("\n"); + } + return max_len * max_len; +} + +/* ./test 11111111 11111110 11111110 11111000 01111000 */ +int main(int argc, char **argv) +{ + if (argc < 2) { + fprintf(stderr, "Usage: ./test row1 row2...\n"); + exit(-1); + } + + int i, j; + int row_size = argc - 1; + int col_size = strlen(argv[1]); + for (i = 0; i < row_size; i++) { + printf("%s\n", argv[i + 1]); + } + printf("%d\n", maximalSquare(argv + 1, argc - 1, strlen(argv[1]))); + return 0; +} diff --git a/0224_basic_calculator/Makefile b/0224_basic_calculator/Makefile new file mode 100644 index 0000000..b12a1c8 --- /dev/null +++ b/0224_basic_calculator/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test calculator.c 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/0226_invert_binary_tree/Makefile b/0226_invert_binary_tree/Makefile new file mode 100644 index 0000000..842878d --- /dev/null +++ b/0226_invert_binary_tree/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test invert_binary_tree.c diff --git a/0226_invert_binary_tree/invert_binary_tree.c b/0226_invert_binary_tree/invert_binary_tree.c new file mode 100644 index 0000000..7efae0d --- /dev/null +++ b/0226_invert_binary_tree/invert_binary_tree.c @@ -0,0 +1,70 @@ +#include +#include +#include + +struct TreeNode { + int val; + struct TreeNode *left; + struct TreeNode *right; +}; + +static struct TreeNode *invertTree(struct TreeNode* root) +{ + 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; +} + +int main(void) +{ +#if 1 + struct TreeNode root, n10, n11, n20, n21, n22, n23; + root.val = 1; + n10.val = 2; + n11.val = 2; + n20.val = 3; + n21.val = 4; + n22.val = 4; + n23.val = 3; + root.left = &n10; + root.right = &n11; + n10.left = &n20; + n10.right = &n21; + n11.left = &n22; + n11.right = &n23; + n20.left = NULL; + n20.right = NULL; + n21.left = NULL; + n21.right = NULL; + n22.left = NULL; + n22.right = NULL; + n23.left = NULL; + n23.right = NULL; +#else + struct TreeNode root, n10, n11, n21, n22; + root.val = 1; + n10.val = 2; + n11.val = 2; + n21.val = 3; + n22.val = 4; + root.left = &n10; + root.right = &n11; + n10.left = NULL; + n10.right = &n21; + n11.left = &n22; + n11.right = NULL; + n21.left = NULL; + n21.right = NULL; + n22.left = NULL; + n22.right = NULL; +#endif + + invertTree(&root); + return 0; +} 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/0227_basic_calculator_ii/Makefile b/0227_basic_calculator_ii/Makefile new file mode 100644 index 0000000..b12a1c8 --- /dev/null +++ b/0227_basic_calculator_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test calculator.c diff --git a/0227_basic_calculator_ii/calculator.c b/0227_basic_calculator_ii/calculator.c new file mode 100644 index 0000000..6465b9b --- /dev/null +++ b/0227_basic_calculator_ii/calculator.c @@ -0,0 +1,75 @@ +#include +#include + +static int calculator(char *s) +{ + int n; + int pos1 = 0; + int pos2 = 0; + int *nums = malloc(100 * sizeof(int)); + char *signs = malloc(100 * sizeof(char)); + + nums[pos1++] = 0; + while (*s != '\0') { + switch (*s) { + case '+': + case '-': + if (pos1 >= 3) { + int b = nums[pos1 - 1]; + int a = nums[pos1 - 2]; + if (signs[--pos2] == '+') { + nums[pos1 - 2] = a + b; + } else { + nums[pos1 - 2] = a - b; + } + pos1--; + } + case '*': + case '/': + signs[pos2++] = *s; + 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++; + } + + while (pos2 > 0) { + n = nums[--pos1]; + int a = nums[--pos1]; + if (signs[--pos2] == '+') { + n = a + n; + } else { + n = a - n; + } + } + 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/0229_majority_element_ii/Makefile b/0229_majority_element_ii/Makefile new file mode 100644 index 0000000..84ca762 --- /dev/null +++ b/0229_majority_element_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test majority.c diff --git a/0229_majority_element_ii/majority.c b/0229_majority_element_ii/majority.c new file mode 100644 index 0000000..780fca4 --- /dev/null +++ b/0229_majority_element_ii/majority.c @@ -0,0 +1,67 @@ +#include +#include + +static int *majorityElement(int* nums, int numsSize, int *returnSize) +{ + int i, m = -1, n = -1, cm = 0, cn = 0; + for (i = 0; i < numsSize; i++) { + if (m == nums[i]) { + cm++; + } else if (n == nums[i]) { + cn++; + } else if (cm == 0) { + m = nums[i]; + cm++; + } else if (cn == 0) { + n = nums[i]; + cn++; + } else { + cm--; + cn--; + } + } + + cm = 0; + cn = 0; + for (i = 0; i < numsSize; i++) { + if (nums[i] == m) { + cm++; + } else if (nums[i] == n) { + cn++; + } + } + + int count = 0; + int *results = malloc(2 * sizeof(int)); + if (cm > numsSize / 3) { + results[count++] = m; + } + if (cn > numsSize / 3) { + results[count++] = n; + } + + *returnSize = count; + return results; +} + +int main(int argc, char **argv) +{ + if (argc < 2) { + fprintf(stderr, "Usage: ./test target n1 n2...\n"); + exit(-1); + } + + int i, size = argc - 1; + int *nums = malloc(size * sizeof(int)); + for (i = 0; i < size; i++) { + nums[i] = atoi(argv[i + 1]); + } + + int count = 0; + int *results = majorityElement(nums, size, &count); + for (i = 0; i < count; i++) { + printf("%d ", results[i]); + } + printf("\n"); + return 0; +} diff --git a/022_generate_paratheses/Makefile b/022_generate_paratheses/Makefile deleted file mode 100644 index 5445d90..0000000 --- a/022_generate_paratheses/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test parentheses.c diff --git a/022_generate_paratheses/parentheses.c b/022_generate_paratheses/parentheses.c deleted file mode 100644 index f9103ed..0000000 --- a/022_generate_paratheses/parentheses.c +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include -#include - -/** - ** Return an array of size *returnSize. - ** Note: The returned array must be malloced, assume caller calls free(). - **/ -char** generateParenthesis(int n, int* returnSize) { - int left, right, cap = 1, count = 0; - char *stack = malloc(2 * n + 1); - char **parentheses = malloc(cap * sizeof(char *)); - - char *p = stack; - left = right = 0; - stack[2 * n] = '\0'; - - /* begin and end condition of loop */ - while (p != stack || count == 0) { - if (left == n && right == n) { - /* new stacks */ - if (count + 1 >= cap) { - cap *= 2; - parentheses = realloc(parentheses, cap * sizeof(char *)); - } - parentheses[count] = malloc(2 * n + 1); - strcpy(parentheses[count], stack); - count++; - - /* back tracking */ - while (--p != stack) { - if (*p == '(') { - /* until ')' is no more than '(' is guaranteed */ - if (--left > right) { - *p++ = ')'; - right++; - break; - } - } else { - right--; - } - } - } else { - /* forward */ - while (left < n) { - *p++ = '('; - left++; - } - while (right < n) { - *p++ = ')'; - right++; - } - } - } - - *returnSize = count; - return parentheses; -} - -int main(int argc, char **argv) -{ - int i, count; - if (argc != 2) { - fprintf(stderr, "Usage: ./test 3\n"); - exit(-1); - } - char ** lists = generateParenthesis(atoi(argv[1]), &count); - for (i = 0; i < count; i++) { - printf("%s\n", lists[i]); - } - return 0; -} diff --git a/0230_kth_smallest_element_in_a_bst/Makefile b/0230_kth_smallest_element_in_a_bst/Makefile new file mode 100644 index 0000000..7fe9d06 --- /dev/null +++ b/0230_kth_smallest_element_in_a_bst/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test kth_bst.c diff --git a/0230_kth_smallest_element_in_a_bst/kth_bst.c b/0230_kth_smallest_element_in_a_bst/kth_bst.c new file mode 100644 index 0000000..337f1a3 --- /dev/null +++ b/0230_kth_smallest_element_in_a_bst/kth_bst.c @@ -0,0 +1,83 @@ +#include +#include +#include + +struct TreeNode { + int val; + struct TreeNode *left; + struct TreeNode *right; +}; + +static bool traverse(struct TreeNode *node, int *k, int *val) +{ + if (node == NULL) { + return false; + } + if (traverse(node->left, k, val)) { + return true; + } + if (--*k == 0) { + *val = node->val; + return true; + } + if (traverse(node->right, k, val)) { + return true; + } + return false; +} + +static int kthSmallest(struct TreeNode* root, int k) +{ + int value = 0; + traverse(root, &k, &value); + return value; +} + +int main(void) +{ +#if 1 + struct TreeNode root, n10, n11, n20, n21, n22, n23; + root.val = 1; + n10.val = 2; + n11.val = 2; + n20.val = 3; + n21.val = 4; + n22.val = 4; + n23.val = 3; + root.left = &n10; + root.right = &n11; + n10.left = &n20; + n10.right = &n21; + n11.left = &n22; + n11.right = &n23; + n20.left = NULL; + n20.right = NULL; + n21.left = NULL; + n21.right = NULL; + n22.left = NULL; + n22.right = NULL; + n23.left = NULL; + n23.right = NULL; +#else + struct TreeNode root, n10, n11, n21, n22; + root.val = 1; + n10.val = 2; + n11.val = 2; + n21.val = 3; + n22.val = 4; + root.left = &n10; + root.right = &n11; + n10.left = NULL; + n10.right = &n21; + n11.left = &n22; + n11.right = NULL; + n21.left = NULL; + n21.right = NULL; + n22.left = NULL; + n22.right = NULL; +#endif + + int k = 1; + printf("%d\n", kthSmallest(&root, k)); + return 0; +} 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/0235_lowest_common_ancestor_of_a_binary_search_tree/Makefile b/0235_lowest_common_ancestor_of_a_binary_search_tree/Makefile new file mode 100644 index 0000000..1cfab66 --- /dev/null +++ b/0235_lowest_common_ancestor_of_a_binary_search_tree/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test bst_lca.c diff --git a/0235_lowest_common_ancestor_of_a_binary_search_tree/bst_lca.c b/0235_lowest_common_ancestor_of_a_binary_search_tree/bst_lca.c new file mode 100644 index 0000000..aecdf1c --- /dev/null +++ b/0235_lowest_common_ancestor_of_a_binary_search_tree/bst_lca.c @@ -0,0 +1,58 @@ +#include +#include +#include + +struct TreeNode { + int val; + struct TreeNode *left; + struct TreeNode *right; +}; + +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; + } else if (p->val > root->val && q->val > root->val) { + return lowestCommonAncestor(root->right, p, q); + } else if (p->val < root->val && q->val < root->val) { + return lowestCommonAncestor(root->left, p, q); + } else { + return root; + } +} + +int main(int argc, char **argv) +{ + struct TreeNode root, node1, node2, node11, node12, node21, node22, node121, node122; + root.val = 3; + node1.val = 2; + node2.val = 8; + node11.val = 0; + node12.val = 4; + node21.val = 7; + node22.val = 9; + node121.val = 3; + node122.val = 5; + root.left = &node1; + root.right = &node2; + node1.left = &node11; + node1.right = &node12; + node2.left = &node21; + node2.right = &node22; + node11.left = NULL; + node11.right = NULL; + node12.left = &node121; + node12.right = &node122; + node21.left = NULL; + node21.right = NULL; + node22.left = NULL; + node22.right = NULL; + node121.left = NULL; + node121.right = NULL; + node122.left = NULL; + node122.right = NULL; + + struct TreeNode *ancestor = lowestCommonAncestor(&root, &node11, &node22); + printf("%d\n", ancestor->val); + return 0; +} diff --git a/0235_lowest_common_ancestor_of_a_binary_search_tree/bst_lca.cc b/0235_lowest_common_ancestor_of_a_binary_search_tree/bst_lca.cc new file mode 100644 index 0000000..82fbf71 --- /dev/null +++ b/0235_lowest_common_ancestor_of_a_binary_search_tree/bst_lca.cc @@ -0,0 +1,28 @@ +#include + +using namespace std; + +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ + +class Solution { +public: + TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { + if (root == nullptr || root->val == p->val || root->val == q->val) { + return root; + } else if (root->val < p->val && root->val < q->val) { + return lowestCommonAncestor(root->right, p, q); + } else if (root->val > p->val && root->val > q->val) { + return lowestCommonAncestor(root->left, p, q); + } else { + return root; + } + } +}; diff --git a/0236_lowest_common_ancestor_of_a_binary_tree/Makefile b/0236_lowest_common_ancestor_of_a_binary_tree/Makefile new file mode 100644 index 0000000..1cfab66 --- /dev/null +++ b/0236_lowest_common_ancestor_of_a_binary_tree/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test bst_lca.c diff --git a/0236_lowest_common_ancestor_of_a_binary_tree/bst_lca.c b/0236_lowest_common_ancestor_of_a_binary_tree/bst_lca.c new file mode 100644 index 0000000..4eefea8 --- /dev/null +++ b/0236_lowest_common_ancestor_of_a_binary_tree/bst_lca.c @@ -0,0 +1,65 @@ +#include +#include +#include + + +struct TreeNode { + int val; + struct TreeNode *left; + struct TreeNode *right; +}; + +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); + /* r is the LCA in the right branch but not root->right */ + struct TreeNode *r = lowestCommonAncestor(root->right, p, q); + if (l != NULL && r != NULL) { + return root; + } else { + /* if not return root node, the return value is fixed */ + return l != NULL ? l : r; + } +} + +int main(int argc, char **argv) +{ + struct TreeNode root, node1, node2, node11, node12, node21, node22, node121, node122; + root.val = 3; + node1.val = 5; + node2.val = 1; + node11.val = 0; + node12.val = 4; + node21.val = 7; + node22.val = 9; + node121.val = 3; + node122.val = 5; + root.left = &node1; + root.right = &node2; + node1.left = &node11; + node1.right = &node12; + node2.left = &node21; + node2.right = &node22; + node11.left = NULL; + node11.right = NULL; + node12.left = &node121; + node12.right = &node122; + node21.left = NULL; + node21.right = NULL; + node22.left = NULL; + node22.right = NULL; + node121.left = NULL; + node121.right = NULL; + node122.left = NULL; + node122.right = NULL; + + struct TreeNode *ancestor = lowestCommonAncestor(&root, &node11, &node22); + printf("%d\n", ancestor->val); + return 0; +} 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/0239_sliding_window_maximum/Makefile b/0239_sliding_window_maximum/Makefile new file mode 100644 index 0000000..59c5a61 --- /dev/null +++ b/0239_sliding_window_maximum/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test slide_window.c diff --git a/0239_sliding_window_maximum/slide_window.c b/0239_sliding_window_maximum/slide_window.c new file mode 100644 index 0000000..8fa5cbf --- /dev/null +++ b/0239_sliding_window_maximum/slide_window.c @@ -0,0 +1,62 @@ +#include +#include + +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* maxSlidingWindow(int* nums, int numsSize, int k, int* returnSize) +{ + 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 (right > left && nums[i] >= nums[indexes[right - 1]]) { + /* squeeze out the previous smaller ones */ + right--; + } + + /* 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; + + /* let k = 1 to verify the corner case */ + if (i >= k - 1) { + results[count++] = nums[indexes[left]]; + } + + if (i - indexes[left] + 1 >= k) { + left++; + } + } + + *returnSize = count; + return results; +} + +int main(int argc, char **argv) +{ + if (argc < 2) { + fprintf(stderr, "Usage: ./test k n1 n2...\n"); + exit(-1); + } + + int i, size = argc - 2; + int k = atoi(argv[1]); + int *nums = malloc(size * sizeof(int)); + for (i = 0; i < size; i++) { + nums[i] = atoi(argv[i + 2]); + } + + int count = 0; + int *lists = maxSlidingWindow(nums, size, k, &count); + for (i = 0; i < count; i++) { + printf("%d ", lists[i]); + } + printf("\n"); + return 0; +} 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/Makefile b/023_merge_k_sorted_lists/Makefile deleted file mode 100644 index 9c7c9b0..0000000 --- a/023_merge_k_sorted_lists/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test merge_lists.c 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 8c81669..0000000 --- a/023_merge_k_sorted_lists/merge_lists.c +++ /dev/null @@ -1,91 +0,0 @@ -#include -#include -#include - -struct ListNode { - int val; - struct ListNode *next; -}; - -struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) { - if (listsSize == 0) { - return NULL; - } - if (listsSize == 1) { - return lists[0]; - } - - int i, index; - struct ListNode dummy, *p, *prev; - - dummy.next = NULL; - prev = &dummy; - index = 0; - while (index != -1) { - int min = INT_MAX; - index = -1; - for (i = 0; i < listsSize; i++) { - if (lists[i] != NULL && lists[i]->val < min) { - min = lists[i]->val; - index = i; - } - } - - if (index != -1) { - p = malloc(sizeof(*p)); - p->val = min; - p->next = NULL; - prev->next = p; - prev = p; - lists[index] = lists[index]->next; - } - } - - 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/024_swap_nodes_in_pairs/Makefile b/024_swap_nodes_in_pairs/Makefile deleted file mode 100644 index a3f3513..0000000 --- a/024_swap_nodes_in_pairs/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test swap_nodes.c diff --git a/025_reverse_nodes_in_k_group/Makefile b/025_reverse_nodes_in_k_group/Makefile deleted file mode 100644 index d0564d0..0000000 --- a/025_reverse_nodes_in_k_group/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test reverse_nodes.c diff --git a/025_reverse_nodes_in_k_group/reverse_nodes.c b/025_reverse_nodes_in_k_group/reverse_nodes.c deleted file mode 100644 index 680889b..0000000 --- a/025_reverse_nodes_in_k_group/reverse_nodes.c +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include - -struct ListNode { - int val; - struct ListNode *next; -}; - -static struct ListNode* reverseKGroup(struct ListNode* head, int k) { - if (head == NULL || k <= 1) { - return head; - } - - int first = 1; - struct ListNode dummy; - dummy.next = head; - struct ListNode *dhead = &dummy; - struct ListNode *prev = head; - struct ListNode *p = head->next; - struct ListNode *next = p == NULL ? NULL : p->next; - while (p != NULL) { - int i; - struct ListNode *end = dhead->next; - for (i = 0; end != NULL && i < k; i++) { - end = end->next; - } - if (i < k) { - break; - } - - while (p != end) { - p->next = dhead->next; - dhead->next = p; - prev->next = next; - p = next; - next = p == NULL ? NULL : p->next; - } - - if (first) { - first = 0; - dummy.next = dhead->next; - } - - dhead = prev; - prev = p; - p = p == NULL ? NULL : p->next; - next = p == NULL ? NULL : p->next; - } - return dummy.next; -} - -int main(int argc, char **argv) -{ - int i; - struct ListNode *p, *prev, dummy, *list; - - dummy.next = NULL; - prev = &dummy; - for (i = 2; i < argc; i++) { - p = malloc(sizeof(*p)); - int n = atoi(argv[i]); - printf("%d ", n); - p->val = n; - p->next = NULL; - prev->next = p; - prev = p; - } - putchar('\n'); - - list = reverseKGroup(dummy.next, atoi(argv[1])); - for (p = list; p != NULL; p = p->next) { - printf("%d ", p->val); - } - putchar('\n'); - - return 0; -} diff --git a/026_remove_duplicates_from_sorted_array/Makefile b/026_remove_duplicates_from_sorted_array/Makefile deleted file mode 100644 index 5cf5932..0000000 --- a/026_remove_duplicates_from_sorted_array/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test rm_dup.c diff --git a/027_remove_element/Makefile b/027_remove_element/Makefile deleted file mode 100644 index 210f162..0000000 --- a/027_remove_element/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test rm_elem.c diff --git a/028_implement_strstr/Makefile b/028_implement_strstr/Makefile deleted file mode 100644 index 2feaab7..0000000 --- a/028_implement_strstr/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test strstr.c 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/029_divide_two_integers/Makefile b/029_divide_two_integers/Makefile deleted file mode 100644 index 0c80c5b..0000000 --- a/029_divide_two_integers/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test divide.c diff --git a/029_divide_two_integers/divide.c b/029_divide_two_integers/divide.c deleted file mode 100644 index f587cd4..0000000 --- a/029_divide_two_integers/divide.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include - -int divide(int dividend, int divisor) { - int sign = (float) dividend / divisor > 0 ? 1 : -1; - unsigned int dvd = dividend > 0 ? dividend : -dividend; - unsigned int dvs = divisor > 0 ? divisor : -divisor; - unsigned int bit_num[33]; - unsigned int i = 0; - long long d = dvs; - - bit_num[i] = d; - while (d <= dvd) { - bit_num[++i] = d = d << 1; - } - i--; - - unsigned int result = 0; - while (dvd >= dvs) { - if (dvd >= bit_num[i]) { - dvd -= bit_num[i]; - result += (1< INT_MAX && sign > 0) { - return INT_MAX; - } - return (int) result * sign; -} - -int main(int argc, char **argv) -{ - if (argc != 3) { - fprintf(stderr, "Usage: ./test dividend divisor\n"); - exit(-1); - } - printf("%d\n", divide(atoi(argv[1]), atoi(argv[2]))); - return 0; -} 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/030_substring_with_concatenation_of_all_words/Makefile b/030_substring_with_concatenation_of_all_words/Makefile deleted file mode 100644 index e9e4958..0000000 --- a/030_substring_with_concatenation_of_all_words/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test concatenation.c diff --git a/030_substring_with_concatenation_of_all_words/concatenation.c b/030_substring_with_concatenation_of_all_words/concatenation.c deleted file mode 100644 index ababaa9..0000000 --- a/030_substring_with_concatenation_of_all_words/concatenation.c +++ /dev/null @@ -1,110 +0,0 @@ -#include -#include -#include -#include - -struct word_hash { - char *word; - int freq; -}; - -static inline int BKDRHash(char *s, size_t size) -{ - int seed = 31; /* 131 1313 13131... */ - unsigned long hash = 0; - while (*s != '\0') { - hash = hash * seed + *s++; - } - return hash % size; -} - -static int find(char *word, struct word_hash *table, int size) -{ - int hash = BKDRHash(word, size); - int i = hash; - do { - if (table[i].freq > 0 && !strcmp(table[i].word, word)) { - return i; - } - i = ++i % size; - } while (i != hash); - return -1; -} - -static void add(char *word, struct word_hash *table, int size) -{ - int i, hash = BKDRHash(word, size); - for (i = hash; table[i].freq > 0 && strcmp(table[i].word, word); i = ++i % size) {} - if (table[i].freq == 0) { - table[i].word = word; - } - table[i].freq++; -} - -/** - ** Return an array of size *returnSize. - ** Note: The returned array must be malloced, assume caller calls free(). - **/ -static int *findSubstring(char *s, char **words, int wordsSize, int *returnSize) -{ - if (*s == '\0' || wordsSize == 0) { - *returnSize = 0; - return NULL; - } - - int i, j, cap = 500, count = 0; - char *start = s; - struct word_node *wn; - int hash_size = wordsSize * 2; - int len = strlen(words[0]); - char *word = malloc(len + 1); - int *indexes = malloc(cap * sizeof(int)); - int *freqs = malloc(wordsSize * sizeof(int)); - struct word_hash *table = malloc(hash_size * sizeof(*table)); - - memset(table, 0, hash_size * sizeof(*table)); - for (i = 0; i < wordsSize; i++) { - add(words[i], table, hash_size); - } - - word[len] = '\0'; - int length = len * wordsSize - 1; - while (s[length] != '\0') { - memset(freqs, 0, hash_size * sizeof(int)); - for (i = 0; i < wordsSize; i++) { - memcpy(word, s + i * len, len); - int index = find(word, table, hash_size); - if (index < 0) { - break; - } else { - if (++freqs[index] > table[index].freq) { - break; - } - } - } - - if (i == wordsSize) { - indexes[count++] = s - start; - } - s++; - } - - *returnSize = count; - return indexes; -} - -int main(int argc, char **argv) -{ - if (argc < 3) { - fprintf(stderr, "Usage: ./test str w1 w2...\n"); - exit(-1); - } - - int i, count = 0; - int *indexes = findSubstring(argv[1], argv + 2, argc - 2, &count); - for (i = 0; i < count; i++) { - printf("%d ", indexes[i]); - } - printf("\n"); - return 0; -} diff --git a/031_next_permutation/Makefile b/031_next_permutation/Makefile deleted file mode 100644 index 437189e..0000000 --- a/031_next_permutation/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test next_permutation.c diff --git a/031_next_permutation/next_permutation.c b/031_next_permutation/next_permutation.c deleted file mode 100644 index 19b0afe..0000000 --- a/031_next_permutation/next_permutation.c +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include - -static void reverse(int *a, int size) -{ - int left = 0; - int right = size - 1; - while (left < right) { - int tmp = a[left]; - a[left] = a[right]; - a[right] = tmp; - left++; - right--; - } -} - -void nextPermutation(int* nums, int numsSize) { - if (numsSize <= 1) { - return; - } - - int *p = nums + numsSize - 1; - int *q = nums + numsSize - 1; - - while (p != nums && *(p - 1) >= *p) { - p--; - } - - if (p != nums) { - int n = *(p - 1); - while (*q <= n) { - q--; - } - - int tmp = *q; - *q = *(p - 1); - *(p - 1) = tmp; - } - reverse(p, numsSize - (p - nums)); -} - -int main(int argc, char **argv) -{ - if (argc <= 1) { - fprintf(stderr, "Usage: ./test ...\n"); - exit(-1); - } - - int i; - int *nums = malloc(sizeof(int)); - for (i = 0; i < argc - 1; i++) { - nums[i] = atoi(argv[i + 1]); - } - - nextPermutation(nums, argc - 1); - - for (i = 0; i < argc - 1; i++) { - printf("%d", nums[i]); - } - putchar('\n'); - - return 0; -} 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/032_longest_valid_parentheses/Makefile b/032_longest_valid_parentheses/Makefile deleted file mode 100644 index 04fa256..0000000 --- a/032_longest_valid_parentheses/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test valid_parentheses.c diff --git a/032_longest_valid_parentheses/valid_parentheses.c b/032_longest_valid_parentheses/valid_parentheses.c deleted file mode 100644 index 525c186..0000000 --- a/032_longest_valid_parentheses/valid_parentheses.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include - -static int longestValidParentheses(char* s) { - int cap = 1, error = -1; - int length = 0, max_length = 0; - char *p = s; - int *stack = malloc(cap * sizeof(int)); - int *top = stack; - - while (*s != '\0') { - if (*s == '(') { - if (top + 1 - stack >= cap) { - cap *= 2; - stack = realloc(stack, cap * sizeof(int)); - } - *top++ = s - p; - } else { - if (top > stack) { - if (--top == stack) { - /* The stack never keep ')' so we use 'error' to record index */ - length = s - p - error; - } else { - /* The *(top - 1) is the index of the last kept '(' */ - length = s - p - *(top - 1); - } - if (length > max_length) { - max_length = length; - } - } else { - error = s - p; - } - } - s++; - } - return max_length; -} - -int main(int argc, char **argv) -{ - printf("%d\n", longestValidParentheses(argv[1])); - return 0; -} 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/033_search_in_rotated_sorted_array/Makefile b/033_search_in_rotated_sorted_array/Makefile deleted file mode 100644 index 18163ef..0000000 --- a/033_search_in_rotated_sorted_array/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test rotated_array.c diff --git a/033_search_in_rotated_sorted_array/rotated_array.c b/033_search_in_rotated_sorted_array/rotated_array.c deleted file mode 100644 index 84c32ce..0000000 --- a/033_search_in_rotated_sorted_array/rotated_array.c +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include - -static int binary_search(int *nums, int size, int target) -{ - int low = -1; - int high = size; - while (low + 1 < high) { - int mid = low + (high - low) / 2; - if (target > nums[mid]) { - low = mid; - } else { - high = mid; - } - } - if (high == size || nums[high] != target) { - return -1; - } else { - return high; - } -} - -static int start_find(int *nums, int size) -{ - int low = 0; - int high = size - 1; - while (low < high && nums[low] > nums[high]) { - int mid = low + (high - low) / 2; - if (nums[mid] > nums[high]) { - low = mid + 1; - } else if (nums[mid] < nums[low]) { - /* Assume no duplicate exists in arry */ - high = mid; - } - } - return low; -} - -static int search(int* nums, int numsSize, int target) { - if (numsSize <= 0) { - return -1; - } - if (numsSize == 1) { - return target == nums[0] ? 0 : -1; - } - - int i = start_find(nums, numsSize); - if (i == 0) { - return binary_search(nums, numsSize, target); - } else if (target >= nums[0]) { - return binary_search(nums, i, target); - } else if (target <= nums[numsSize - 1]) { - int index = binary_search(nums + i, numsSize - i, target); - return index >= 0 ? index + i : -1; - } else { - return -1; - } -} - -int main(int argc, char **argv) -{ - int i; - int target = atoi(argv[1]); - int size = argc - 2; - int *nums = malloc(size * sizeof(int)); - - for (i = 0; i < argc - 2; i++) { - nums[i] = atoi(argv[i + 2]); - } - printf("%d\n", search(nums, size, target)); - return 0; -} diff --git a/034_search_for_a_range/Makefile b/034_search_for_a_range/Makefile deleted file mode 100644 index 8660352..0000000 --- a/034_search_for_a_range/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test range_search.c 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/035_search_insert_position/Makefile b/035_search_insert_position/Makefile deleted file mode 100644 index 6a4bcfc..0000000 --- a/035_search_insert_position/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test insert_position.c diff --git a/036_valid_sudoku/Makefile b/036_valid_sudoku/Makefile deleted file mode 100644 index fcc56aa..0000000 --- a/036_valid_sudoku/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test valid_sudoku.c diff --git a/036_valid_sudoku/valid_sudoku.c b/036_valid_sudoku/valid_sudoku.c deleted file mode 100644 index 452fb2e..0000000 --- a/036_valid_sudoku/valid_sudoku.c +++ /dev/null @@ -1,139 +0,0 @@ -#include -#include -#include -#include - -struct stack { - int row; - int col; - int value; -}; - -static bool valid(char **board, int row, int col) -{ - int i, j, k; - char mark[10]; - - for (i = 0; i <= row; i++) { - memset(mark, 0, 10); - /* check row validity */ - for (j = 0; j < 9; j++) { - if (board[i][j] != '.') { - int index = board[i][j] - '0'; - if (mark[index]) { - return false; - } else { - mark[index] = 1; - } - } - } - } - - /* check column validity */ - for (i = 0; i <= col; i++) { - memset(mark, 0, 10); - for (j = 0; j < 9; j++) { - if (board[j][i] != '.') { - int index = board[j][i] - '0'; - if (mark[index]) { - return false; - } else { - mark[index] = 1; - } - } - } - } - - /* check sub-box validity */ - int count = row / 3 * 3 + col / 3 + 1; - for (k = 0; k < count; k++) { - int sr = k / 3 * 3; - int sc = (k % 3) * 3; - memset(mark, 0, 10); - for (i = sr; i < sr + 3; i++) { - for (j = sc; j < sc + 3; j++) { - if (board[i][j] != '.') { - int index = board[i][j] - '0'; - if (mark[index]) { - return false; - } else { - mark[index] = 1; - } - } - } - } - } - - return true; -} - -bool isValidSudoku(char** board, int boardRowSize, int boardColSize) { - if (boardRowSize != 9 || boardColSize != 9) { - return false; - } - - int i = 0, j = 0, k = 1, num = 0; - struct stack stack[81]; - - while (i < boardRowSize) { - if (board[i][j] == '.') { - while (k <= 9) { - board[i][j] = k + '0'; - if (valid(board, i, j)) { - stack[num].row = i; - stack[num].col = j; - stack[num].value = k; - num++; - k = 1; - break; - } - k++; - } - if (k == 10) { - if (num == 0) { - return false; - } - board[i][j] = '.'; - --num; - i = stack[num].row; - j = stack[num].col; - k = stack[num].value + 1; - board[i][j] = '.'; - continue; - } - } - /* next row */ - if (++j == boardColSize) { - j = 0; - i++; - } - } - - return true; -} - -int main(int argc, char **argv) -{ - int i, j; - char *str = argv[1]; - char **board = malloc(9 * sizeof(char *)); - for (i = 0; i < 9; i++) { - board[i] = malloc(10); - memcpy(board[i], str + i * 9, 9); - board[9] = '\0'; - char *row = board[i]; - for (j = 0; j < 9; j++) { - printf("%c ", row[j]); - } - printf("\n"); - } - printf("%s\n", isValidSudoku(board, 9, 9) ? "true" : "false"); - for (i = 0; i < 9; i++) { - char *row = board[i]; - for (j = 0; j < 9; j++) { - printf("%c ", row[j]); - } - printf("\n"); - } - return; -} diff --git a/037_sudoku_solver/Makefile b/037_sudoku_solver/Makefile deleted file mode 100644 index debabd7..0000000 --- a/037_sudoku_solver/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test sudoku_solver.c diff --git a/038_count_and_say/Makefile b/038_count_and_say/Makefile deleted file mode 100644 index 27b8e9a..0000000 --- a/038_count_and_say/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test count_and_say.c diff --git a/039_combination_sum/Makefile b/039_combination_sum/Makefile deleted file mode 100644 index e5462fa..0000000 --- a/039_combination_sum/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test combination_sum.c diff --git a/039_combination_sum/combination_sum.c b/039_combination_sum/combination_sum.c deleted file mode 100644 index 2687ff5..0000000 --- a/039_combination_sum/combination_sum.c +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include - -static void insert_sort(int *a, int size) -{ - int i, j; - for (i = 1; i < size; i++) { - int tmp = a[i]; - for (j = i - 1; j >= 0 && tmp < a[j]; j--) { - a[j + 1] = a[j]; - } - a[j + 1] = tmp; - } -} - -static void combination_recursive(int *nums, int size, int start, int target, - int *solution, int len, - int **results, int *column_sizes, int *count) -{ - int i; - if (target > 0) { - for (i = start; i < size; i++) { - if (i > 0 && nums[i] == nums[i - 1]) { - continue; - } - /* You may dump the content of the solution here, and you would find - * the order of element represents the number of nested layers, and - * the element at the specific order represents the iteration from - * the start in the current recursive layer. - */ - solution[len++] = nums[i]; - combination_recursive(nums, size, i, target - nums[i], solution, len, results, column_sizes, count); - len--; - } - } else if (target == 0) { - results[*count] = malloc(len * sizeof(int)); - memcpy(results[*count], solution, len * sizeof(int)); - column_sizes[*count] = len; - (*count)++; - } -} - -/** - ** 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(). - **/ -int** combinationSum(int* candidates, int candidatesSize, int target, int** columnSizes, int* returnSize) { - insert_sort(candidates, candidatesSize); - - int *solution = malloc(target * sizeof(int)); - int **results = malloc(100 * sizeof(int *)); - *columnSizes = malloc(100 * sizeof(int)); - *returnSize = 0; - combination_recursive(candidates, candidatesSize, 0, target, solution, 0, results, *columnSizes, returnSize); - return results; - //for (i = 0; i < candidatesSize; i++) { - // //int *columns = malloc(); - // for (j = 1; candidates[i] * j < target, j++) { - // for (k = i + 1; k < candidatesSize; k++) { - // - // } - // int remain = target - candidates[i] * j; - // if (remain == 0) { - // int *column = malloc(sizeof(int)); - // if (count + 1 >= cap) { - // cap *= 2; - // columnSizes = realloc(columnSizes, cap * sizeof(int *)); - // } - // columnSizes[count++] = column; - // } else { - // k = i + 1; - // } - // } - //} -} - -int main(int argc, char **argv) -{ - if (argc <= 2) { - fprintf(stderr, "Usage: ./test target array...\n"); - exit(-1); - } - - int i, j, count = 0; - int target = atoi(argv[1]); - int *nums = malloc((argc - 2) * sizeof(int)); - for (i = 0; i < argc - 2; i++) { - nums[i] = atoi(argv[i + 2]); - } - - int *sizes; - int **lists = combinationSum(nums, argc - 2, target, &sizes, &count); - for (i = 0; i < count; i++) { - for (j = 0; j < sizes[i]; j++) { - printf("%d ", lists[i][j]); - } - printf("\n"); - } - return 0; -} diff --git a/040_combination_sum_ii/Makefile b/040_combination_sum_ii/Makefile deleted file mode 100644 index e5462fa..0000000 --- a/040_combination_sum_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test combination_sum.c diff --git a/040_combination_sum_ii/combination_sum.c b/040_combination_sum_ii/combination_sum.c deleted file mode 100644 index 52f3083..0000000 --- a/040_combination_sum_ii/combination_sum.c +++ /dev/null @@ -1,91 +0,0 @@ -#include -#include -#include -#include - -static bool exist(int **results, int count, int *solution, int len) -{ - int i; - for (i = 0; i < count; i++) { - if (!memcmp(results[i], solution, len * sizeof(int))) { - return true; - } - } - return false; -} - -static void insert_sort(int *a, int size) -{ - int i, j; - for (i = 1; i < size; i++) { - int tmp = a[i]; - for (j = i - 1; j >= 0 && tmp < a[j]; j--) { - a[j + 1] = a[j]; - } - a[j + 1] = tmp; - } -} - -static void combination_recursive(int *nums, int size, int start, int target, - int *solution, int len, - int **results, int *column_sizes, int *count) -{ - int i; - if (target > 0) { - for (i = start; i < size; i++) { - /* You may dump the content of the solution here, and you would find - * the order of element represents the number of nested layers, and - * the element at the specific order represents the iteration from - * the start in the current recursive layer. - */ - solution[len++] = nums[i]; - combination_recursive(nums, size, i + 1, target - nums[i], solution, - len, results, column_sizes, count); - len--; - } - } else if (target == 0) { - if (!exist(results, *count, solution, len)) { - results[*count] = malloc(len * sizeof(int)); - memcpy(results[*count], solution, len * sizeof(int)); - column_sizes[*count] = len; - (*count)++; - } - } -} - -/** - ** 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(). - **/ -static int** combinationSum(int* candidates, int candidatesSize, int target, int** columnSizes, int* returnSize) -{ - insert_sort(candidates, candidatesSize); - - int *solution = malloc(target * sizeof(int)); - int **results = malloc(100 * sizeof(int *)); - *columnSizes = malloc(100 * sizeof(int)); - *returnSize = 0; - combination_recursive(candidates, candidatesSize, 0, target, solution, 0, results, *columnSizes, returnSize); - return results; -} - -int main(int argc, char **argv) -{ - int i, j, count = 0; - int target = atoi(argv[1]); - int *nums = malloc((argc - 2) * sizeof(int)); - for (i = 0; i < argc - 2; i++) { - nums[i] = atoi(argv[i + 2]); - } - - int *sizes; - int **lists = combinationSum(nums, argc - 2, target, &sizes, &count); - for (i = 0; i < count; i++) { - for (j = 0; j < sizes[i]; j++) { - printf("%d ", lists[i][j]); - } - printf("\n"); - } - return 0; -} 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/041_first_missing_positive/Makefile b/041_first_missing_positive/Makefile deleted file mode 100644 index 4c24d01..0000000 --- a/041_first_missing_positive/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test missing_positive.c diff --git a/042_trapping_rain_water/Makefile b/042_trapping_rain_water/Makefile deleted file mode 100644 index 8d38674..0000000 --- a/042_trapping_rain_water/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test trap_water.c diff --git a/042_trapping_rain_water/trap_water.c b/042_trapping_rain_water/trap_water.c deleted file mode 100644 index a7d5b30..0000000 --- a/042_trapping_rain_water/trap_water.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include - -static int trap(int* height, int heightSize) { - if (heightSize < 2) { - return 0; - } - - int i, j, top0 = -1, top1 = -1, sum = 0, level = 0; - for (i = 0; i < heightSize; i++) { - if (height[i] > 0) { - top0 = i; - break; - } - } - - while (i < heightSize) { - top1 = -1; - for (j = i + 1; j < heightSize; j++) { - if (height[j] >= height[j - 1]) { - if (top1 < 0 || height[j] >= height[top1]) { - top1 = j; - } - if (height[j] >= height[top0]) { - break; - } - } - } - - if (top1 >= 0) { - int level = height[top0] < height[top1] ? height[top0] : height[top1]; - while (i < top1) { - if (level > height[i]) { - sum += level - height[i]; - } - i++; - } - top0 = top1; - i = top1; - } else { - i = j; - } - } - - return sum; -} - -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/Makefile b/043_multiply_strings/Makefile deleted file mode 100644 index b90103f..0000000 --- a/043_multiply_strings/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test multiply_strings.c diff --git a/043_multiply_strings/multiply_strings.c b/043_multiply_strings/multiply_strings.c deleted file mode 100644 index be32919..0000000 --- a/043_multiply_strings/multiply_strings.c +++ /dev/null @@ -1,67 +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/Makefile b/044_wildcard_matching/Makefile deleted file mode 100644 index 9543392..0000000 --- a/044_wildcard_matching/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test wildcard_matching.c 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/Makefile b/045_jump_game_ii/Makefile deleted file mode 100644 index e39cccc..0000000 --- a/045_jump_game_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test jump_game.c diff --git a/045_jump_game_ii/jump_game.c b/045_jump_game_ii/jump_game.c deleted file mode 100644 index 53a8128..0000000 --- a/045_jump_game_ii/jump_game.c +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include - -static int jump(int* nums, int numsSize) { - if (numsSize <= 1) { - return 0; - } - - int i; - int pos = numsSize - 1; - int *indexes = malloc(numsSize * sizeof(int)); - int *p = indexes; - - *p++ = numsSize - 1; - while (--pos >= 0) { - for (i = 0; i < p - indexes; i++) { - if (nums[pos] >= indexes[i] - pos) { - indexes[i + 1] = pos; - p = indexes + i + 2; - break; - } - } - } - - return p - indexes - 1; -} - -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/046_permutations/Makefile b/046_permutations/Makefile deleted file mode 100644 index 25f7501..0000000 --- a/046_permutations/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test permutations.c diff --git a/046_permutations/permutations.c b/046_permutations/permutations.c deleted file mode 100644 index 7eb4c9e..0000000 --- a/046_permutations/permutations.c +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include - -static void reverse(int *a, int size) -{ - int left = 0; - int right = size - 1; - while (left < right) { - int tmp = a[left]; - a[left] = a[right]; - a[right] = tmp; - left++; - right--; - } -} - -static void next_permute(int* nums, int numsSize) { - if (numsSize <= 1) { - return; - } - - int *p = nums + numsSize - 1; - int *q = nums + numsSize - 1; - - while (p != nums && *(p - 1) >= *p) { - p--; - } - - if (p != nums) { - int n = *(p - 1); - while (*q <= n) { - q--; - } - - int tmp = *q; - *q = *(p - 1); - *(p - 1) = tmp; - } - reverse(p, numsSize - (p - nums)); -} - -/** - ** Return an array of arrays of size *returnSize. - ** Note: The returned array must be malloced, assume caller calls free(). - **/ -static int** permute(int* nums, int numsSize, int* returnSize) { - if (numsSize == 0) { - return NULL; - } - - int i, count = 1, size = numsSize; - while (size > 0) { - count *= size--; - } - - int **permutations = malloc(count * sizeof(int *)); - permutations[0] = malloc(numsSize * sizeof(int)); - memcpy(permutations[0], nums, numsSize * sizeof(int)); - for (i = 1; i < count; i++) { - permutations[i] = malloc(numsSize * sizeof(int)); - memcpy(permutations[i], permutations[i - 1], numsSize * sizeof(int)); - next_permute(permutations[i], numsSize); - } - - *returnSize = count; - return permutations; -} - -int main(int argc, char **argv) -{ - if (argc <= 1) { - fprintf(stderr, "Usage: ./test ...\n"); - exit(-1); - } - - int i, j, count; - int *nums = malloc(sizeof(int)); - for (i = 0; i < argc - 1; i++) { - nums[i] = atoi(argv[i + 1]); - } - - int **lists = permute(nums, argc - 1, &count); - - for (i = 0; i < count; i++) { - for (j = 0; j < argc - 1; j++) { - printf("%d", lists[i][j]); - } - putchar('\n'); - } - - return 0; -} diff --git a/047_permutations_II/Makefile b/047_permutations_II/Makefile deleted file mode 100644 index 35f7ea7..0000000 --- a/047_permutations_II/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test permutations_unique.c diff --git a/047_permutations_II/permutations_unique.c b/047_permutations_II/permutations_unique.c deleted file mode 100644 index e51b695..0000000 --- a/047_permutations_II/permutations_unique.c +++ /dev/null @@ -1,99 +0,0 @@ -#include -#include -#include - -static void reverse(int *a, int size) -{ - int left = 0; - int right = size - 1; - while (left < right) { - int tmp = a[left]; - a[left] = a[right]; - a[right] = tmp; - left++; - right--; - } -} - -static void next_permute(int* nums, int numsSize) { - if (numsSize <= 1) { - return; - } - - int *p = nums + numsSize - 1; - int *q = nums + numsSize - 1; - - while (p != nums && *(p - 1) >= *p) { - p--; - } - - if (p != nums) { - int n = *(p - 1); - while (*q <= n) { - q--; - } - - int tmp = *q; - *q = *(p - 1); - *(p - 1) = tmp; - } - reverse(p, numsSize - (p - nums)); -} - -/** - ** Return an array of arrays of size *returnSize. - ** Note: The returned array must be malloced, assume caller calls free(). - **/ -static int** permute_unique(int* nums, int numsSize, int* returnSize) { - if (numsSize == 0) { - return NULL; - } - - int cap = 1, count = 0, stop = 0; - int **permutations = malloc(cap * sizeof(int *)); - permutations[count] = malloc(numsSize * sizeof(int)); - memcpy(permutations[count], nums, numsSize * sizeof(int)); - count++; - - while (!stop) { - int *permutation = malloc(numsSize * sizeof(int)); - memcpy(permutation, permutations[count - 1], numsSize * sizeof(int)); - next_permute(permutation, numsSize); - if (memcmp(permutation, nums, numsSize * sizeof(int))) { - if (count + 1 >= cap) { - cap *= 2; - permutations = realloc(permutations, cap * sizeof(int *)); - } - permutations[count++] = permutation; - } else { - stop = 1; - } - } - - *returnSize = count; - return permutations; -} - -int main(int argc, char **argv) -{ - if (argc <= 1) { - fprintf(stderr, "Usage: ./test ...\n"); - exit(-1); - } - - int i, j, count; - int *nums = malloc(sizeof(int)); - for (i = 0; i < argc - 1; i++) { - nums[i] = atoi(argv[i + 1]); - } - - int **lists = permute_unique(nums, argc - 1, &count); - for (i = 0; i < count; i++) { - for (j = 0; j < argc - 1; j++) { - printf("%d", lists[i][j]); - } - putchar('\n'); - } - - return 0; -} diff --git a/048_rotate_image/Makefile b/048_rotate_image/Makefile deleted file mode 100644 index 152b201..0000000 --- a/048_rotate_image/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test rotate.c diff --git a/048_rotate_image/rotate.c b/048_rotate_image/rotate.c deleted file mode 100644 index a332eef..0000000 --- a/048_rotate_image/rotate.c +++ /dev/null @@ -1,48 +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++; - } - } - - 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/049_group_anagrams/Makefile b/049_group_anagrams/Makefile deleted file mode 100644 index 787d9da..0000000 --- a/049_group_anagrams/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test anagrams.c diff --git a/049_group_anagrams/anagrams.c b/049_group_anagrams/anagrams.c deleted file mode 100644 index 7e225e8..0000000 --- a/049_group_anagrams/anagrams.c +++ /dev/null @@ -1,143 +0,0 @@ -#include -#include -#include - -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 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 word_node { - struct hlist_node node; - int index; -}; - -struct word_hash { - struct hlist_head head; - char *word; - int num; -}; - -static void insert_sort(char *s, int len) -{ - int i, j; - for (i = 1; i < len; i++) { - char tmp = s[i]; - j = i - 1; - for (; j >= 0 && s[j] > tmp; j--) { - s[j + 1] = s[j]; - } - s[j + 1] = tmp; - } -} - -static inline int BKDRHash(char *s, size_t size) -{ - int seed = 31; /* 131 1313 13131... */ - unsigned long hash = 0; - while (*s != '\0') { - hash = hash * seed + *s++; - } - return hash % 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(). - **/ -static char*** groupAnagrams(char** strs, int strsSize, int** columnSizes, int* returnSize) { - int i, j, count = 0; - struct word_node *wn; - - int hash_size = strsSize; - struct word_hash *ht = malloc(hash_size * sizeof(*ht)); - for (i = 0; i < hash_size; i++) { - INIT_HLIST_HEAD(&ht[i].head); - ht[i].num = 0; - } - - char **words = malloc(strsSize * sizeof(char *)); - for (i = 0; i < strsSize; i++) { - int len = strlen(strs[i]); - words[i] = malloc(len + 1); - strcpy(words[i], strs[i]); - insert_sort(words[i], len); - 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) {} - wn = malloc(sizeof(*wn)); - wn->index = i; - if (ht[j].num == 0) { - ht[j].word = words[i]; - count++; - } - hlist_add_head(&wn->node, &ht[j].head); - ht[j].num++; - } - - j = 0; - struct hlist_node *p; - char ***lists = malloc(count * sizeof(char **)); - *columnSizes = malloc(count * sizeof(int)); - for (i = 0; i < hash_size; i++) { - if (ht[i].num > 0) { - (*columnSizes)[j] = ht[i].num; - lists[j] = malloc(ht[i].num * sizeof(char *)); - int k = 0; - hlist_for_each(p, &ht[i].head) { - wn = list_entry(p, struct word_node, node); - lists[j][k++] = strs[wn->index]; - } - j++; - } - } - - *returnSize = count; - return lists; -} - -int main(int argc, char **argv) -{ - int *column_sizes, count = 0, i, j; - char ***lists = groupAnagrams(argv + 1, argc - 1, &column_sizes, &count); - for (i = 0; i < count; i++) { - for (j = 0; j < column_sizes[i]; j++) { - printf("%s ", lists[i][j]); - } - printf("\n"); - } - return 0; -} diff --git a/050_pow/Makefile b/050_pow/Makefile deleted file mode 100644 index 59054b3..0000000 --- a/050_pow/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test pow.c diff --git a/050_pow/pow.c b/050_pow/pow.c deleted file mode 100644 index 68c9fa9..0000000 --- a/050_pow/pow.c +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include -#include - -/* - * n == 2(10) -- 2 -- res = 1 * 2^2 - * n == 3(11) -- 2 + 1 -- res = 1 * 2^1 * 2^2 - * n == 4(100) -- 4 -- res = 1 * 2^4 - * n == 5(101) -- 4 + 1 -- res = 1 * 2^1 * 2^4 - * n == 6(110) -- 4 + 2 + 1 -- res = 1 * 2^1 * 2^2 * 2^4 - */ -static double my_pow(double x, int n) -{ - int orig = x; - int sign = 0; - int one_more = 0; - if (n < 0) { - if (n == INT_MIN) { - n = INT_MAX; - one_more = 1; - } else { - n = -n; - } - sign = 1; - } - - double res = 1; - while (n > 0) { - if (n & 0x1) { - res *= x; - } - x *= x; - n >>= 1; - } - if (one_more) { - res *= orig; - } - - return sign ? 1 / res : res; -} - -int main(int argc, char **argv) -{ - if (argc != 3) { - fprintf(stderr, "Usage: ./test x n\n"); - exit(-1); - } - printf("%lf\n", my_pow(atoi(argv[1]), atoi(argv[2]))); - 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/0518_coin_change_ii/Makefile b/0518_coin_change_ii/Makefile new file mode 100644 index 0000000..a766ed4 --- /dev/null +++ b/0518_coin_change_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O1 -o test coin_change.c diff --git a/0518_coin_change_ii/coin_change.c b/0518_coin_change_ii/coin_change.c new file mode 100644 index 0000000..d119fcb --- /dev/null +++ b/0518_coin_change_ii/coin_change.c @@ -0,0 +1,44 @@ +#include +#include + + +int change(int amount, int* coins, int coinsSize) +{ + int i, j; + unsigned int **dp = malloc((coinsSize + 1) * sizeof(unsigned int *)); + + for (i = 0; i <= coinsSize; i++) { + dp[i] = calloc(amount + 1, sizeof(unsigned int)); + dp[i][0] = 1; + } + + for (i = 1; i <= coinsSize; i++) { + for (j = 1; j <= amount; j++) { + if (j - coins[i - 1] >= 0) { + dp[i][j] = dp[i - 1][j] + dp[i][j - coins[i - 1]]; + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + + return dp[coinsSize][amount]; +} + +int main(int argc, char **argv) +{ + if (argc < 3) { + fprintf(stderr, "Usage: ./test 11 1 2 5"); + exit(-1); + } + + int amount = atoi(argv[1]); + int i, size = argc - 2; + int *coins = malloc(size * sizeof(int)); + for (i = 0; i < size; i++) { + coins[i] = atoi(argv[i + 2]); + } + printf("%d\n", change(amount, coins, size)); + + return 0; +} diff --git a/0518_coin_change_ii/coin_change.cc b/0518_coin_change_ii/coin_change.cc new file mode 100644 index 0000000..5282ef3 --- /dev/null +++ b/0518_coin_change_ii/coin_change.cc @@ -0,0 +1,24 @@ +#include + +using namespace std; + +class Solution { +public: + int change(int amount, vector& coins) { + vector> dp(coins.size() + 1, vector(amount + 1)); + for (int i = 0; i <= coins.size(); i++) { + dp[i][0] = 1; + } + + for (int i = 1; i <= coins.size(); i++) { + for (int j = 1; j <= amount; j++) { + if (j >= coins[i - 1]) { + dp[i][j] = dp[i - 1][j] + dp[i][j - coins[i - 1]]; + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + return dp[coins.size()][amount]; + } +}; diff --git a/051_n_queens/Makefile b/051_n_queens/Makefile deleted file mode 100644 index 74f9e03..0000000 --- a/051_n_queens/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o queen n_queens.c diff --git a/052_n_queens/Makefile b/052_n_queens/Makefile deleted file mode 100644 index 74f9e03..0000000 --- a/052_n_queens/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o queen n_queens.c diff --git a/053_maximum_subarray/Makefile b/053_maximum_subarray/Makefile deleted file mode 100644 index 32c2032..0000000 --- a/053_maximum_subarray/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test max_subarray.c 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/054_spiral_matrix/Makefile b/054_spiral_matrix/Makefile deleted file mode 100644 index 273c67f..0000000 --- a/054_spiral_matrix/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test spiral_matrix.c diff --git a/055_jump_game/Makefile b/055_jump_game/Makefile deleted file mode 100644 index e39cccc..0000000 --- a/055_jump_game/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test jump_game.c diff --git a/055_jump_game/jump_game.c b/055_jump_game/jump_game.c deleted file mode 100644 index 8d4e5b0..0000000 --- a/055_jump_game/jump_game.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include -#include - -static bool canJump(int* nums, int numsSize) { - if (numsSize == 0) return false; - - int i = numsSize - 1, j; - while (i > 0) { - if (nums[--i] == 0) { - for (j = i - 1; j >= 0; j--) { - if (nums[j] > i - j) { - break; - } - } - if (j == -1) { - return false; - } - } - } - - return true; -} - -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("%s\n", canJump(nums, count) ? "true" : "false"); - return 0; -} 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..1061ae6 --- /dev/null +++ b/0567_permutation_in_string/permutation_in_string.cc @@ -0,0 +1,33 @@ +#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, hits = 0; + while (r < s2.length()) { + if (--count[s2[r++]] >= 0) { + hits++; + } + + // When the window length equals to the hit length, + // the permutation is contained. + if (r - l >= s1.length()) { + if (hits == s1.length()) { + return true; + } + if (++count[s2[l++]] > 0) { + hits--; + } + } + } + + return false; + } +}; diff --git a/056_merge_intervals/Makefile b/056_merge_intervals/Makefile deleted file mode 100644 index 9b568bc..0000000 --- a/056_merge_intervals/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test merge_intervals.c diff --git a/056_merge_intervals/merge_intervals.c b/056_merge_intervals/merge_intervals.c deleted file mode 100644 index a07096d..0000000 --- a/056_merge_intervals/merge_intervals.c +++ /dev/null @@ -1,151 +0,0 @@ -#include -#include -#include - -struct Interval { - int start; - int end; -}; - -static int binary_search(int *nums, int size, int target) -{ - int low = -1; - int high = size; - while (low + 1 < high) { - int mid = low + (high - low) / 2; - if (target > nums[mid]) { - low = mid; - } else { - high = mid; - } - } - if (high == size || nums[high] != target) { - return -high - 1; - } else { - return high; - } -} - -/** - ** Return an array of size *returnSize. - ** Note: The returned array must be malloced, assume caller calls free(). - **/ -static struct Interval* insert(struct Interval* intervals, int intervalsSize, struct Interval newInterval, int* returnSize) -{ - struct Interval *p; - if (intervalsSize == 0) { - p = malloc(sizeof(*p)); - p->start = newInterval.start; - p->end = newInterval.end; - *returnSize = 1; - return p; - } - - int i, count; - int *nums = malloc(2 * intervalsSize * sizeof(int)); - for (i = 0; i < intervalsSize; i++) { - nums[i * 2] = intervals[i].start; - nums[i * 2 + 1] = intervals[i].end; - } - - int start0 = binary_search(nums, 2 * intervalsSize, newInterval.start); - int end0 = binary_search(nums, 2 * intervalsSize, newInterval.end); - - int start1 = -1, end1 = -1; - int merge_start= -1, merge_end = -1; - if (start0 >= 0) { - merge_start = start0 / 2; - } else { - start1 = -start0 - 1; - merge_start = start1 / 2; - } - - if (end0 >= 0) { - merge_end = end0 / 2; - } else { - end1 = -end0 - 1; - if (end1 % 2 == 0) { - merge_end = end1 / 2 > 0 ? end1 / 2 - 1 : 0; - } else { - merge_end = end1 / 2; - } - } - - if (merge_start == merge_end) { - if (start0 < 0 && end0 < 0 && start1 == end1 && start1 % 2 == 0) { - count = intervalsSize + 1; - p = malloc(count * sizeof(*p)); - memcpy(p, intervals, merge_start * sizeof(*p)); - p[merge_start] = newInterval; - memcpy(p + merge_start + 1, intervals + merge_start, (intervalsSize - merge_start) * sizeof(*p)); - } else { - count = intervalsSize; - p = malloc(count * sizeof(*p)); - memcpy(p, intervals, count * sizeof(*p)); - if (start0 < 0 && start1 % 2 == 0) { - p[merge_start].start = newInterval.start; - } - if (end0 < 0 && end1 % 2 == 0) { - p[merge_end].end = newInterval.end; - } - } - } else { - count = intervalsSize - (merge_end - merge_start); - p = malloc(count * sizeof(*p)); - memcpy(p, intervals, merge_start * sizeof(*p)); - memcpy(p + merge_start, intervals + merge_end, (intervalsSize - merge_end) * sizeof(*p)); - if (start0 < 0 && start1 % 2 == 0) { - p[merge_start].start = newInterval.start; - } else { - p[merge_start].start = intervals[merge_start].start; - } - if (end0 < 0 && end1 % 2 == 0) { - p[merge_start].end = newInterval.end; - } else { - p[merge_start].end = intervals[merge_end].end; - } - } - - free(nums); - free(intervals); - *returnSize = count; - return p; -} - -/** - * * Return an array of size *returnSize. - * * Note: The returned array must be malloced, assume caller calls free(). - * */ -struct Interval* merge(struct Interval* intervals, int intervalsSize, int* returnSize) { - int i, count = 0; - struct Interval *p = NULL; - for (i = 0; i < intervalsSize; i++) { - p = insert(p, count, intervals[i], &count); - } - *returnSize = count; - return p; -} - -int main(int argc, char **argv) -{ - if (argc < 1|| argc % 2 == 0) { - fprintf(stderr, "Usage: ./test s0 e0 s1 e1..."); - exit(-1); - } - - int i, count = 0; - struct Interval *intervals = malloc((argc - 1) / 2 * sizeof(struct Interval)); - struct Interval *p = intervals; - for (i = 1; i < argc; i += 2) { - p->start = atoi(argv[i]); - p->end = atoi(argv[i + 1]); - p++; - } - - struct Interval *q = merge(intervals, (argc - 1) / 2, &count); - for (i = 0; i < count; i++) { - printf("[%d, %d]\n", q->start, q->end); - q++; - } - return 0; -} diff --git a/057_insert_interval/Makefile b/057_insert_interval/Makefile deleted file mode 100644 index bc9dd24..0000000 --- a/057_insert_interval/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test insert_interval.c diff --git a/057_insert_interval/insert_interval.c b/057_insert_interval/insert_interval.c deleted file mode 100644 index fd29352..0000000 --- a/057_insert_interval/insert_interval.c +++ /dev/null @@ -1,139 +0,0 @@ -#include -#include -#include - -struct Interval { - int start; - int end; -}; - -static int binary_search(int *nums, int size, int target) -{ - int low = -1; - int high = size; - while (low + 1 < high) { - int mid = low + (high - low) / 2; - if (target > nums[mid]) { - low = mid; - } else { - high = mid; - } - } - if (high == size || nums[high] != target) { - return -high - 1; - } else { - return high; - } -} - -/** - ** Return an array of size *returnSize. - ** Note: The returned array must be malloced, assume caller calls free(). - **/ -static struct Interval* insert(struct Interval* intervals, int intervalsSize, struct Interval newInterval, int* returnSize) { - struct Interval *p; - if (intervalsSize == 0) { - p = malloc(sizeof(*p)); - p->start = newInterval.start; - p->end = newInterval.end; - *returnSize = 1; - return p; - } - - int i, count; - int *nums = malloc(2 * intervalsSize * sizeof(int)); - for (i = 0; i < intervalsSize; i++) { - nums[i * 2] = intervals[i].start; - nums[i * 2 + 1] = intervals[i].end; - } - - int start0 = binary_search(nums, 2 * intervalsSize, newInterval.start); - int end0 = binary_search(nums, 2 * intervalsSize, newInterval.end); - - int start1 = -1, end1 = -1; - int merge_start= -1, merge_end = -1; - if (start0 >= 0) { - merge_start = start0 / 2; - } else { - start1 = -start0 - 1; - merge_start = start1 / 2; - } - - if (end0 >= 0) { - merge_end = end0 / 2; - } else { - end1 = -end0 - 1; - if (end1 % 2 == 0) { - merge_end = end1 / 2 > 0 ? end1 / 2 - 1 : 0; - } else { - merge_end = end1 / 2; - } - } - - if (merge_start == merge_end) { - if (start0 < 0 && end0 < 0 && start1 == end1 && start1 % 2 == 0) { - count = intervalsSize + 1; - p = malloc(count * sizeof(*p)); - memcpy(p, intervals, merge_start * sizeof(*p)); - p[merge_start] = newInterval; - memcpy(p + merge_start + 1, intervals + merge_start, (intervalsSize - merge_start) * sizeof(*p)); - } else { - count = intervalsSize; - p = malloc(count * sizeof(*p)); - memcpy(p, intervals, count * sizeof(*p)); - if (start0 < 0 && start1 % 2 == 0) { - p[merge_start].start = newInterval.start; - } - if (end0 < 0 && end1 % 2 == 0) { - p[merge_end].end = newInterval.end; - } - } - } else { - count = intervalsSize - (merge_end - merge_start); - p = malloc(count * sizeof(*p)); - memcpy(p, intervals, merge_start * sizeof(*p)); - memcpy(p + merge_start, intervals + merge_end, (intervalsSize - merge_end) * sizeof(*p)); - if (start0 < 0 && start1 % 2 == 0) { - p[merge_start].start = newInterval.start; - } else { - p[merge_start].start = intervals[merge_start].start; - } - if (end0 < 0 && end1 % 2 == 0) { - p[merge_start].end = newInterval.end; - } else { - p[merge_start].end = intervals[merge_end].end; - } - } - - free(nums); - *returnSize = count; - return p; -} - -int main(int argc, char **argv) -{ - if (argc < 3 || argc % 2 == 0) { - fprintf(stderr, "Usage: ./test new_s new_e s0 e0 s1 e1..."); - exit(-1); - } - - struct Interval new_interv; - new_interv.start = atoi(argv[1]); - new_interv.end = atoi(argv[2]); - - int i, count = 0; - struct Interval *intervals = malloc((argc - 3) / 2 * sizeof(struct Interval)); - struct Interval *p = intervals; - for (i = 3; i < argc; i += 2) { - p->start = atoi(argv[i]); - p->end = atoi(argv[i + 1]); - p++; - } - - struct Interval *q = insert(intervals, (argc - 3) / 2, new_interv, &count); - for (i = 0; i < count; i++) { - printf("[%d, %d]\n", q->start, q->end); - q++; - } - return 0; -} diff --git a/058_length_of_last_word/Makefile b/058_length_of_last_word/Makefile deleted file mode 100644 index fe49695..0000000 --- a/058_length_of_last_word/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test word_length.c diff --git a/059_spiral_matrix_ii/Makefile b/059_spiral_matrix_ii/Makefile deleted file mode 100644 index 273c67f..0000000 --- a/059_spiral_matrix_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test spiral_matrix.c diff --git a/060_permutation_sequence/Makefile b/060_permutation_sequence/Makefile deleted file mode 100644 index 21302bd..0000000 --- a/060_permutation_sequence/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test permutation_sequence.c diff --git a/060_permutation_sequence/permutation_sequence.c b/060_permutation_sequence/permutation_sequence.c deleted file mode 100644 index 983b1a7..0000000 --- a/060_permutation_sequence/permutation_sequence.c +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include - -static void reverse(int *a, int size) -{ - int left = 0; - int right = size - 1; - while (left < right) { - int tmp = a[left]; - a[left] = a[right]; - a[right] = tmp; - left++; - right--; - } -} - -void nextPermutation(int* nums, int numsSize) { - if (numsSize <= 1) { - return; - } - - int *p = nums + numsSize - 1; - int *q = nums + numsSize - 1; - - while (p != nums && *(p - 1) >= *p) { - p--; - } - - if (p != nums) { - int n = *(p - 1); - while (*q <= n) { - q--; - } - - int tmp = *q; - *q = *(p - 1); - *(p - 1) = tmp; - } - reverse(p, numsSize - (p - nums)); -} - -static char* getPermutation(int n, int k) { - int i; - int *permutation = malloc(n * sizeof(int)); - for (i = 0; i < n; i++) { - permutation[i] = i + 1; - } - while (--k > 0) { - nextPermutation(permutation, n); - } - char *result = malloc(n + 1); - for (i = 0; i < n; i++) { - result[i] = permutation[i] + '0'; - } - result[n] = '\0'; - free(permutation); - return result; -} - -int main(int argc, char **argv) -{ - if (argc != 3) { - fprintf(stderr, "Usage: ./test n, k\n"); - exit(-1); - } - - printf("%s\n", getPermutation(atoi(argv[1]), atoi(argv[2]))); - return 0; -} diff --git a/061_rotate_list/Makefile b/061_rotate_list/Makefile deleted file mode 100644 index dd0aef9..0000000 --- a/061_rotate_list/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test rotate_list.c diff --git a/062_unique_path/Makefile b/062_unique_path/Makefile deleted file mode 100644 index 63953c4..0000000 --- a/062_unique_path/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test unique_path.c diff --git a/062_unique_path/unique_path.c b/062_unique_path/unique_path.c deleted file mode 100644 index b7dd848..0000000 --- a/062_unique_path/unique_path.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include - -static void valid_path_recursive(int col, int m, int row, int n, int *count) -{ - if (col == m - 1 && row == n - 1) { - (*count)++; - } else { - if (m > n) { - if (col < m - 1) { - valid_path(col + 1, m, row, n, count); - } - if (row < n - 1) { - valid_path(col, m, row + 1, n, count); - } - } else { - if (col < m - 1) { - valid_path(col + 1, m, row, n, count); - } - if (row < n - 1) { - valid_path(col, m, row + 1, n, count); - } - } - } -} - -static int uniquePaths(int m, int n) { - //int count = 0; - //valid_path(0, m, 0, n, &count); - //return count; - int row, col; - int *grids = malloc(m * n * sizeof(int)); - for (col = 0; col < m; col++) { - grids[col] = 1; - } - for (row = 0; row < n; row++) { - grids[row * m] = 1; - } - for (row = 1; row < n; row++) { - for (col = 1; col < m; col++) { - grids[row * m + col] = grids[row * m + col - 1] + grids[(row - 1) * m + col]; - } - } - int result = grids[m * n - 1]; - free(grids); - return result; -} - -int main(int argc, char **argv) -{ - if (argc != 3) { - fprintf(stderr, "Usage: ./test m n\n"); - exit(-1); - } - printf("%d\n", uniquePaths(atoi(argv[1]), atoi(argv[2]))); - return 0; -} diff --git a/063_unique_paths_ii/Makefile b/063_unique_paths_ii/Makefile deleted file mode 100644 index 63953c4..0000000 --- a/063_unique_paths_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test unique_path.c diff --git a/064_minumum_path_sum/Makefile b/064_minumum_path_sum/Makefile deleted file mode 100644 index a70641a..0000000 --- a/064_minumum_path_sum/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test minimum_path_sum.c diff --git a/065_valid_number/Makefile b/065_valid_number/Makefile deleted file mode 100644 index bef5548..0000000 --- a/065_valid_number/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test valid_number.c diff --git a/065_valid_number/valid_number.c b/065_valid_number/valid_number.c deleted file mode 100644 index 36a0c5e..0000000 --- a/065_valid_number/valid_number.c +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include - -static bool isNumber(const char *s) { - bool point = false; - bool hasE = false; - - //trim the space - while(isspace(*s)) s++; - //check empty - if (*s == '\0' ) return false; - //check sign - if (*s=='+' || *s=='-') s++; - - const char *head = s; - for(; *s!='\0'; s++){ - // if meet point - if ( *s == '.' ){ - if ( hasE == true || point == true){ - return false; - } - if ( s == head && !isdigit(*(s+1)) ){ - return false; - } - point = true; - continue; - } - //if meet "e" - if ( *s == 'e' ){ - if ( hasE == true || s == head) { - return false; - } - s++; - if ( *s=='+' || *s=='-' ) s++; - if ( !isdigit(*s) ) return false; - - hasE = true; - continue; - } - //if meet space, check the rest chars are space or not - if (isspace(*s)){ - for (; *s != '\0'; s++){ - if (!isspace(*s)) return false; - } - return true; - } - if ( !isdigit(*s) ) { - return false; - } - - } - - return true; -} - -int main(int argc, char** argv) -{ - if (argc != 2) { - fprintf(stderr, "Usage: ./test number\n"); - exit(-1); - } - printf("%s\n", isNumber(argv[1]) ? "true" : "false"); - return 0; -} diff --git a/066_plus_one/Makefile b/066_plus_one/Makefile deleted file mode 100644 index 954c8bf..0000000 --- a/066_plus_one/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test plus_one.c diff --git a/067_add_binary/Makefile b/067_add_binary/Makefile deleted file mode 100644 index 5b996ad..0000000 --- a/067_add_binary/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test add_binary.c diff --git a/068_text_justification/Makefile b/068_text_justification/Makefile deleted file mode 100644 index afcf23f..0000000 --- a/068_text_justification/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test justification.c diff --git a/069_sqrt/Makefile b/069_sqrt/Makefile deleted file mode 100644 index 3d94c52..0000000 --- a/069_sqrt/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test sqrt.c 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 -#include - -static int recursive(int n, int *count) -{ - if (n == 0) { - return 0; - } else if (count[n] > 0) { - return count[n]; - } else { - if (n >= 1) { - count[n] += recursive(n - 1, count); - } - if (n >= 2) { - count[n] += recursive(n - 2, count); - } - return count[n]; - } -} - -static int climbStairs(int n) -{ - int *count = malloc((n + 1) * sizeof(int)); - memset(count, 0, (n + 1) * sizeof(int)); - count[1] = 1; - count[2] = 2; - return recursive(n, count); -} - -int main(int argc, char **argv) -{ - if (argc != 2) { - fprintf(stderr, "Usage: ./test n\n"); - exit(-1); - } - - printf("%d\n", climbStairs(atoi(argv[1]))); - return 0; -} diff --git a/071_simplify_path/Makefile b/071_simplify_path/Makefile deleted file mode 100644 index 5e49404..0000000 --- a/071_simplify_path/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test simplify_path.c diff --git a/072_edit_distance/Makefile b/072_edit_distance/Makefile deleted file mode 100644 index b8aad45..0000000 --- a/072_edit_distance/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test edit_distance.c diff --git a/072_edit_distance/edit_distance.c b/072_edit_distance/edit_distance.c deleted file mode 100644 index c854187..0000000 --- a/072_edit_distance/edit_distance.c +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include -#include - -/* - * Dynamic Programming - * - * Definitaion - * - * m[i][j] is minimal distance from word1[0..i] to word2[0..j] - * - * So, - * - * 1) if word1[i] == word2[j], then m[i][j] == m[i-1][j-1]. - * - * 2) if word1[i] != word2[j], then we need to find which one below is minimal: - * - * min( m[i-1][j-1], m[i-1][j], m[i][j-1] ) - * - * and +1 - current char need be changed. - * - * Let's take a look m[1][2] : "a" => "ab" - * - * +---+ +---+ - * ''=> a | 1 | | 2 | '' => ab - * +---+ +---+ - * - * +---+ +---+ - * a => a | 0 | | 1 | a => ab - * +---+ +---+ - * - * To know the minimal distance `a => ab`, we can get it from one of the following cases: - * - * 1) delete the last char in word1, minDistance( '' => ab ) + 1 - * 2) delete the last char in word2, minDistance( a => a ) + 1 - * 3) change the last char, minDistance( '' => a ) + 1 - * - * - * For Example: - * - * word1="abb", word2="abccb" - * - * 1) Initialize the DP matrix as below: - * - * "" a b c c b - * "" 0 1 2 3 4 5 - * a 1 - * b 2 - * b 3 - * - * 2) Dynamic Programming - * - * "" a b c c b - * "" 0 1 2 3 4 5 - * a 1 0 1 2 3 4 - * b 2 1 0 1 2 3 - * b 3 2 1 1 2 2 - * - */ - -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); - } - - for (i = 0; i < len2 + 1; i++) { - dp[0][i] = i; - } - for (i = 0; i < len1 + 1; i++) { - dp[i][0] = i; - } - - for (i = 1; i < len1 + 1; i++) { - for (j = 1; j < len2 + 1; j++) { - if (word1[i - 1] == word2[j - 1]) { - dp[i][j] = dp[i - 1][j - 1]; - } else { - int min = dp[i - 1][j] > dp[i][j - 1] ? dp[i][j - 1] : dp[i - 1][j]; - dp[i][j] = min > dp[i - 1][j - 1] ? dp[i - 1][j - 1] : min; - dp[i][j] += 1; - } - } - } - return dp[len1][len2]; -} - -int main(int argc, char **argv) -{ - if (argc != 3) { - fprintf(stderr, "Usage: ./test word1 word2\n"); - exit(-1); - } - printf("%d\n", minDistance(argv[1], argv[2])); - return 0; -} diff --git a/073_set_matrix_zeroes/Makefile b/073_set_matrix_zeroes/Makefile deleted file mode 100644 index 85d2147..0000000 --- a/073_set_matrix_zeroes/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test set_zero.c diff --git a/073_set_matrix_zeroes/set_zero.c b/073_set_matrix_zeroes/set_zero.c deleted file mode 100644 index 71e54a7..0000000 --- a/073_set_matrix_zeroes/set_zero.c +++ /dev/null @@ -1,40 +0,0 @@ -#include -#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 -#include - -static void swap(int *a, int *b) -{ - int tmp = *a; - *a = *b; - *b = tmp; -} - -/* - * RED = 0 - * WHITE = 1 - * BLUE = 2 - */ -static void sortColors(int* nums, int numsSize) { - int i = 0, j = numsSize - 1; - while (i < j) { - while (nums[i] == 0 && i < j) { - i++; - } - while (nums[j] != 0 && j > i) { - j--; - } - swap(nums + i, nums + j); - } - j = numsSize - 1; - while (i < j) { - while (nums[i] == 1 && i < j) { - i++; - } - while (nums[j] != 1 && j > i) { - j--; - } - swap(nums + i, nums + j); - } -} - -int main(int argc, char **argv) -{ - if (argc != 2) { - fprintf(stderr, "Usage: ./test colors\n"); - exit(-1); - } - int i, count = strlen(argv[1]); - int *nums = malloc(count * sizeof(int)); - for (i = 0; i < count; i++) { - nums[i] = argv[1][i] - '0'; - } - sortColors(nums, count); - for (i = 0; i < count; i++) { - printf("%d", nums[i]); - } - printf("\n"); - return 0; -} diff --git a/076_minimum_window_substring/Makefile b/076_minimum_window_substring/Makefile deleted file mode 100644 index 5cd14dc..0000000 --- a/076_minimum_window_substring/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test window_substring.c diff --git a/076_minimum_window_substring/window_substring.c b/076_minimum_window_substring/window_substring.c deleted file mode 100644 index 50970ee..0000000 --- a/076_minimum_window_substring/window_substring.c +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include -#include -#include - -static char *minWindow(char *s, char *t) -{ - /* - * Declare two "hash map" for ASCII chars - * f[]: represents the char found in s - * m[]: stores the chars in t - */ - int i, f[256], m[256], pat_len = 0; - memset(m, 0, sizeof(m)); - memset(f, 0, sizeof(f)); - - /* - * Go through t, and inital the m[] and f[] - * Notes: duplicate char is allowed. - */ - for (i = 0; t[i] != '\0'; i++) { - m[t[i]]++; - pat_len++; - } - - int start =-1; - int size = INT_MAX; - int found = 0; - int begin = 0; - for (i = 0; s[i] != '\0'; i++) { - /* First, find the right side of the window which should be in t */ - if (m[s[i]] > 0) { - /* if one char has been found enough times, then do not do found++ */ - if (++f[s[i]] <= m[s[i]]) { - found++; - } - - /* the right side of the window is confirmed as i */ - /* The found counter will no more increase if the first right side of the window is confirmed, - * the next step run here can also be regarded as a new right side of a new window. */ - if (found == pat_len) { - /* Then we need to find the left side of the window - * 1) m[s[begin]] == 0 => Both left and right side should be found in t - * 2) f[s[begin]] > m[s[begin]] => duplicate chars are more than excepted in the window so that we can even shrink the size. */ - while (m[s[begin]] == 0 || f[s[begin]] > m[s[begin]]) { - if (f[s[begin]] > m[s[begin]]) { - f[s[begin]]--; - } - begin++; - } - - /* Calculate the minimized window size */ - if (size > i - begin + 1) { - start = begin; - size = i - begin + 1; - } - } - } - } - - char *result; - if (start >= 0 && size > 0) { - result = malloc(size + 1); - memcpy(result, s + start, size); - result[size] = '\0'; - } else { - result = malloc(1); - result[0] = '\0'; - } - return result; -} - -int main(int argc, char **argv) -{ - if (argc != 3) { - fprintf(stderr, "Usage: ./test string pattern\n"); - exit(-1); - } - printf("Answer: %s\n", minWindow(argv[1], argv[2])); - return 0; -} diff --git a/077_combinations/Makefile b/077_combinations/Makefile deleted file mode 100644 index 6361695..0000000 --- a/077_combinations/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test combinations.c diff --git a/077_combinations/combinations.c b/077_combinations/combinations.c deleted file mode 100644 index 47a6b71..0000000 --- a/077_combinations/combinations.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include -#include - -static void recursive(int n, int k, int start, int *stack, int len, bool *used, - int *col_sizes, int **results, int *count) -{ - int i; - if (len == k) { - col_sizes[*count] = k; - results[*count] = malloc(k * sizeof(int)); - memcpy(results[*count], stack, k * sizeof(int)); - (*count)++; - } else { - for (i = start; i <= n; i++) { - if (!used[i]) { - stack[len] = i; - used[i] = true; - recursive(n, k, i + 1, stack, len + 1, used, col_sizes, results, count); - used[i] = false; - } - } - } -} - -/** - * 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(). - */ -int** combine(int n, int k, int** columnSizes, int* returnSize) { - int capacity = 10000; - int count = 0; - int **results = malloc(capacity * sizeof(int *)); - int *stack = malloc(k * sizeof(int)); - bool *used = malloc((n + 1) * sizeof(bool)); - memset(used, false, n + 1); - *columnSizes = malloc(capacity * sizeof(int)); - recursive(n, k, 1, stack, 0, used, *columnSizes, results, &count); - *returnSize = count; - return results; -} - -int main(int argc, char **argv) -{ - if (argc != 3) { - fprintf(stderr, "Usage: ./test n k\n"); - exit(-1); - } - - int i, j, *col_sizes, count = 0; - int **lists = combine(atoi(argv[1]), atoi(argv[2]), &col_sizes, &count); - 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/078_subsets/Makefile b/078_subsets/Makefile deleted file mode 100644 index 580c713..0000000 --- a/078_subsets/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test subsets.c diff --git a/079_word_search/Makefile b/079_word_search/Makefile deleted file mode 100644 index 99bef24..0000000 --- a/079_word_search/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test word_search.c diff --git a/080_remove_duplicates_from_sorted_array_ii/Makefile b/080_remove_duplicates_from_sorted_array_ii/Makefile deleted file mode 100644 index 863c440..0000000 --- a/080_remove_duplicates_from_sorted_array_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test rm_dups.c diff --git a/080_remove_duplicates_from_sorted_array_ii/rm_dups.c b/080_remove_duplicates_from_sorted_array_ii/rm_dups.c deleted file mode 100644 index 6156057..0000000 --- a/080_remove_duplicates_from_sorted_array_ii/rm_dups.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include - -int removeDuplicates(int* nums, int numsSize) { - int i = 0, j, x, y, count = 0; - while (i < numsSize) { - for (j = i + 1; j < numsSize && nums[i] == nums[j]; j++) {} - int diff = j - i; - if (diff > 2) { - for (x = i + 2, y = j; y < numsSize; x++, y++) { - nums[x] = nums[y]; - } - numsSize -= diff - 2; - } - count += diff > 2 ? 2 : diff; - i += diff > 2 ? 2 : diff; - } - return count; -} - -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]); - } - count = removeDuplicates(nums, count); - for (i = 0; i < count; i++) { - printf("%d ", nums[i]); - } - printf("\n"); -} diff --git a/081_search_in_rotated_sorted_array_ii/Makefile b/081_search_in_rotated_sorted_array_ii/Makefile deleted file mode 100644 index 751e614..0000000 --- a/081_search_in_rotated_sorted_array_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test search_rotated_array.c diff --git a/081_search_in_rotated_sorted_array_ii/search_rotated_array.c b/081_search_in_rotated_sorted_array_ii/search_rotated_array.c deleted file mode 100644 index b5ba3b5..0000000 --- a/081_search_in_rotated_sorted_array_ii/search_rotated_array.c +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include - -static int binary_search(int *nums, int size, int target) -{ - int low = -1; - int high = size; - while (low + 1 < high) { - int mid = low + (high - low) / 2; - if (target > nums[mid]) { - low = mid; - } else { - high = mid; - } - } - if (high == size || nums[high] != target) { - return -1; - } else { - return high; - } -} - -static int search(int* nums, int numsSize, int target) { - if (numsSize <= 0) { - return -1; - } - if (numsSize == 1) { - return target == nums[0] ? 0 : -1; - } - - int i; - for (i = 1; i < numsSize; i++) { - if (nums[i] < nums[i - 1]) { - break; - } - } - - if (i == 0) { - return binary_search(nums, numsSize, target); - } else if (target >= nums[0]) { - return binary_search(nums, i, target); - } else if (target <= nums[numsSize - 1]) { - int index = binary_search(nums + i, numsSize - i, target); - return index >= 0 ? index + i : -1; - } else { - return -1; - } -} - -int main(int argc, char **argv) -{ - int i; - int target = atoi(argv[1]); - int size = argc - 2; - int *nums = malloc(size * sizeof(int)); - - for (i = 0; i < argc - 2; i++) { - nums[i] = atoi(argv[i + 2]); - } - printf("%d\n", search(nums, size, target)); - return 0; -} diff --git a/082_remove_duplicates_from_sorted_list_ii/Makefile b/082_remove_duplicates_from_sorted_list_ii/Makefile deleted file mode 100644 index 5cf5932..0000000 --- a/082_remove_duplicates_from_sorted_list_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test rm_dup.c diff --git a/083_remove_duplicates_from_sorted_list/Makefile b/083_remove_duplicates_from_sorted_list/Makefile deleted file mode 100644 index 5cf5932..0000000 --- a/083_remove_duplicates_from_sorted_list/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test rm_dup.c diff --git a/084_largest_rectangle_in_histogram/Makefile b/084_largest_rectangle_in_histogram/Makefile deleted file mode 100644 index 8306292..0000000 --- a/084_largest_rectangle_in_histogram/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test rect_in_histogram.c diff --git a/084_largest_rectangle_in_histogram/rect_in_histogram.c b/084_largest_rectangle_in_histogram/rect_in_histogram.c deleted file mode 100644 index 7036579..0000000 --- a/084_largest_rectangle_in_histogram/rect_in_histogram.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include - -static int largestRectangleArea(int* heights, int heightsSize) -{ - int i, max_area = 0; - for (i = 0; i < heightsSize; i++) { - if (i > 0 && heights[i - 1] == heights[i]) { - continue; - } - int low = i; - int high = i; - while (low - 1 >= 0 && heights[low - 1] >= heights[i]) { - low--; - } - while (high + 1 < heightsSize && heights[high + 1] >= heights[i]) { - high++; - } - int area = (high - low + 1) * heights[i]; - max_area = area > max_area ? area : max_area; - } - return max_area; -} - -int main(void) -{ - int nums[] = { 2, 1, 5, 6, 2, 3 }; - int count = sizeof(nums) / sizeof(*nums); - printf("%d\n", largestRectangleArea(nums, count)); - return 0; -} diff --git a/085_maximal_rectangle/Makefile b/085_maximal_rectangle/Makefile deleted file mode 100644 index c85beaa..0000000 --- a/085_maximal_rectangle/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test maximal_rectangle.c diff --git a/085_maximal_rectangle/maximal_rectangle.c b/085_maximal_rectangle/maximal_rectangle.c deleted file mode 100644 index cdca77a..0000000 --- a/085_maximal_rectangle/maximal_rectangle.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -#include -#include - -int maximalRectangle(char** matrix, int matrixRowSize, int matrixColSize) { - int i, j, max_area = 0; - for (i = 0; i < matrixRowSize; i++) { - for (j = 0; j < matrixColSize; j++) { - if (matrix[i][j] == '1') { - int area = 0, x, y; - int row = i; - int min_col = matrixColSize; - while (row < matrixRowSize) { - for (x = j; x < matrixColSize && matrix[row][x] == '1'; x++) {} - min_col = x < min_col ? x : min_col; - area = (row - i + 1) * (min_col - j); - max_area = area > max_area ? area : max_area; - row++; - } - int col = j; - int min_row = matrixRowSize; - while (col < matrixColSize) { - for (y = i; y < matrixRowSize && matrix[y][col] == '1'; y++) {} - min_row = y < min_row ? y : min_row; - area = (min_row - i) * (col - j + 1); - max_area = area > max_area ? area : max_area; - col++; - } - } - } - } - return max_area; -} - -/* ./test 11111111 11111110 11111110 11111000 01111000 */ -int main(int argc, char **argv) -{ - if (argc < 2) { - fprintf(stderr, "Usage: ./test row1 row2...\n"); - exit(-1); - } - - int i, j; - int row_size = argc - 1; - int col_size = strlen(argv[1]); - for (i = 0; i < row_size; i++) { - printf("%s\n", argv[i + 1]); - } - printf("%d\n", maximalRectangle(argv + 1, argc - 1, strlen(argv[1]))); - return 0; -} diff --git a/086_partition_list/Makefile b/086_partition_list/Makefile deleted file mode 100644 index eabdaba..0000000 --- a/086_partition_list/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test partition_list.c diff --git a/087_scramble_string/Makefile b/087_scramble_string/Makefile deleted file mode 100644 index 52cecd7..0000000 --- a/087_scramble_string/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test scramble_string.c diff --git a/088_merge_sorted_array/Makefile b/088_merge_sorted_array/Makefile deleted file mode 100644 index e286d3c..0000000 --- a/088_merge_sorted_array/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test merge_array.c diff --git a/088_merge_sorted_array/merge_array.c b/088_merge_sorted_array/merge_array.c deleted file mode 100644 index dcc4e94..0000000 --- a/088_merge_sorted_array/merge_array.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include - -static int binary_search(int *nums, int len, int target) -{ - int low = -1; - int high = len; - while (low + 1 < high) { - int mid = high - (high - low) / 2; - if (target > nums[mid]) { - low = mid; - } else { - high = mid; - } - } - if (high == len || nums[high] != target) { - return -high - 1; - } else { - return high; - } -} - -static void merge(int* nums1, int m, int* nums2, int n) -{ - int i, j, len1 = m; - for (i = 0; i < n; i++) { - int index = binary_search(nums1, len1, nums2[i]); - if (index < 0) { - index = -index - 1; - } - for (j = len1 - 1; j >= index; j--) { - nums1[j + 1] = nums1[j]; - } - nums1[index] = nums2[i]; - len1++; - } -} - -int main(int argc, char **argv) -{ - int i; - int nums1[] = { 1, 3, 5, 7, 9, 0, 0, 0, 0, 0 }; - int nums2[] = { 2, 4, 6, 8, 10 }; - int size1 = 5;//sizeof(nums1) / sizeof(*nums1); - int size2 = sizeof(nums2) / sizeof(*nums2); - merge(nums1, size1, nums2, size2); - for (i = 0; i < sizeof(nums1) / sizeof(*nums1); i++) { - printf("%d ", nums1[i]); - } - printf("\n"); - return 0; -} diff --git a/089_gray_code/Makefile b/089_gray_code/Makefile deleted file mode 100644 index dbe10ea..0000000 --- a/089_gray_code/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test gray_code.c diff --git a/090_subsets_ii/Makefile b/090_subsets_ii/Makefile deleted file mode 100644 index 580c713..0000000 --- a/090_subsets_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test subsets.c diff --git a/090_subsets_ii/subsets.c b/090_subsets_ii/subsets.c deleted file mode 100644 index c33fe19..0000000 --- a/090_subsets_ii/subsets.c +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include - -int *cache1, *cache2; - -static void insert_sort(int *nums, int size) -{ - int i, j; - for (i = 1; i < size; i++) { - int tmp = nums[i]; - for (j = i - 1; j >= 0 && tmp < nums[j]; j--) { - nums[j + 1] = nums[j]; - } - nums[j + 1] = tmp; - } -} - -static int exist(int **results, int count, int *sizes, int *buf, int len) -{ - int i, j; - for (i = 0; i < count; i++) { - if (len == sizes[i]) { - memcpy(cache1, results[i], len * sizeof(int)); - memcpy(cache2, buf, len * sizeof(int)); - insert_sort(cache1, len); - insert_sort(cache2, len); - if (!memcmp(cache1, cache2, len * sizeof(int))) { - return 1; - } - } - } - return 0; -} - -static void subset_recursive(int *nums, int size, int start, - int *buf, int len, - int **sets, int *sizes, int *count) -{ - int i; - if (!exist(sets, *count, sizes, buf, len)) { - sets[*count] = malloc(len * sizeof(int)); - memcpy(sets[*count], buf, len * sizeof(int)); - sizes[*count] = len; - (*count)++; - } - for (i = start; i < size; i++) { - buf[len++] = nums[i]; - subset_recursive(nums, size, i + 1, buf, len, sets, sizes, count); - len--; - } -} - -/** - ** 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(). - **/ -int** subsets(int* nums, int numsSize, int** columnSizes, int* returnSize) { - int capacity = 5000; - int **sets = malloc(capacity * sizeof(int *)); - int *buf = malloc(numsSize * sizeof(int)); - *columnSizes = malloc(capacity * sizeof(int)); - *returnSize = 0; - cache1 = malloc(numsSize * sizeof(int)); - cache2 = malloc(numsSize * sizeof(int)); - subset_recursive(nums, numsSize, 0, buf, 0, sets, *columnSizes, returnSize); - return sets; -} - -int main(int argc, char **argv) -{ - int i, j; - if (argc <= 1) { - fprintf(stderr, "Usage: ./test array...\n"); - exit(-1); - } - int size = argc - 1; - int *nums = malloc(size * sizeof(int)); - for (i = 0; i < size; i++) { - nums[i] = atoi(argv[i + 1]); - } - int *sizes; - int count; - int **lists = subsets(nums, size, &sizes, &count); - for (i = 0; i < count; i++) { - for (j = 0; j < sizes[i]; j++) { - printf("%d ", lists[i][j]); - } - printf("\n"); - } - return 0; -} diff --git a/0912_sort_an_array/Makefile b/0912_sort_an_array/Makefile new file mode 100644 index 0000000..b959cec --- /dev/null +++ b/0912_sort_an_array/Makefile @@ -0,0 +1,2 @@ +all: + gcc -o test sort.c diff --git a/0912_sort_an_array/sort.c b/0912_sort_an_array/sort.c new file mode 100644 index 0000000..304ffaf --- /dev/null +++ b/0912_sort_an_array/sort.c @@ -0,0 +1,125 @@ +#include +#include + + +static void show(int *nums, int lo, int hi) +{ + int i; + for (i = lo; i <= hi; i++) { + printf("%d ", nums[i]); + } + printf("\n"); +} + +static inline void swap(int *a, int *b) +{ + int t = *a; + *a = *b; + *b = t; +} + +static void quick_sort(int *nums, int lo, int hi) +{ + int i, j, mid, pivot; + + if (lo >= hi) { + return; + } + + /* shuffle the pivot as it is a must for performance */ + mid = lo + (hi - lo) / 2; + swap(&nums[mid], &nums[hi]); + + i = lo - 1; + j = hi; + pivot = nums[hi]; + while (i < j) { + /* For case of large amounts of consecutive duplicate elements, we + * shall make the partition in the middle of the array as far as + * possible. If the partition is located in the head or tail, the + * performance might well be very bad for it. + * + * Note: Do NOT use nums[++i] <= pivot or nums[--j] >= pivot as the + * loop condition because it leads to redundant operations in each + * recusive iteration when there are many duplicate elements. + */ + while (i < j && nums[++i] < pivot) {} + while (i < j && nums[--j] > pivot) {} + if (i < j) { + swap(&nums[i], &nums[j]); + } + } + + /* Loop invariant: i == j + 1 or i == j */ + swap(&nums[i], &nums[hi]); + quick_sort(nums, lo, i - 1); + quick_sort(nums, i + 1, hi); +} + +static void merge(int *nums, int lo, int mid, int hi) +{ + int i, j, k, size = hi - mid; + int *tmp = malloc(size * sizeof(int)); + + for (j = 0; j < size; j++) { + tmp[j] = nums[mid + 1 + j]; + } + + i = mid; + j = size - 1; + k = hi; + while (i >= lo && j >= 0) { + if (tmp[j] >= nums[i]) { + nums[k--] = tmp[j--]; + } else { + nums[k--] = nums[i--]; + } + } + + while (j >= 0) { + nums[k--] = tmp[j--]; + } + + free(tmp); +} + +static void merge_sort(int *nums, int lo, int hi) +{ + int mid; + + if (lo >= hi) { + return; + } + + mid = lo + (hi - lo) / 2; + + merge_sort(nums, lo, mid); + merge_sort(nums, mid + 1, hi); + + merge(nums, lo, mid, hi); +} + +int *sortArray(int *nums, int numsSize, int *returnSize) +{ +#if 1 + quick_sort(nums, 0, numsSize - 1); +#else + merge_sort(nums, 0, numsSize - 1); +#endif + *returnSize = numsSize; + return nums; +} + +int main(int argc, char **argv) +{ + int i, count = argc - 1; + int ret_size = 0; + int *nums = malloc(count * sizeof(int)); + for (i = 0; i < count; i++) { + nums[i] = atoi(argv[i + 1]); + } + + show(sortArray(nums, count, &ret_size), 0, ret_size - 1); + + return 0; +} diff --git a/091_decode_ways/Makefile b/091_decode_ways/Makefile deleted file mode 100644 index 165f550..0000000 --- a/091_decode_ways/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test decode_ways.c diff --git a/091_decode_ways/decode_ways.c b/091_decode_ways/decode_ways.c deleted file mode 100644 index 4f374fb..0000000 --- a/091_decode_ways/decode_ways.c +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include - -//static void recursive(char *s, char *stack, int len, char **results, int *count) -//{ -// if (*s == '\0') { -// printf("%s\n", stack); -// results[*count] = malloc(len + 1); -// strcpy(results[*count], stack); -// (*count)++; -// } else { -// //while (*s != '\0') { -// stack[len++] = *s - '0' - 1 + 'A'; -// recursive(s + 1, stack, len, results, count); -// stack[--len] = '\0'; -// if (*(s + 1) != '\0') { -// int value = (*s - '0') * 10 + (*(s + 1) - '0'); -// char c = (value - 1) + 'A'; -// if (c >= 'A' && c <= 'Z') { -// stack[len++] = c; -// recursive(s + 2, stack, len, results, count); -// stack[--len] = '\0'; -// //s++; -// } -// } -// //s++; -// //} -// } -//} - -static void recursive(char *s, int *count) -{ - int value; - char c; - if (*s == '\0') { - (*count)++; - } else { - value = *s - '0'; - c = (value - 1) + 'A'; - if (c >= 'A' && c <= 'Z') { - recursive(s + 1, count); - } - if (*(s + 1) != '\0' && *s != '0') { - value = (*s - '0') * 10 + (*(s + 1) - '0'); - c = (value - 1) + 'A'; - if (c >= 'A' && c <= 'Z') { - recursive(s + 2, count); - } - } - } -} - -static int numDecodings(char* s) { - int count = 0; - if (*s != '\0' && *s != '0') { - recursive(s, &count); - } - return count; -} - -int main(int argc, char **argv) -{ - if (argc != 2) { - fprintf(stderr, "Usage: ./test number\n"); - exit(-1); - } - printf("%d\n", numDecodings(argv[1])); - return 0; -} diff --git a/092_reverse_linked_list_ii/Makefile b/092_reverse_linked_list_ii/Makefile deleted file mode 100644 index d480ecf..0000000 --- a/092_reverse_linked_list_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test reverse_list.c diff --git a/093_restore_ip_addresses/Makefile b/093_restore_ip_addresses/Makefile deleted file mode 100644 index eae26d6..0000000 --- a/093_restore_ip_addresses/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test ip_addr.c diff --git a/094_binary_tree_inorder_traversal/Makefile b/094_binary_tree_inorder_traversal/Makefile deleted file mode 100644 index d3ae6df..0000000 --- a/094_binary_tree_inorder_traversal/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test bst_inorder_traversal.c diff --git a/095_unique_binary_search_trees_ii/Makefile b/095_unique_binary_search_trees_ii/Makefile deleted file mode 100644 index c64e979..0000000 --- a/095_unique_binary_search_trees_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test unique_bst.c diff --git a/096_unique_binary_search_trees/Makefile b/096_unique_binary_search_trees/Makefile deleted file mode 100644 index c64e979..0000000 --- a/096_unique_binary_search_trees/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test unique_bst.c diff --git a/097_interleaving_string/Makefile b/097_interleaving_string/Makefile deleted file mode 100644 index 8b5afb2..0000000 --- a/097_interleaving_string/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test interleaving_string.c diff --git a/098_validate_binary_search_tree/Makefile b/098_validate_binary_search_tree/Makefile deleted file mode 100644 index 72cc896..0000000 --- a/098_validate_binary_search_tree/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test valid_bst.c diff --git a/098_validate_binary_search_tree/valid_bst.c b/098_validate_binary_search_tree/valid_bst.c deleted file mode 100644 index 3b90ad7..0000000 --- a/098_validate_binary_search_tree/valid_bst.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include -#include - -struct TreeNode { - int val; - struct TreeNode *left; - struct TreeNode *right; -}; - -static bool traverse(struct TreeNode* node, int *last_val) -{ - bool ret = true; - - if (ret && node->left != NULL) { - ret = traverse(node->left, last_val); - } - - if (node->val <= *last_val) { - return false; - } - *last_val = node->val; - - if (ret && node->right != NULL) { - ret = traverse(node->right, last_val); - } - return ret; -} - -static bool isValidBST(struct TreeNode* root) -{ - if (root == NULL) { - return true; - } else { - int last_val = -1; - return traverse(root, &last_val); - } -} - -int main(int argc, char **argv) -{ - struct TreeNode root; - struct TreeNode left; - struct TreeNode right; - root.val = 2; - root.left = &left; - root.right = &right; - left.val = 1; - left.left = NULL; - left.right = NULL; - right.val = 3; - right.left = NULL; - right.right = NULL; - printf("%s\n", isValidBST(&root) ? "true" : "false"); - 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/099_recover_binary_search_tree/Makefile b/099_recover_binary_search_tree/Makefile deleted file mode 100644 index 95d5434..0000000 --- a/099_recover_binary_search_tree/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test recover_bst.c diff --git a/099_recover_binary_search_tree/recover_bst.c b/099_recover_binary_search_tree/recover_bst.c deleted file mode 100644 index ecae963..0000000 --- a/099_recover_binary_search_tree/recover_bst.c +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include - -struct TreeNode { - int val; - struct TreeNode *left; - struct TreeNode *right; -}; - -static struct TreeNode *last = NULL; -static struct TreeNode *m1 = NULL; -static struct TreeNode *m2 = NULL; -static int wrong = 0; - -static void traverse(struct TreeNode* node) -{ - if (node->left != NULL) { - traverse(node->left); - } - - if (last != NULL && node->val < last->val) { - if (++wrong == 2) { - int tmp = node->val; - node->val = m1->val; - m1->val = tmp; - } - m1 = last; - m2 = node; - } - last = node; - - if (node->right != NULL) { - traverse(node->right); - } -} - -static void recoverTree(struct TreeNode* root) { - if (root != NULL) { - last = NULL; - m1 = NULL; - m2 = NULL; - wrong = 0; - traverse(root); - if (wrong == 1) { - int tmp = m1->val; - m1->val = m2->val; - m2->val = tmp; - } - } -} - -int main(int argc, char **argv) -{ - struct TreeNode root; - struct TreeNode left; - struct TreeNode right; - root.val = 2; - root.left = &left; - root.right = &right; - left.val = 3; - left.left = NULL; - left.right = NULL; - right.val = 1; - right.left = NULL; - right.right = NULL; - recoverTree(&root); - printf("%d %d %d\n", root.val, left.val, right.val); - return 0; -} diff --git a/100_same_tree/Makefile b/100_same_tree/Makefile deleted file mode 100644 index cbec06a..0000000 --- a/100_same_tree/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test same_tree.c diff --git a/100_same_tree/same_tree.c b/100_same_tree/same_tree.c deleted file mode 100644 index 14e15ee..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; -}; - -bool isSameTree(struct TreeNode* p, struct TreeNode* q) { - if ((p == NULL && q != NULL) || (p != NULL && q == NULL)) { - return false; - } - 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; - } - } - - return true; -} - -int main(void) -{ - printf("%s\n", isSameTree(NULL, NULL) ? "true" : "false"); - return 0; -} diff --git a/101_symmetric_tree/Makefile b/101_symmetric_tree/Makefile deleted file mode 100644 index eb640cf..0000000 --- a/101_symmetric_tree/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test symmetric_tree.c diff --git a/102_binary_tree_level_order_traversal/Makefile b/102_binary_tree_level_order_traversal/Makefile deleted file mode 100644 index d8026db..0000000 --- a/102_binary_tree_level_order_traversal/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test bst_bfs.c diff --git a/103_binary_tree_zigzag_level_order_traversal/Makefile b/103_binary_tree_zigzag_level_order_traversal/Makefile deleted file mode 100644 index 48851f2..0000000 --- a/103_binary_tree_zigzag_level_order_traversal/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test bst_zigzag.c diff --git a/104_maximum_depth_of_binary_tree/Makefile b/104_maximum_depth_of_binary_tree/Makefile deleted file mode 100644 index 5a375a6..0000000 --- a/104_maximum_depth_of_binary_tree/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test bst_depth.c diff --git a/105_construct_binary_tree_from_preorder_and_inorder_traversal/Makefile b/105_construct_binary_tree_from_preorder_and_inorder_traversal/Makefile deleted file mode 100644 index fe2f6d1..0000000 --- a/105_construct_binary_tree_from_preorder_and_inorder_traversal/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test binary_tree_build.c diff --git a/105_construct_binary_tree_from_preorder_and_inorder_traversal/binary_tree_build.c b/105_construct_binary_tree_from_preorder_and_inorder_traversal/binary_tree_build.c deleted file mode 100644 index 4319273..0000000 --- a/105_construct_binary_tree_from_preorder_and_inorder_traversal/binary_tree_build.c +++ /dev/null @@ -1,199 +0,0 @@ -#include -#include - -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 INIT_HLIST_NODE(struct hlist_node *n) { - n->next = NULL; - n->pprev = 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; - } -} - -#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 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 struct TreeNode *recursive(int *preorder, int pre_low, int pre_high, - int *inorder, int in_low, int in_high, - struct hlist_head *in_heads, int size) -{ - if (in_low > in_high || pre_low > pre_high) { - return NULL; - } - struct TreeNode *tn = malloc(sizeof(*tn)); - tn->val = preorder[pre_low]; - int index = find(preorder[pre_low], size, in_heads); - tn->left = recursive(preorder, pre_low + 1, pre_low + (index - in_low), inorder, in_low, index - 1, in_heads, size); - tn->right = recursive(preorder, pre_high - (in_high - index - 1), pre_high, inorder, index + 1, in_high, in_heads, size); - 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 *buildTree(int *preorder, int preorderSize, int *inorder, int inorderSize) -{ - 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); - } - -#if 0 - struct hlist_head *pre_heads = malloc(preorderSize * sizeof(*pre_heads)); - for (i = 0; i < preorderSize; i++) { - INIT_HLIST_HEAD(&pre_heads[i]); - } - for (i = 0; i < inorderSize; i++) { - node_add(preorder[i], i, preorderSize, pre_heads); - } - - int last_index, level = 0; - struct TreeNode **stack = malloc(preorderSize * sizeof(*stack)); - struct TreeNode *tn, *root = NULL; - for (i = 0; i < preorderSize; i++) { - if (i == 0) { - tn = root = node_new(preorder[0]); - last_index = find(preorder[0], inorderSize, in_heads); - stack[level++] = root; - } else { - int index = find(preorder[i], inorderSize, in_heads); - if (index < last_index) { - tn->left = node_new(preorder[i]); - tn = tn->left; - } else { - for (j = index - 1; j >= 0; j--) { - if (find(inorder[j], preorderSize, pre_heads) < i) { - break; - } - } - /* find the parent of the right child */ - while (stack[--level]->val != inorder[j]) {} - tn = stack[level++]; - tn->right = node_new(preorder[i]); - tn = tn->right; - } - stack[level++] = tn; - last_index = index; - } - } - - return root; -#else - return recursive(preorder, 0, preorderSize - 1, inorder, 0, inorderSize - 1, in_heads, inorderSize); -#endif -} - -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 preorder[] = { 8,4,2,1,3,6,5,7,12,10,9,11,14,13,15 }; - //int inorder[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 }; - int preorder[] = { 7,-10,-4,3,-1,2,-8,11 }; - int inorder[] = { -4,-10,3,-1,7,11,-8,2 }; - //int preorder[] = { 3,2,1 }; - //int preorder[] = { 3,1,2 }; - //int preorder[] = { 2,1,3 }; - //int preorder[] = { 1,3,2 }; - //int preorder[] = { 1,2,3 }; - //int inorder[] = { 1,2,3 }; - int pre_size = sizeof(preorder) / sizeof(*preorder); - int in_size = sizeof(inorder) / sizeof(*inorder); - struct TreeNode *root = buildTree(preorder, pre_size, inorder, in_size); - dump(root); - printf("\n"); - return 0; -} diff --git a/106_construct_binary_tree_from_inorder_and_postorder_traversal/Makefile b/106_construct_binary_tree_from_inorder_and_postorder_traversal/Makefile deleted file mode 100644 index fe2f6d1..0000000 --- a/106_construct_binary_tree_from_inorder_and_postorder_traversal/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test binary_tree_build.c 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 a02c17b..0000000 --- a/106_construct_binary_tree_from_inorder_and_postorder_traversal/binary_tree_build.c +++ /dev/null @@ -1,195 +0,0 @@ -#include -#include - -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 void INIT_HLIST_NODE(struct hlist_node *n) { - n->next = NULL; - n->prev = 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; - } -} - -#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 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 *recursive(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 = recursive(inorder, in_low, index - 1, postorder, post_low, post_low + (index - 1 - in_low), in_heads, size); - tn->right = recursive(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); - } - -#if 0 - struct hlist_head *post_heads = malloc(postorderSize * sizeof(*post_heads)); - for (i = 0; i < postorderSize; i++) { - INIT_HLIST_HEAD(&post_heads[i]); - } - for (i = 0; i < inorderSize; i++) { - node_add(postorder[i], i, postorderSize, post_heads); - } - int last_index, level = 0; - struct TreeNode **stack = malloc(postorderSize * sizeof(*stack)); - struct TreeNode *tn, *root = NULL; - for (i = postorderSize - 1; i >= 0; i--) { - if (i == postorderSize - 1) { - tn = root = node_new(postorder[i]); - last_index = find(postorder[i], inorderSize, in_heads); - stack[level++] = root; - } else { - int index = find(postorder[i], inorderSize, in_heads); - if (index > last_index) { - tn->right = node_new(postorder[i]); - tn = tn->right; - } else { - for (j = index + 1; j < inorderSize; j++) { - if (find(inorder[j], postorderSize, post_heads) > i) { - break; - } - } - /* find the parent of the left child */ - while (stack[--level]->val != inorder[j]) {} - tn = stack[level++]; - tn->left = node_new(postorder[i]); - tn = tn->left; - } - stack[level++] = tn; - last_index = index; - } - } - - return root; -#else - return recursive(inorder, 0, inorderSize - 1, postorder, 0, postorderSize - 1, in_heads, inorderSize); -#endif -} - -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/107_binary_tree_level_order_traversal_ii/Makefile b/107_binary_tree_level_order_traversal_ii/Makefile deleted file mode 100644 index d8026db..0000000 --- a/107_binary_tree_level_order_traversal_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test bst_bfs.c diff --git a/107_binary_tree_level_order_traversal_ii/bst_bfs.c b/107_binary_tree_level_order_traversal_ii/bst_bfs.c deleted file mode 100644 index b9cc5ba..0000000 --- a/107_binary_tree_level_order_traversal_ii/bst_bfs.c +++ /dev/null @@ -1,208 +0,0 @@ -#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) - -#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 TreeNode { - int val; - struct TreeNode *left; - struct TreeNode *right; -}; - -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 bfs_node { - struct TreeNode *node; - struct list_head link; -}; - -static struct bfs_node *node_new(struct list_head *free_list, struct TreeNode *node) -{ - struct bfs_node *new; - if (list_empty(free_list)) { - new = malloc(sizeof(*new)); - } else { - new = list_first_entry(free_list, struct bfs_node, link); - list_del(&new->link); - } - new->node = node; - return new; -} - -static void queue(struct list_head *parents, struct list_head *children, - struct list_head *free_list, int **results, int *col_sizes, int level) -{ - 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->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)); - list_for_each_safe(p, n, parents) { - struct bfs_node *parent = list_entry(p, struct bfs_node, link); - results[level][i++] = parent->node->val; - list_del(p); - list_add(p, 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(). - **/ -static int** levelOrderBottom(struct TreeNode* root, int** columnSizes, int* returnSize) -{ - if (root == NULL) { - *returnSize = 0; - return NULL; - } - - struct list_head free_list; - struct list_head q0; - struct list_head q1; - INIT_LIST_HEAD(&free_list); - INIT_LIST_HEAD(&q0); - INIT_LIST_HEAD(&q1); - - int **results = malloc(BST_MAX_LEVEL * sizeof(int *)); - *columnSizes = malloc(BST_MAX_LEVEL * sizeof(int)); - memset(*columnSizes, 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, &free_list, results, *columnSizes, level); - } else { - queue(&q0, &q1, &free_list, results, *columnSizes, level); - } - level++; - } - - *returnSize = level; - - int i, j; - for (i = 0, j = level - 1; i < j; i++, j--) { - int *tmp = results[i]; - results[i] = results[j]; - results[j] = tmp; - int t = (*columnSizes)[i]; - (*columnSizes)[i] = (*columnSizes)[j]; - (*columnSizes)[j] = t; - } - 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 = levelOrderBottom(&root, &col_sizes, &count); - 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/108_convert_sorted_array_to_binary_search_tree/Makefile b/108_convert_sorted_array_to_binary_search_tree/Makefile deleted file mode 100644 index 113460f..0000000 --- a/108_convert_sorted_array_to_binary_search_tree/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test bst_convert.c diff --git a/108_convert_sorted_array_to_binary_search_tree/bst_convert.c b/108_convert_sorted_array_to_binary_search_tree/bst_convert.c deleted file mode 100644 index 3f249c2..0000000 --- a/108_convert_sorted_array_to_binary_search_tree/bst_convert.c +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include - - -struct TreeNode { - int val; - struct TreeNode *left; - struct TreeNode *right; -}; - -static void recursive(struct TreeNode **node, int *nums, int size, int i, struct TreeNode **root) -{ - if () { - *node = malloc(sizeof(**node)); - (*node)->val = nums[ - } else { - recursive(node, nums, size, i, root); - *node = malloc(sizeof(**root)); - if (i == size / 2) { - *root = *node; - } - recursive(node, nums, size, i, root); - } -} - -static struct TreeNode* sortedArrayToBST(int* nums, int numsSize) -{ - if (numsSize == 0) { - return NULL; - } - struct TreeNode *node, *root; - recursive(nums, numsSize, 0, &root); - return root; -} - -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]); - } - sortedArrayToBST(nums, count); - return 0; -} diff --git a/109_convert_sorted_list_to_binary_search_tree/Makefile b/109_convert_sorted_list_to_binary_search_tree/Makefile deleted file mode 100644 index 113460f..0000000 --- a/109_convert_sorted_list_to_binary_search_tree/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test bst_convert.c 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 d5f5fa4..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 *recursive(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 ? recursive(nums, lo, mid - 1) : NULL; - node->right = mid < hi ? recursive(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 recursive(nums, 0, i - 1); -} - -int main(int argc, char **argv) -{ - sortedListToBST(NULL); - return 0; -} diff --git a/110_balanced_binary_tree/Makefile b/110_balanced_binary_tree/Makefile deleted file mode 100644 index b36d4d9..0000000 --- a/110_balanced_binary_tree/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test balanced_bst.c diff --git a/111_minimum_depth_of_binary_tree/Makefile b/111_minimum_depth_of_binary_tree/Makefile deleted file mode 100644 index 5a375a6..0000000 --- a/111_minimum_depth_of_binary_tree/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test bst_depth.c diff --git a/112_path_sum/Makefile b/112_path_sum/Makefile deleted file mode 100644 index 770d42b..0000000 --- a/112_path_sum/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test path_sum.c diff --git a/113_path_sum_ii/Makefile b/113_path_sum_ii/Makefile deleted file mode 100644 index 770d42b..0000000 --- a/113_path_sum_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test path_sum.c 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/114_flatten_binary_tree_to_linked_list/Makefile b/114_flatten_binary_tree_to_linked_list/Makefile deleted file mode 100644 index b4afb6d..0000000 --- a/114_flatten_binary_tree_to_linked_list/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test flatten.c diff --git a/115_distinct_subsequences/Makefile b/115_distinct_subsequences/Makefile deleted file mode 100644 index 63c359e..0000000 --- a/115_distinct_subsequences/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test distinct_subseq.c diff --git a/116_populating_next_right_pointers_in_each_node/Makefile b/116_populating_next_right_pointers_in_each_node/Makefile deleted file mode 100644 index 3cc79a6..0000000 --- a/116_populating_next_right_pointers_in_each_node/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test connect.c diff --git a/117_populating_next_right_pointers_in_each_node_ii/Makefile b/117_populating_next_right_pointers_in_each_node_ii/Makefile deleted file mode 100644 index 3cc79a6..0000000 --- a/117_populating_next_right_pointers_in_each_node_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test connect.c diff --git a/118_pascal_triangle/Makefile b/118_pascal_triangle/Makefile deleted file mode 100644 index 41a60e8..0000000 --- a/118_pascal_triangle/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test pascal_triangle.c diff --git a/119_pascal_triangle_ii/Makefile b/119_pascal_triangle_ii/Makefile deleted file mode 100644 index 41a60e8..0000000 --- a/119_pascal_triangle_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test pascal_triangle.c diff --git a/120_triangle/Makefile b/120_triangle/Makefile deleted file mode 100644 index 44d928f..0000000 --- a/120_triangle/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test triangle.c diff --git a/121_best_time_to_buy_and_sell_stock/Makefile b/121_best_time_to_buy_and_sell_stock/Makefile deleted file mode 100644 index c638fbb..0000000 --- a/121_best_time_to_buy_and_sell_stock/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test stock.c diff --git a/122_best_time_to_buy_and_sell_stock_ii/Makefile b/122_best_time_to_buy_and_sell_stock_ii/Makefile deleted file mode 100644 index c638fbb..0000000 --- a/122_best_time_to_buy_and_sell_stock_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test stock.c diff --git a/123_best_time_to_buy_and_sell_stock_iii/Makefile b/123_best_time_to_buy_and_sell_stock_iii/Makefile deleted file mode 100644 index c638fbb..0000000 --- a/123_best_time_to_buy_and_sell_stock_iii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test stock.c diff --git a/124_binary_tree_maximum_path_sum/Makefile b/124_binary_tree_maximum_path_sum/Makefile deleted file mode 100644 index 2f04423..0000000 --- a/124_binary_tree_maximum_path_sum/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test bst_max_path.c diff --git a/125_valid_palindrome/Makefile b/125_valid_palindrome/Makefile deleted file mode 100644 index fc2acce..0000000 --- a/125_valid_palindrome/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test valid_palindrome.c diff --git a/126_word_ladder_ii/Makefile b/126_word_ladder_ii/Makefile deleted file mode 100644 index eb51704..0000000 --- a/126_word_ladder_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test word_ladder.c diff --git a/126_word_ladder_ii/word_ladder.c b/126_word_ladder_ii/word_ladder.c deleted file mode 100644 index a3aaa8d..0000000 --- a/126_word_ladder_ii/word_ladder.c +++ /dev/null @@ -1,319 +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_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 INIT_HLIST_NODE(struct hlist_node *n) { - n->next = NULL; - n->pprev = 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; -} - -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 { - 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.. - unsigned int hash = 0 ; - while (*str != '\0') { - hash = hash * seed + (*str++); - } - return hash % size; -} - -static struct word_node *find(char *word, struct hlist_head *hhead, int size, int step) -{ - struct hlist_node *p; - int hash = BKDRHash(word, size); - hlist_for_each(p, &hhead[hash]) { - struct word_node *node = list_entry(p, struct word_node, node); - if (!strcmp(node->word, word)) { - if (node->step == 0 || node->step == step) { - return node; - } - } - } - 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 *columnSizes array. - * * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). - * */ -static char*** findLadders(char* beginWord, char* endWord, char** wordList, int wordListSize, int** columnSizes, int* returnSize) -{ - int i, j, k; - int len = strlen(beginWord); - int hashsize = wordListSize * 2; - char *word = malloc(len + 1); - - struct hlist_head *hhead = malloc(hashsize * sizeof(*hhead)); - for (i = 0; i < hashsize; i++) { - INIT_HLIST_HEAD(hhead + i); - } - - struct list_head *level_heads = malloc(wordListSize * sizeof(*level_heads)); - for (i = 0; i < wordListSize; i++) { - INIT_LIST_HEAD(&level_heads[i]); - } - - /* Add into hash list */ - struct word_node *node; - 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]); - } - - struct list_head *p, queue; - INIT_LIST_HEAD(&queue); - - struct word_tree *root = malloc(sizeof(*root)); - 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); - if (node != NULL) { - node->step = 1; - } - - struct word_tree *first = root; - while (strcmp(first->word, endWord)) { - strcpy(word, first->word); - for (i = 0; i < len; i++) { - char c; - char o = word[i]; - for (c = 'a'; c <= 'z'; c++) { - word[i] = c; - node = find(word, hhead, 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)) { - enqueue = 0; - parent_add(first, w); - break; - } - } - - if (enqueue) { - node->step = first->step + 1; - struct word_tree *new = malloc(sizeof(*new)); - 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->link, &queue); - parent_add(first, new); - } - } - } - word[i] = o; - } - - if (list_empty(&queue)) { - *returnSize = 0; - return NULL; - } else { - first = list_first_entry(&queue, struct word_tree, 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); - 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]]; - } - - /* 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)); - move_on = 1; - break; - } - } - - i++; - } - } - } - - *columnSizes = malloc(i * sizeof(int)); - for (j = 0; j < i; j++) { - (*columnSizes)[j] = size; - } - *returnSize = i; - return results; -} - -int main(int argc, char **argv) -{ - if (argc < 3) { - fprintf(stderr, "Usage: ./test begin end dict...\n"); - exit(-1); - } - - int i, j, *sizes, count = 0; - char ***lists = findLadders(argv[1], argv[2], argv + 3, argc - 3, &sizes, &count); - for (i = 0; i < count; i++) { - for (j = 0; j < sizes[i]; j++) { - printf("%s ", lists[i][j]); - } - printf("\n"); - } - - return 0; -} diff --git a/127_word_ladder/Makefile b/127_word_ladder/Makefile deleted file mode 100644 index eb51704..0000000 --- a/127_word_ladder/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test word_ladder.c diff --git a/128_longest_consecutive_sequence/Makefile b/128_longest_consecutive_sequence/Makefile deleted file mode 100644 index 7b3d506..0000000 --- a/128_longest_consecutive_sequence/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test consec_seq.c diff --git a/128_longest_consecutive_sequence/consec_seq.c b/128_longest_consecutive_sequence/consec_seq.c deleted file mode 100644 index a290d5c..0000000 --- a/128_longest_consecutive_sequence/consec_seq.c +++ /dev/null @@ -1,132 +0,0 @@ -#include -#include - -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 INIT_HLIST_NODE(struct hlist_node *n) { - n->next = NULL; - n->pprev = 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; - } -} - -#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 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/129_sum_root_to_leaf_numbers/Makefile b/129_sum_root_to_leaf_numbers/Makefile deleted file mode 100644 index 013b36e..0000000 --- a/129_sum_root_to_leaf_numbers/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test sum_tree.c diff --git a/130_surrounded_regions/Makefile b/130_surrounded_regions/Makefile deleted file mode 100644 index 0743ff4..0000000 --- a/130_surrounded_regions/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test surrounded_regions.c 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/131_palindrome_patitioning/Makefile b/131_palindrome_patitioning/Makefile deleted file mode 100644 index 3179327..0000000 --- a/131_palindrome_patitioning/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test palindrome_partition.c diff --git a/132_palindrome_patitioning_ii/Makefile b/132_palindrome_patitioning_ii/Makefile deleted file mode 100644 index 3179327..0000000 --- a/132_palindrome_patitioning_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test palindrome_partition.c diff --git a/133_clone_graph/Makefile b/133_clone_graph/Makefile deleted file mode 100644 index 4e700dc..0000000 --- a/133_clone_graph/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test clone_graph.c diff --git a/133_clone_graph/clone_graph.c b/133_clone_graph/clone_graph.c deleted file mode 100644 index cea7f4d..0000000 --- a/133_clone_graph/clone_graph.c +++ /dev/null @@ -1,139 +0,0 @@ -#include -#include - -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 INIT_HLIST_NODE(struct hlist_node *n) { - n->next = NULL; - n->pprev = 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; - } -} - -#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 NEIGHBORS_MAX_SIZE 100 - -struct UndirectedGraphNode { - int label; - struct UndirectedGraphNode *neighbors[NEIGHBORS_MAX_SIZE]; - int neighborsCount; -}; - -struct label_node { - struct UndirectedGraphNode *gn; - struct hlist_node node; -}; - -static struct UndirectedGraphNode *find(int label, int size, struct hlist_head *heads) -{ - 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); - if (ln->gn->label == label) { - return ln->gn; - } - } - return NULL; -} - -static struct UndirectedGraphNode *recursive_clone(struct UndirectedGraphNode *graph, struct hlist_head *heads, int size) -{ - if (graph == NULL) { - return NULL; - } - - struct UndirectedGraphNode *node = find(graph->label, size, heads); - if (node != NULL) { - return node; - } - - node = malloc(sizeof(*node)); - node->label = graph->label; - node->neighborsCount = graph->neighborsCount; - 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]); - - int i; - for (i = 0; i < node->neighborsCount; i++) { - node->neighbors[i] = recursive_clone(graph->neighbors[i], heads, size); - } - - return node; -} - -static struct UndirectedGraphNode *cloneGraph(struct UndirectedGraphNode *graph) -{ - int i, cap = 1000; - struct hlist_head *heads = malloc(cap * sizeof(*heads)); - for (i = 0; i < cap; i++) { - INIT_HLIST_HEAD(&heads[i]); - } - - return recursive_clone(graph, heads, cap); -} - -int main(void) -{ - struct UndirectedGraphNode n0, n1, n2; - n0.label = 0; - n1.label = 1; - n2.label = 2; - n0.neighborsCount = 2; - n1.neighborsCount = 1; - n2.neighborsCount = 1; - n0.neighbors[0] = &n1; - n0.neighbors[1] = &n2; - n1.neighbors[0] = &n2; - n2.neighbors[0] = &n2; - - struct UndirectedGraphNode *res = cloneGraph(&n0); - return 0; -} diff --git a/134_gas_station/Makefile b/134_gas_station/Makefile deleted file mode 100644 index f2ca4c0..0000000 --- a/134_gas_station/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test gas_station.c diff --git a/135_candy/Makefile b/135_candy/Makefile deleted file mode 100644 index 36411f5..0000000 --- a/135_candy/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test candy.c diff --git a/136_single_number/Makefile b/136_single_number/Makefile deleted file mode 100644 index f992802..0000000 --- a/136_single_number/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test single_number.c 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/137_single_number_ii/Makefile b/137_single_number_ii/Makefile deleted file mode 100644 index f992802..0000000 --- a/137_single_number_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test single_number.c diff --git a/138_copy_list_with_random_pointer/Makefile b/138_copy_list_with_random_pointer/Makefile deleted file mode 100644 index 87e8a90..0000000 --- a/138_copy_list_with_random_pointer/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test copy_list.c diff --git a/138_copy_list_with_random_pointer/copy_list.c b/138_copy_list_with_random_pointer/copy_list.c deleted file mode 100644 index b35d708..0000000 --- a/138_copy_list_with_random_pointer/copy_list.c +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include - -struct RandomListNode { - int label; - struct RandomListNode *next; - struct RandomListNode *random; -}; - -static struct RandomListNode *copyRandomList(struct RandomListNode *head) -{ - if (head == NULL) { - return NULL; - } - - struct RandomListNode *p, *new; - for (p = head; p != NULL; p = p->next->next) { - new = malloc(sizeof(*new)); - new->label = p->label; - new->next = p->next; - p->next = new; - } - - for (p = head; p != NULL; p = p->next->next) { - new = p->next; - new->random = p->random != NULL ? p->random->next : NULL; - } - - struct RandomListNode dummy; - struct RandomListNode *prev = &dummy; - for (p = head; p != NULL; p = p->next) { - new = p->next; - p->next = new->next; - prev->next = new; - prev = new; - new->next = NULL; - } - - return dummy.next; -} - -int main(int argc, char **argv) -{ - int i, count = argc - 1; - struct RandomListNode *head = NULL, *p, *prev; - for (i = 0; i < count; i++) { - p = malloc(sizeof(*p)); - p->label = atoi(argv[i + 1]); - p->next = NULL; - p->random = NULL; - if (head == NULL) { - head = p; - } else { - prev->next = p; - prev->random = p; - } - prev = p; - } - - struct RandomListNode *r = head; - struct RandomListNode *q = p = copyRandomList(head); - - for (r = head; r != NULL; r = r->next) { - printf("%d ", r->label); - } - printf("\n"); - - for (r = head; r != NULL; r = r->random) { - printf("%d ", r->label); - } - printf("\n"); - - for (; p != NULL; p = p->next) { - printf("%d ", p->label); - } - printf("\n"); - - for (; q != NULL; q = q->random) { - printf("%d ", q->label); - } - printf("\n"); - return 0; -} diff --git a/139_word_break/Makefile b/139_word_break/Makefile deleted file mode 100644 index a9604bc..0000000 --- a/139_word_break/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test word_break.c diff --git a/139_word_break/word_break.c b/139_word_break/word_break.c deleted file mode 100644 index 9938b02..0000000 --- a/139_word_break/word_break.c +++ /dev/null @@ -1,180 +0,0 @@ -#include -#include -#include -#include - -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; -} - -#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 word_node { - char *word; - struct list_head link; -}; - -struct recur_cache { - int num; - int cap; - struct list_head **heads; -}; - -static struct recur_cache *resize(struct recur_cache **caches, int index) -{ - int i; - struct recur_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 recur_cache *recursive(char *s, char **words, int *sizes, int num, - struct recur_cache **caches, int len, int index) -{ - int i, j; - struct word_node *wn; - struct recur_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 recur_cache *next = recursive(s + sizes[i], words, sizes, num, caches, len, 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 recur_cache **caches = malloc(len * sizeof(*caches)); - memset(caches, 0, len * sizeof(*caches)); - return recursive(s, wordDict, sizes, wordDictSize, caches, len, 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/Makefile b/140_word_break_ii/Makefile deleted file mode 100644 index a9604bc..0000000 --- a/140_word_break_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test word_break.c diff --git a/140_word_break_ii/word_break.c b/140_word_break_ii/word_break.c deleted file mode 100644 index 97e4bac..0000000 --- a/140_word_break_ii/word_break.c +++ /dev/null @@ -1,208 +0,0 @@ -#include -#include -#include - -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; -} - -#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 word_node { - char *word; - struct list_head link; -}; - -struct recur_cache { - int num; - int cap; - struct list_head **heads; -}; - -static struct recur_cache *resize(struct recur_cache **caches, int index) -{ - int i; - struct recur_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 recur_cache *recursive(char *s, char **words, int *sizes, int num, - struct recur_cache **caches, int len, int index) -{ - int i, j; - struct word_node *wn; - struct recur_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 recur_cache *next = recursive(s + sizes[i], words, sizes, num, caches, len, 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 recur_cache **caches = malloc(len * sizeof(*caches)); - memset(caches, 0, len * sizeof(*caches)); - struct recur_cache *cache = recursive(s, wordDict, sizes, wordDictSize, caches, len, 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/141_linked_list_cycle/Makefile b/141_linked_list_cycle/Makefile deleted file mode 100644 index cf8bd0d..0000000 --- a/141_linked_list_cycle/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test list_cycle.c diff --git a/142_linked_list_cycle_ii/Makefile b/142_linked_list_cycle_ii/Makefile deleted file mode 100644 index cf8bd0d..0000000 --- a/142_linked_list_cycle_ii/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test list_cycle.c diff --git a/143_reorder_list/Makefile b/143_reorder_list/Makefile deleted file mode 100644 index c6ca20b..0000000 --- a/143_reorder_list/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test reorder_list.c diff --git a/143_reorder_list/reorder_list.c b/143_reorder_list/reorder_list.c deleted file mode 100644 index a8d220a..0000000 --- a/143_reorder_list/reorder_list.c +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include - -struct ListNode { - int val; - struct ListNode *next; -}; - -static void reverse(struct ListNode *dummy) -{ - struct ListNode *prev = dummy->next; - if (prev != NULL) { - struct ListNode *p = prev->next; - while (p != NULL) { - prev->next = p->next; - p->next = dummy->next; - dummy->next = p; - p = prev->next; - } - } -} - -static void reorderList(struct ListNode *head) -{ - if (head == NULL) { - return; - } - - int count = 0; - struct ListNode *p = head; - struct ListNode *q = p; - for (; p != NULL; p = p->next) { - if ((++count & 0x1) == 0) { - q = q->next; - } - } - - reverse(q); - - struct ListNode *r; - for (p = head, r = q->next; r != NULL; p = r->next, r = q->next) { - q->next = r->next; - r->next = p->next; - p->next = r; - } -} - -int main(int argc, char **argv) -{ - int i, count = argc - 1; - struct ListNode *head = NULL, *p, *prev; - for (i = 0; i < count; i++) { - p = malloc(sizeof(*p)); - p->val = atoi(argv[i + 1]); - p->next = NULL; - if (head == NULL) { - head = p; - } else { - prev->next = p; - } - prev = p; - } - - reorderList(head); - for (p = head; p != NULL; p = p->next) { - printf("%d ", p->val); - } - printf("\n"); - return 0; -} diff --git a/144_binary_tree_preorder_traversal/Makefile b/144_binary_tree_preorder_traversal/Makefile deleted file mode 100644 index f08c087..0000000 --- a/144_binary_tree_preorder_traversal/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test bst_preorder.c diff --git a/145_binary_tree_postorder_traversal/Makefile b/145_binary_tree_postorder_traversal/Makefile deleted file mode 100644 index c35a74f..0000000 --- a/145_binary_tree_postorder_traversal/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test bst_postorder.c diff --git a/146_lru_cache/Makefile b/146_lru_cache/Makefile deleted file mode 100644 index b64babf..0000000 --- a/146_lru_cache/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test lru_cache.c diff --git a/146_lru_cache/lru_cache.c b/146_lru_cache/lru_cache.c deleted file mode 100644 index a11558f..0000000 --- a/146_lru_cache/lru_cache.c +++ /dev/null @@ -1,300 +0,0 @@ -#include -#include - -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 INIT_HLIST_NODE(struct hlist_node *n) { - n->next = NULL; - n->pprev = 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; - } -} - -#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 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)); - INIT_HLIST_NODE(&cache->node); - INIT_LIST_HEAD(&cache->link); - /* Add into hash list */ - hlist_add_head(&cache->node, &obj->hhead[hash]); - /* Add into double list */ - 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/147_insertion_sort_list/Makefile b/147_insertion_sort_list/Makefile deleted file mode 100644 index 576b707..0000000 --- a/147_insertion_sort_list/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test insert_sort_list.c diff --git a/148_sort_list/Makefile b/148_sort_list/Makefile deleted file mode 100644 index c8c671c..0000000 --- a/148_sort_list/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test sort_list.c diff --git a/149_max_points_on_a_line/Makefile b/149_max_points_on_a_line/Makefile deleted file mode 100644 index b3597be..0000000 --- a/149_max_points_on_a_line/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test points_on_line.c diff --git a/150_evaluate_reverse_polish_notation/Makefile b/150_evaluate_reverse_polish_notation/Makefile deleted file mode 100644 index 173a84c..0000000 --- a/150_evaluate_reverse_polish_notation/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -all: - gcc -O2 -o test eval_rpn.c 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. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy