diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f11b75 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea/ diff --git a/README.md b/README.md index 7b1cfe5..761de71 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # leetcode -the algorithm codes of LeetCode OJ(https://leetcode.com/problemset/algorithms/) +The solutions of [LeetCode Algorithms](https://leetcode.com/problemset/algorithms/) -those codes are implemented by C languages +Those codes are implemented by C, C++, Python and Go. +# Star History + +[![Star History Chart](https://api.star-history.com/svg?repos=lightmen/leetcode&type=Date)](https://star-history.com/#lightmen/leetcode&Date) diff --git a/c/array/3sum-closest.c b/c/array/3sum-closest.c new file mode 100644 index 0000000..e971e49 --- /dev/null +++ b/c/array/3sum-closest.c @@ -0,0 +1,27 @@ +static int cmp(void *a, void *b) +{ + return *(int *)a - *(int *)b; +} + +int threeSumClosest(int* nums, int numsSize, int target) { + int i,start,end; + int ret = nums[0] + nums[1] + nums[2]; + int sum; + + qsort(nums,numsSize,sizeof(int),cmp); + for(i = 0; i < numsSize - 2; ++i){ + start = i + 1; + end = numsSize - 1; + while(start < end){ + sum = nums[i] + nums[start] + nums[end]; + if(abs(ret - target) > abs(sum - target)) + ret = sum; + if(sum > target) + --end; + else + ++start; + } + } + + return ret; +} diff --git a/c/array/3sum.c b/c/array/3sum.c new file mode 100644 index 0000000..aea518f --- /dev/null +++ b/c/array/3sum.c @@ -0,0 +1,58 @@ +/** + * Return an array of arrays of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +static int cmp(const void *a, const void *b) +{ + return *(const int *)a - *(const int *)b; +} + +int *get_3sum(int a, int b, int c) +{ + int *ret = (int *)malloc(sizeof(int) * 3); + ret[0] = a; + ret[1] = b; + ret[2] = c; + return ret; +} + +int** threeSum(int* nums, int numsSize, int* returnSize) { + int i,start,end,sum; + int size = 0; + int count = 500; + int **arr; + + qsort(nums,numsSize,sizeof(int),cmp); + arr = (int **)malloc(sizeof(int *) * count); + for(i = 0; i < numsSize - 2; ++i){ + if(i > 0 && nums[i] == nums[i-1]) + continue; + + start = i + 1; + end = numsSize - 1; + while(start < end){ + sum = nums[i] + nums[start] + nums[end]; + + if(start > i + 1 && nums[start-1] == nums[start]){ + ++start; + continue; + } + + if(sum == 0){ + arr[size++] = get_3sum(nums[i],nums[start],nums[end]); + if(size == count){ + count <<= 1; + arr = realloc(arr,sizeof(int *) * count); + } + } + + if(sum > 0) + --end; + else + ++start; + } + } + + *returnSize = size; + return arr; +} diff --git a/c/array/4sum.c b/c/array/4sum.c new file mode 100644 index 0000000..86c1fa5 --- /dev/null +++ b/c/array/4sum.c @@ -0,0 +1,66 @@ +/** + * Return an array of arrays of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +static int cmp(const void *a, const void *b) +{ + return *(const int *)a - *(const int *)b; +} + +int *get_4sum(int a, int b, int c, int d) +{ + int *ret = (int *)malloc(sizeof(int) * 4); + ret[0] = a; + ret[1] = b; + ret[2] = c; + ret[3] = d; + + return ret; +} + +int** fourSum(int* nums, int numsSize, int target, int* returnSize) { + int i,j,start,end; + int sum; + int **arr; + int size = 0; + int count = 500; + + arr = (int **)malloc(sizeof(int *) * count); + + qsort(nums,numsSize, sizeof(int),cmp); + for(i = 0; i < numsSize - 3; ++i){ + if(i > 0 && nums[i] == nums[i-1]) + continue; + + for(j = i + 1; j < numsSize - 2; ++j){ + if(j > i + 1 && nums[j] == nums[j-1]) + continue; + + start = j + 1; + end = numsSize - 1; + while(start < end){ + if(start > j + 1 && nums[start] == nums[start-1]){ + start++; + continue; + } + + sum = nums[i] + nums[j] + nums[start] + nums[end]; + if(sum == target){ + arr[size++] = get_4sum(nums[i],nums[j],nums[start],nums[end]); + if(size >= count){ + count <<= 1; + arr = realloc(arr,sizeof(int *) * count); + } + } + + if(sum > target) + --end; + else + ++start; + } + } + } + + *returnSize = size; + return arr; +} diff --git a/c/array/best-time-to-buy-and-sell-stock-ii.c b/c/array/best-time-to-buy-and-sell-stock-ii.c new file mode 100644 index 0000000..bee28c6 --- /dev/null +++ b/c/array/best-time-to-buy-and-sell-stock-ii.c @@ -0,0 +1,10 @@ +int maxProfit(int* prices, int pricesSize) { + int ret = 0; + int i; + + for(i = 1; i < pricesSize; ++i) + if(prices[i] > prices[i-1]) + ret += prices[i] - prices[i-1]; + + return ret; +} diff --git a/c/array/best-time-to-buy-and-sell-stock-iii.c b/c/array/best-time-to-buy-and-sell-stock-iii.c new file mode 100644 index 0000000..10488fd --- /dev/null +++ b/c/array/best-time-to-buy-and-sell-stock-iii.c @@ -0,0 +1,35 @@ +int maxProfit(int* prices, int pricesSize) { + int *left,*right; + int min,max; + int diff; + int i; + int ret = 0; + + left = (int *)malloc(sizeof(int) * pricesSize); + right = (int *)malloc(sizeof(int) * pricesSize); + + min = prices[0]; + left[0] = 0; + for(i = 1; i < pricesSize; ++i){ + min = prices[i] < min ? prices[i] : min; + diff = prices[i] - min; + left[i] = diff > left[i-1] ? diff : left[i-1]; + } + + max = prices[pricesSize-1]; + right[pricesSize-1] = 0; + for(i = pricesSize-2; i >= 0; --i){ + max = prices[i] > max ? prices[i] : max; + diff = max - prices[i]; + right[i] = diff > right[i+1] ? diff : right[i+1]; + } + + for(i = 0; i < pricesSize; ++i){ + if(left[i] + right[i] > ret) + ret = left[i] + right[i]; + } + + free(left); + free(right); + return ret; +} diff --git a/c/array/best-time-to-buy-and-sell-stock.c b/c/array/best-time-to-buy-and-sell-stock.c new file mode 100644 index 0000000..c35bb8c --- /dev/null +++ b/c/array/best-time-to-buy-and-sell-stock.c @@ -0,0 +1,23 @@ +int maxProfit(int* prices, int pricesSize) { + int ret = 0; + int *left; + int *right; + int i; + left = (int *)malloc(sizeof(int) * pricesSize); + right = (int *)malloc(sizeof(int) * pricesSize); + + left[0] = prices[0]; + for(i = 1; i < pricesSize; ++i) + left[i] = prices[i] < left[i-1] ? prices[i] : left[i-1]; + + right[pricesSize-1] = prices[pricesSize-1]; + for(i = pricesSize-2; i >= 0; --i) + right[i] = prices[i] > right[i+1] ? prices[i] : right[i+1]; + + for(i = 0; i < pricesSize-1; ++i) + ret = right[i+1] - left[i] > ret ? right[i+1] - left[i] : ret; + + free(left); + free(right); + return ret; +} diff --git a/c/array/best-time-to-buy-and-sell-stock[2].c b/c/array/best-time-to-buy-and-sell-stock[2].c new file mode 100644 index 0000000..e4d3349 --- /dev/null +++ b/c/array/best-time-to-buy-and-sell-stock[2].c @@ -0,0 +1,12 @@ +int maxProfit(int* prices, int pricesSize) { + int min = INT_MAX; + int i; + int ret = 0; + + for(i = 0; i < pricesSize; ++i){ + min = prices[i] < min ? prices[i] : min; + ret = prices[i] - min > ret ? prices[i] - min : ret; + } + + return ret; +} diff --git a/c/array/combination-sum-ii.c b/c/array/combination-sum-ii.c new file mode 100644 index 0000000..4bcc2dd --- /dev/null +++ b/c/array/combination-sum-ii.c @@ -0,0 +1,69 @@ +/** + * 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 top; +int count; +int alloc_size; +int *data; +int **ret; +int *col; + +int *get_array(int *src, int len) +{ + int *dst = (int *)malloc(sizeof(int) * len); + memcpy(dst,src,sizeof(int) * len); + return dst; +} + +void helper(int *candidates, int candidatesSize, int index, int diff) +{ + if(diff == 0){ + col[count] = top; + ret[count++] = get_array(data,top); + if(count == alloc_size){ + alloc_size <<= 1; + col = realloc(col,sizeof(int) * alloc_size); + ret = realloc(ret,sizeof(int *) * alloc_size); + } + return ; + } + + int i; + for(i = index; i < candidatesSize; ++i){ + if(candidates[i] > diff) + break; + if(i > index && candidates[i] == candidates[i-1]) + continue; + data[top++] = candidates[i]; + helper(candidates,candidatesSize,i+1,diff - candidates[i]); + top--; + } +} + +static int cmp(const void *a, const void *b) +{ + return *(const int *)a - *(const int *)b; +} + +int** combinationSum2(int* candidates, int candidatesSize, + int target, int** columnSizes, int* returnSize) +{ + top = 0; + count= 0; + alloc_size = 500; + + ret = (int **)malloc(sizeof(int *) * alloc_size); + col = (int *)malloc(sizeof(int *) * alloc_size); + data = (int *)malloc(sizeof(int *) * target); + + qsort(candidates,candidatesSize,sizeof(int),cmp); + + helper(candidates,candidatesSize,0,target); + *columnSizes = col; + *returnSize = count; + + return ret; +} diff --git a/c/array/combination-sum-iii.c b/c/array/combination-sum-iii.c new file mode 100644 index 0000000..88e13af --- /dev/null +++ b/c/array/combination-sum-iii.c @@ -0,0 +1,60 @@ +/** + * 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 top; +int count; +int alloc_size; +int *data; +int **ret; +int *col; + +int *get_array(int *src, int len) +{ + int *dst = (int *)malloc(sizeof(int) * len); + memcpy(dst,src,sizeof(int) * len); + return dst; +} + +void helper(int index, int k, int diff) +{ + if(top == k && diff == 0){ + col[count] = top; + ret[count++] = get_array(data,top); + if(count == alloc_size){ + alloc_size <<= 1; + col = realloc(col,sizeof(int) * alloc_size); + ret = realloc(ret,sizeof(int *) * alloc_size); + } + return ; + } + if(top == k || diff == 0) + return ; + + int i; + for(i = index; i <= 9; ++i){ + if(i > diff) + break; + data[top++] = i; + helper(i+1,k,diff - i); + top--; + } +} + +int** combinationSum3(int k, int n, int** columnSizes, int* returnSize) { + top = 0; + count= 0; + alloc_size = 500; + + ret = (int **)malloc(sizeof(int *) * alloc_size); + col = (int *)malloc(sizeof(int *) * alloc_size); + data = (int *)malloc(sizeof(int *) * 9); + + helper(1,k,n); + + *columnSizes = col; + *returnSize = count; + return ret; +} diff --git a/c/array/combination-sum.c b/c/array/combination-sum.c new file mode 100644 index 0000000..1ccc6d6 --- /dev/null +++ b/c/array/combination-sum.c @@ -0,0 +1,70 @@ +/** + * 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 top; +int *data; +int **ret; +int count; +int alloc_size; +int *col; + +int *get_array(int *arr, int size) +{ + int *tmp = (int *)malloc(sizeof(int) * size); + memcpy(tmp,arr,sizeof(int) * size); + return tmp; +} + +void helper(int *candidates, int candidatesSize, int index, int diff) +{ + if(diff == 0){ + col[count] = top; + ret[count++] = get_array(data,top); + if(count == alloc_size){ + alloc_size <<= 1; + ret = realloc(ret,sizeof(int *) * alloc_size); + col = realloc(col,sizeof(int) * alloc_size); + } + return ; + } + + int i; + for(i = index; i < candidatesSize; ++i){ + if(candidates[i] > diff) + break; + if(i > index && candidates[i] == candidates[i-1]) + continue; + + data[top++] = candidates[i]; + helper(candidates,candidatesSize,i,diff - candidates[i]); + top--; + } +} + +static int cmp(const void *a, const void *b) +{ + return *(const int *)a - *(const int *)b; +} + +int** combinationSum(int* candidates, int candidatesSize, + int target, int** columnSizes, int* returnSize) +{ + top = 0; + count = 0; + alloc_size = 500; + + ret = (int **)malloc(sizeof(int *) * alloc_size); + col = (int *)malloc(sizeof(int) * alloc_size); + data = (int *)malloc(sizeof(int) * target); + + qsort(candidates,candidatesSize,sizeof(int),cmp); + helper(candidates,candidatesSize,0,target); + + *columnSizes = col; + *returnSize = count; + + return ret; +} diff --git a/c/array/combination-sum.cpp b/c/array/combination-sum.cpp new file mode 100644 index 0000000..be274d1 --- /dev/null +++ b/c/array/combination-sum.cpp @@ -0,0 +1,27 @@ +class Solution { +public: + vector > vret; + void helper(vector &vi, vector& candidates, int index, int diff) + { + if(diff == 0){ + vret.push_back(vi); + return ; + } + + int size = candidates.size(); + for(int i = index; i < size; ++i){ + if(candidates[i] > diff) + break; + vi.push_back(candidates[i]); + helper(vi,candidates,i,diff-candidates[i]); + vi.pop_back(); + } + } + + vector> combinationSum(vector& candidates, int target) { + vector vi; + sort(candidates.begin(),candidates.end()); + helper(vi,candidates,0,target); + return vret; + } +}; diff --git a/c/array/construct-binary-tree-from-inorder-and-postorder-traversal.c b/c/array/construct-binary-tree-from-inorder-and-postorder-traversal.c new file mode 100644 index 0000000..911c9b6 --- /dev/null +++ b/c/array/construct-binary-tree-from-inorder-and-postorder-traversal.c @@ -0,0 +1,33 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +struct TreeNode *helper(int *inorder, int in_start, int in_end, + int *postorder, int post_start, int post_end) +{ + if(in_end < in_start) + return NULL; + + struct TreeNode *root = (struct TreeNode *)malloc(sizeof(struct TreeNode)); + root->val = postorder[post_end]; + + int mid; + for(mid = in_start; mid <= in_end; ++mid) + if(inorder[mid] == postorder[post_end]) + break; + + root->left = helper(inorder,in_start,mid-1,postorder,post_start,post_start+mid-in_start-1); + root->right = helper(inorder,mid+1,in_end,postorder,post_start+mid-in_start,post_end-1); + + return root; +} + +struct TreeNode* buildTree(int* inorder, int inorderSize, int* postorder, int postorderSize) { + if(inorderSize == 0) + return NULL; + return helper(inorder,0,inorderSize-1,postorder,0,postorderSize-1); +} diff --git a/c/array/construct-binary-tree-from-preorder-and-inorder-traversal.c b/c/array/construct-binary-tree-from-preorder-and-inorder-traversal.c new file mode 100644 index 0000000..2c2f34a --- /dev/null +++ b/c/array/construct-binary-tree-from-preorder-and-inorder-traversal.c @@ -0,0 +1,33 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +struct TreeNode *helper(int *preorder, int pre_start, int pre_end, + int *inorder, int in_start, int in_end) +{ + if(in_end < in_start) + return NULL; + + struct TreeNode *root = (struct TreeNode *)malloc(sizeof(struct TreeNode)); + root->val = preorder[pre_start]; + + int mid; + for(mid = in_start; mid <= in_end; ++mid) + if(inorder[mid] == preorder[pre_start]) + break; + + root->left = helper(preorder,pre_start+1,pre_start+mid-in_start,inorder,in_start,mid-1); + root->right = helper(preorder,pre_start+mid-in_start + 1,pre_end,inorder,mid+1,in_end); + + return root; +} +struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize) { + if(inorderSize == 0) + return NULL; + + return helper(preorder,0,preorderSize-1,inorder,0,inorderSize-1); +} diff --git a/c/array/container-with-most-water.c b/c/array/container-with-most-water.c new file mode 100644 index 0000000..d8b46a2 --- /dev/null +++ b/c/array/container-with-most-water.c @@ -0,0 +1,21 @@ +int maxArea(int* height, int heightSize) { + int ret = 0; + int start,end; + int mul; + + start = 0; + end = heightSize-1; + while(start < end){ + if(height[start] < height[end]){ + mul = height[start] * (end - start); + ++start; + }else{ + mul = height[end] * (end - start); + --end; + } + + ret = mul > ret ? mul : ret; + } + + return ret; +} diff --git a/c/array/contains-duplicate-ii.c b/c/array/contains-duplicate-ii.c new file mode 100644 index 0000000..5140dc9 --- /dev/null +++ b/c/array/contains-duplicate-ii.c @@ -0,0 +1,11 @@ +bool containsNearbyDuplicate(int* nums, int numsSize, int k) { + int i,j; + + for(i = 0; i < numsSize; ++i){ + for(j = i+1; j <= i+k && j < numsSize; ++j) + if(nums[j] == nums[i]) + return true; + } + + return false; +} diff --git a/c/array/contains-duplicate.c b/c/array/contains-duplicate.c new file mode 100644 index 0000000..af955e0 --- /dev/null +++ b/c/array/contains-duplicate.c @@ -0,0 +1,14 @@ +static int cmp(const void *a, const void *b) +{ + return *(const int *)a - *(const int *)b; +} + +bool containsDuplicate(int* nums, int numsSize) { + qsort(nums,numsSize,sizeof(int),cmp); + + for(int i = 1; i < numsSize; ++i) + if(nums[i] == nums[i-1]) + return true; + + return false; +} diff --git a/c/array/find-minimum-in-rotated-sorted-array-ii.c b/c/array/find-minimum-in-rotated-sorted-array-ii.c new file mode 100644 index 0000000..bfcdec1 --- /dev/null +++ b/c/array/find-minimum-in-rotated-sorted-array-ii.c @@ -0,0 +1,17 @@ +int findMin(int* nums, int numsSize) { + int start,end,mid; + start = 0; + end = numsSize - 1; + + while(start < end){ + mid = start + (end - start) / 2; + if(nums[mid] > nums[end]) + start = mid + 1; + else if(nums[mid] < nums[end]) + end = mid; + else + --end; + } + + return nums[start]; +} diff --git a/c/array/find-minimum-in-rotated-sorted-array.c b/c/array/find-minimum-in-rotated-sorted-array.c new file mode 100644 index 0000000..0a8b0eb --- /dev/null +++ b/c/array/find-minimum-in-rotated-sorted-array.c @@ -0,0 +1,14 @@ +int findMin(int* nums, int numsSize) { + int start,end,mid; + start = 0; + end = numsSize - 1; + while(start + 1 < end){ + mid = start + (end - start) / 2; + if(nums[mid] > nums[end]) + start = mid; + else + end = mid; + } + + return nums[start] < nums[end] ? nums[start] : nums[end]; +} diff --git a/c/array/find-minimum-in-rotated-sorted-array[1].c b/c/array/find-minimum-in-rotated-sorted-array[1].c new file mode 100644 index 0000000..3d82a30 --- /dev/null +++ b/c/array/find-minimum-in-rotated-sorted-array[1].c @@ -0,0 +1,15 @@ +int findMin(int* nums, int numsSize) { + int start,end,mid; + start = 0; + end = numsSize - 1; + + while(start < end){ + mid = start + (end - start) / 2; + if(nums[mid] > nums[end]) + start = mid + 1; + else + end = mid; + } + + return nums[start]; +} diff --git a/c/array/find-peak-element.c b/c/array/find-peak-element.c new file mode 100644 index 0000000..636d20a --- /dev/null +++ b/c/array/find-peak-element.c @@ -0,0 +1,8 @@ +int findPeakElement(int* nums, int numsSize) { + int i; + for(i = 1; i < numsSize; ++i) + if(nums[i-1] > nums[i]) + return i-1; + + return numsSize - 1; +} diff --git a/c/array/find-peak-element[1].c b/c/array/find-peak-element[1].c new file mode 100644 index 0000000..d29ef9b --- /dev/null +++ b/c/array/find-peak-element[1].c @@ -0,0 +1,15 @@ +int findPeakElement(int* nums, int numsSize) { + int start,end,mid; + start = 0; + end = numsSize - 1; + + while(start < end){ + mid = start + (end - start) / 2; + if(nums[mid] < nums[mid+1]) + start = mid + 1; + else + end = mid; + } + + return start; +} diff --git a/c/array/first-missing-positive.c b/c/array/first-missing-positive.c new file mode 100644 index 0000000..1fb4a23 --- /dev/null +++ b/c/array/first-missing-positive.c @@ -0,0 +1,20 @@ +int firstMissingPositive(int* nums, int numsSize) { + int i = 0; + + while(i < numsSize){ + if(nums[i] <= 0 || nums[i] >= numsSize || nums[i] == i + 1 + || nums[i] == nums[nums[i] - 1]){ + ++i; + }else{ + int tmp = nums[i]; + nums[i] = nums[nums[i] - 1]; + nums[tmp-1] = tmp; + } + } + + for(i = 0; i < numsSize; ++i) + if(nums[i] != i + 1) + break; + + return i + 1; +} diff --git a/c/array/insert-interval.c b/c/array/insert-interval.c new file mode 100644 index 0000000..f038cc0 --- /dev/null +++ b/c/array/insert-interval.c @@ -0,0 +1,47 @@ +/** + * Definition for an interval. + * struct Interval { + * int start; + * int end; + * }; + */ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +struct Interval* insert(struct Interval* intervals, int intervalsSize, + struct Interval newInterval, int* returnSize) { + struct Interval *ret; + int count = 0; + int i; + + ret = (struct Interval *)malloc(sizeof(struct Interval) * (intervalsSize + 1)); + + for(i = 0; i < intervalsSize; ++i){ + if(intervals[i].end < newInterval.start){ + ret[count].start = intervals[i].start; + ret[count].end = intervals[i].end; + count++; + }else if(intervals[i].start > newInterval.end){ + break; + }else{ + newInterval.start = intervals[i].start < newInterval.start ? + intervals[i].start : newInterval.start; + newInterval.end = intervals[i].end > newInterval.end ? + intervals[i].end : newInterval.end; + } + } + + ret[count].start = newInterval.start; + ret[count].end = newInterval.end; + count++; + + for(; i < intervalsSize; ++i){ + ret[count].start = intervals[i].start; + ret[count].end = intervals[i].end; + count++; + } + + *returnSize = count; + return ret; +} diff --git a/c/array/jump-game-ii.c b/c/array/jump-game-ii.c new file mode 100644 index 0000000..be9d461 --- /dev/null +++ b/c/array/jump-game-ii.c @@ -0,0 +1,18 @@ +int jump(int* nums, int numsSize) { + int ret = 0; + int i; + int cur_pos,max_pos; + + cur_pos = 0; + max_pos = 0; + for(i = 0; i < numsSize; ++i){ + if(cur_pos < i){ + ret++; + cur_pos = max_pos; + } + if(nums[i] + i > max_pos) + max_pos = nums[i] + i; + } + + return ret; +} diff --git a/c/array/jump-game.c b/c/array/jump-game.c new file mode 100644 index 0000000..9f1078b --- /dev/null +++ b/c/array/jump-game.c @@ -0,0 +1,16 @@ +bool canJump(int* nums, int numsSize) { + int i = 0; + int max_jump = nums[0]; + + while(max_jump < numsSize-1){ + int max = max_jump; + for(; i <= max_jump; ++i) + if(i + nums[i] > max) + max = i + nums[i]; + if(max_jump == max) + return false; + max_jump = max; + } + + return true; +} diff --git a/c/array/largest-rectangle-in-histogram.c b/c/array/largest-rectangle-in-histogram.c new file mode 100644 index 0000000..af39fb6 --- /dev/null +++ b/c/array/largest-rectangle-in-histogram.c @@ -0,0 +1,24 @@ +int largestRectangleArea(int* height, int heightSize) { + int *stack; + int top = -1; + int max = 0; + int i,curh; + + stack = (int *)malloc(sizeof(int) * heightSize); + + for(i = 0; i <= heightSize; ++i){ + curh = (i == heightSize) ? -1 : height[i]; + + while(top != -1 && curh <= height[stack[top]]){ + int h = height[stack[top--]]; + int w = (top == -1) ? i : i - stack[top] - 1; + + if(h * w > max) + max = h * w; + } + stack[++top] = i; + } + + free(stack); + return max; +} diff --git a/c/array/longest-consecutive-sequence.cpp b/c/array/longest-consecutive-sequence.cpp new file mode 100644 index 0000000..3eb1162 --- /dev/null +++ b/c/array/longest-consecutive-sequence.cpp @@ -0,0 +1,30 @@ +class Solution { +public: + int longestConsecutive(vector& nums) { + unordered_map umap; + int ret = 0; + int size = nums.size(); + + for(int i = 0; i < size; ++i) + umap[nums[i]] = true; + + for(int i = 0; i < size; ++i){ + int up = nums[i]; + while(umap.find(up) != umap.end()){ + umap.erase(up); + up++; + } + + int down = nums[i] - 1; + while(umap.find(down) != umap.end()){ + umap.erase(down); + down--; + } + + if(up - down - 1 > ret) + ret = up - down - 1; + } + + return ret; + } +}; diff --git a/c/array/majority-element-ii.c b/c/array/majority-element-ii.c new file mode 100644 index 0000000..4a829c7 --- /dev/null +++ b/c/array/majority-element-ii.c @@ -0,0 +1,60 @@ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* majorityElement(int* nums, int numsSize, int* returnSize) { + int *ret; + int c1,c2,arr1,arr2; + int i; + int size = 0; + + arr1 = nums[0]; + arr2 = nums[0]; + c1 = 0; + c2 = 0; + for(i = 0; i < numsSize; ++i){ + if(arr1 == nums[i]){ + c1++; + continue; + } + + if(arr2 == nums[i]){ + c2++; + continue; + } + + if(c1 == 0){ + arr1 = nums[i]; + c1++; + continue; + } + + if(c2 == 0){ + arr2 = nums[i]; + c2++; + continue; + } + + c1--; + c2--; + } + + c1 = 0; + c2 = 0; + for(i = 0; i < numsSize; ++i){ + if(arr1 == nums[i]) + c1++; + else if(arr2 == nums[i]) + c2++; + } + + ret = (int *)malloc(sizeof(int) * 2); + if(c1 > numsSize / 3) + ret[size++] = arr1; + if(c2 > numsSize / 3) + ret[size++] = arr2; + + *returnSize = size; + + return ret; +} diff --git a/c/array/majority-element.c b/c/array/majority-element.c new file mode 100644 index 0000000..52f648b --- /dev/null +++ b/c/array/majority-element.c @@ -0,0 +1,17 @@ +int majorityElement(int* nums, int numsSize) { + int count; + int ret; + int i; + + count = 0; + for(i = 0; i < numsSize; ++i){ + if(count == 0) + ret = nums[i]; + if(ret == nums[i]) + count++; + else + count--; + } + + return ret; +} diff --git a/c/array/maximal-rectangle.c b/c/array/maximal-rectangle.c new file mode 100644 index 0000000..c8d07c2 --- /dev/null +++ b/c/array/maximal-rectangle.c @@ -0,0 +1,52 @@ +int get_maxarea(int *height, int size) +{ + int *stack; + int top = -1; + int i; + int cur; + int ret = 0; + + stack = (int *)malloc(sizeof(int) * size); + + for(i = 0; i <= size; ++i){ + cur = i == size ? -1 : height[i]; + while(top != -1 && cur <= height[stack[top]]){ + int h = height[stack[top--]]; + int w = top == -1 ? i : i - stack[top] - 1; + + if(h * w > ret) + ret = h * w; + } + stack[++top] = i; + } + + free(stack); + return ret; +} + +int maximalRectangle(char** matrix, int matrixRowSize, int matrixColSize) { + int *height; + int i,j; + int max_area = 0; + int area; + + height = (int *)malloc(sizeof(int) * matrixColSize); + memset(height,0,sizeof(int) * matrixColSize); + + for(i = 0; i < matrixRowSize; ++i){ + for(j = 0; j < matrixColSize; ++j){ + if(matrix[i][j] == '0') + height[j] = 0; + else + height[j]++; + } + + area = get_maxarea(height,matrixColSize); + + if(area > max_area) + max_area = area; + } + + free(height); + return max_area; +} diff --git a/c/array/maximum-product-subarray.c b/c/array/maximum-product-subarray.c new file mode 100644 index 0000000..2fab5cb --- /dev/null +++ b/c/array/maximum-product-subarray.c @@ -0,0 +1,35 @@ +int maxProduct(int* nums, int numsSize) { + int ret; + int i; + int *min; + int *max; + + min = (int *)malloc(sizeof(int) * numsSize); + max = (int *)malloc(sizeof(int) * numsSize); + + + min[0] = nums[0]; + max[0] = nums[0]; + ret = nums[0]; + + for(i = 1; i < numsSize; ++i){ + min[i] = max[i] = nums[i]; + if(nums[i] > 0){ + max[i] = (max[i-1] * nums[i] > max[i]) ? + max[i-1] * nums[i] : max[i]; + min[i] = (min[i-1] * nums[i] < min[i]) ? + min[i-1] * nums[i] : min[i]; + }else if(nums[i] < 0){ + max[i] = (min[i-1] * nums[i] > max[i]) ? + min[i-1] * nums[i] : max[i]; + min[i] = (max[i-1] * nums[i] < min[i]) ? + max[i-1] * nums[i] : min[i]; + } + + ret = max[i] > ret ? max[i] : ret; + } + + free(min); + free(max); + return ret; +} diff --git a/c/array/maximum-subarray.c b/c/array/maximum-subarray.c new file mode 100644 index 0000000..a30a4d3 --- /dev/null +++ b/c/array/maximum-subarray.c @@ -0,0 +1,13 @@ +int maxSubArray(int* nums, int numsSize) { + int i; + int ret = nums[0]; + int cur = 0; + + for(i = 0; i < numsSize; ++i){ + cur += nums[i]; + ret = cur > ret ? cur : ret; + cur = cur > 0 ? cur : 0; + } + + return ret; +} diff --git a/c/array/median-of-two-sorted-arrays.c b/c/array/median-of-two-sorted-arrays.c new file mode 100644 index 0000000..581a5e3 --- /dev/null +++ b/c/array/median-of-two-sorted-arrays.c @@ -0,0 +1,26 @@ +double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { + int *arr; + int num = nums1Size + nums2Size; + int i,j,k; + double ret; + + arr = (int *)malloc(sizeof(int) * num); + i = 0; + j = 0; + k = 0; + while(i < nums1Size && j < nums2Size) + arr[k++] = nums1[i] < nums2[j] ? nums1[i++] : nums2[j++]; + + while(i < nums1Size) + arr[k++] = nums1[i++]; + while(j < nums2Size) + arr[k++] = nums2[j++]; + + if(num % 2) + ret = arr[num/2]; + else + ret = (arr[(num-1)/2] + arr[num/2]) / 2.0; + + free(arr); + return ret; +} diff --git a/c/array/median-of-two-sorted-arrays[1].c b/c/array/median-of-two-sorted-arrays[1].c new file mode 100644 index 0000000..65e11c8 --- /dev/null +++ b/c/array/median-of-two-sorted-arrays[1].c @@ -0,0 +1,34 @@ +int len1; +int len2; + +int findKth(int a[], int a_start, int b[], int b_start, int k) +{ + if(a_start >= len1) + return b[b_start + k - 1]; + if(b_start >= len2) + return a[a_start + k - 1]; + if(k == 1) + return a[a_start] < b[b_start] ? a[a_start] : b[b_start]; + + int a_key = a_start + k / 2 - 1 < len1 ? + a[a_start + k / 2 - 1] : INT_MAX; + int b_key = b_start + k / 2 - 1 < len2 ? + b[b_start + k / 2 - 1] : INT_MAX; + + if(a_key < b_key) + return findKth(a,a_start + k / 2, b, b_start, k - k / 2); + else + return findKth(a,a_start, b, b_start + k / 2, k - k / 2); +} + +double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { + int len; + len1 = nums1Size; + len2 = nums2Size; + + len = len1 + len2; + if(len % 2) + return findKth(nums1,0,nums2,0,len/2 + 1); + else + return (findKth(nums1,0,nums2,0,len/2) + findKth(nums1,0,nums2,0,len/2 + 1)) / 2.0; +} diff --git a/c/array/merge-sorted-array.c b/c/array/merge-sorted-array.c new file mode 100644 index 0000000..7fb2f82 --- /dev/null +++ b/c/array/merge-sorted-array.c @@ -0,0 +1,14 @@ +void merge(int* nums1, int m, int* nums2, int n) { + int end = m + n - 1; + int i = m - 1; + int j = n - 1; + + while(i >= 0 && j >= 0) + nums1[end--] = nums1[i] > nums2[j] ? nums1[i--] : nums2[j--]; + + while(i >= 0) + nums1[end--] = nums1[i--]; + + while(j >= 0) + nums1[end--] = nums2[j--]; +} diff --git a/c/array/minimum-path-sum.c b/c/array/minimum-path-sum.c new file mode 100644 index 0000000..fa8f1bf --- /dev/null +++ b/c/array/minimum-path-sum.c @@ -0,0 +1,30 @@ +int minPathSum(int** grid, int gridRowSize, int gridColSize) { + int **arr; + int ret; + int i,j; + + arr = (int **)malloc(sizeof(int *) * gridRowSize); + for(i = 0; i < gridRowSize; ++i) + arr[i] = (int *)malloc(sizeof(int) * gridColSize); + + for(i = 0; i < gridRowSize; ++i){ + for(j = 0; j < gridColSize; ++j){ + arr[i][j] = grid[i][j]; + if(i - 1 >= 0 && j - 1 < 0) + arr[i][j] += arr[i-1][j]; + else if(j - 1 >= 0 && i - 1 < 0) + arr[i][j] += arr[i][j-1]; + else if(i - 1 >= 0 && j - 1 >= 0) + arr[i][j] += arr[i-1][j] < arr[i][j-1] ? + arr[i-1][j] : arr[i][j-1]; + } + } + + ret = arr[gridRowSize-1][gridColSize-1]; + + for(i = 0; i < gridRowSize; ++i) + free(arr[i]); + free(arr); + + return ret; +} diff --git a/c/array/minimum-size-subarray-sum.c b/c/array/minimum-size-subarray-sum.c new file mode 100644 index 0000000..6f18b43 --- /dev/null +++ b/c/array/minimum-size-subarray-sum.c @@ -0,0 +1,26 @@ +int minSubArrayLen(int s, int* nums, int numsSize) { + int i,j; + int sum; + int count; + int ret = numsSize + 1; + + i = 0; + j = 0; + sum = 0; + count = 0; + while(1){ + if(i < numsSize && sum >= s){ + if(count < ret) + ret = count; + sum -= nums[i++]; + count--; + }else if(j < numsSize){ + sum += nums[j++]; + count++; + }else{ + break; + } + } + + return ret == numsSize + 1 ? 0 : ret; +} diff --git a/c/array/minimum-size-subarray-sum[1].c b/c/array/minimum-size-subarray-sum[1].c new file mode 100644 index 0000000..2ce4a05 --- /dev/null +++ b/c/array/minimum-size-subarray-sum[1].c @@ -0,0 +1,19 @@ +int minSubArrayLen(int s, int* nums, int numsSize) { + int i,j; + int sum; + int ret = numsSize + 1; + + sum = 0; + j = 0; + for(i = 0; i < numsSize; ++i){ + while(j < numsSize && sum < s){ + sum += nums[j++]; + } + + if(sum >= s) + ret = j - i < ret ? j - i : ret; + sum -= nums[i]; + } + + return ret == numsSize + 1 ? 0 : ret; +} diff --git a/c/array/pascals-triangle-ii.c b/c/array/pascals-triangle-ii.c new file mode 100644 index 0000000..312e228 --- /dev/null +++ b/c/array/pascals-triangle-ii.c @@ -0,0 +1,26 @@ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* getRow(int rowIndex, int* returnSize) { + int *ret; + int i,j; + int tmp,prev; + + ret = (int *)malloc(sizeof(int) * (rowIndex + 1)); + memset(ret,0,sizeof(int) * (rowIndex + 1)); + + for(i = 0; i <= rowIndex; ++i){ + ret[0] = 1; + prev = ret[0]; + for(j = 1; j < i; ++j){ + tmp = ret[j]; + ret[j] = prev + ret[j]; + prev = tmp; + } + ret[i] = 1; + } + + *returnSize = rowIndex + 1; + return ret; +} diff --git a/c/array/pascals-triangle.c b/c/array/pascals-triangle.c new file mode 100644 index 0000000..810fe24 --- /dev/null +++ b/c/array/pascals-triangle.c @@ -0,0 +1,26 @@ +/** + * 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** generate(int numRows, int** columnSizes, int* returnSize) { + int **ret; + int i,j; + int *col; + + col = (int *)malloc(sizeof(int) * numRows); + ret = (int **)malloc(sizeof(int *) * numRows); + for(i = 0; i < numRows; ++i){ + col[i] = i + 1; + ret[i] = (int *)malloc(sizeof(int) * col[i]); + + ret[i][0] = 1; + for(j = 1; j < col[i] - 1; ++j) + ret[i][j] = ret[i-1][j-1] + ret[i-1][j]; + ret[i][col[i]-1] = 1; + } + + *returnSize = numRows; + *columnSizes = col; + return ret; +} diff --git a/c/array/plus-one.c b/c/array/plus-one.c new file mode 100644 index 0000000..0c4e925 --- /dev/null +++ b/c/array/plus-one.c @@ -0,0 +1,26 @@ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* plusOne(int* digits, int digitsSize, int* returnSize) { + int *arr; + int i; + int carry = 1; + int offset = 1; + + arr = (int *)malloc(sizeof(int) * (digitsSize+1)); + + for(i = digitsSize-1; i >= 0; --i){ + int tmp = digits[i] + carry; + carry = tmp / 10; + arr[i+1] = tmp % 10; + } + + if(carry){ + arr[0] = carry; + offset--; + } + + *returnSize = digitsSize + 1 - offset; + return arr + offset; +} diff --git a/c/array/product-of-array-except-self.c b/c/array/product-of-array-except-self.c new file mode 100644 index 0000000..8f167e4 --- /dev/null +++ b/c/array/product-of-array-except-self.c @@ -0,0 +1,27 @@ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* productExceptSelf(int* nums, int numsSize, int* returnSize) { + int product = 1; + int *left; + int *right; + int i; + + left = (int *)malloc(sizeof(int) * numsSize); + right = (int *)malloc(sizeof(int) * numsSize); + left[0] = 1; + for(i = 1; i < numsSize; ++i) + left[i] = nums[i-1] * left[i-1]; + + right[numsSize-1] = 1; + for(i = numsSize - 2; i >= 0; --i) + right[i] = nums[i+1] * right[i+1]; + + for(i = 0; i < numsSize; ++i) + left[i] *= right[i]; + + *returnSize = numsSize; + free(right); + return left; +} diff --git a/c/array/remove-duplicates-from-sorted-array-ii.c b/c/array/remove-duplicates-from-sorted-array-ii.c new file mode 100644 index 0000000..529474a --- /dev/null +++ b/c/array/remove-duplicates-from-sorted-array-ii.c @@ -0,0 +1,14 @@ +int removeDuplicates(int* nums, int numsSize) { + int count,i; + + if(numsSize <= 2) + return numsSize; + + count = 2; + for(i = 2; i < numsSize; ++i){ + if(nums[i] != nums[count-2]) + nums[count++] = nums[i]; + } + + return count; +} diff --git a/c/array/remove-duplicates-from-sorted-array.c b/c/array/remove-duplicates-from-sorted-array.c new file mode 100644 index 0000000..081816e --- /dev/null +++ b/c/array/remove-duplicates-from-sorted-array.c @@ -0,0 +1,14 @@ +int removeDuplicates(int* nums, int numsSize) { + int count,i; + + if(numsSize == 0) + return 0; + + count = 1; + for(i = 1; i < numsSize; ++i){ + if(nums[i] != nums[count-1]) + nums[count++] = nums[i]; + } + + return count; +} diff --git a/c/array/remove-element.c b/c/array/remove-element.c new file mode 100644 index 0000000..c207bad --- /dev/null +++ b/c/array/remove-element.c @@ -0,0 +1,11 @@ +int removeElement(int* nums, int numsSize, int val) { + int count,i; + + count = 0; + for(i = 0; i < numsSize; ++i){ + if(nums[i] != val) + nums[count++] = nums[i]; + } + + return count; +} diff --git a/c/array/rotate-array.c b/c/array/rotate-array.c new file mode 100644 index 0000000..eb7a024 --- /dev/null +++ b/c/array/rotate-array.c @@ -0,0 +1,19 @@ +void reverse(int *nums, int start, int end) +{ + int tmp; + while(start < end){ + tmp = nums[start]; + nums[start] = nums[end]; + nums[end] = tmp; + + ++start; + --end; + } +} + +void rotate(int* nums, int numsSize, int k) { + k %= numsSize; + reverse(nums,0,numsSize - k - 1); + reverse(nums,numsSize - k,numsSize -1); + reverse(nums,0,numsSize-1); +} diff --git a/c/array/rotate-image.c b/c/array/rotate-image.c new file mode 100644 index 0000000..6d61604 --- /dev/null +++ b/c/array/rotate-image.c @@ -0,0 +1,28 @@ +void reverse(int *nums, int start, int end) +{ + int tmp; + while(start < end){ + tmp = nums[start]; + nums[start] = nums[end]; + nums[end] = tmp; + start++; + end--; + } +} + +void rotate(int** matrix, int matrixRowSize, int matrixColSize) { + int i,j; + int tmp; + + for(i = 0; i < matrixRowSize; ++i){ + for(j = 0; j < i; ++j){ + tmp = matrix[i][j]; + matrix[i][j] = matrix[j][i]; + matrix[j][i] = tmp; + } + } + + for(i = 0; i < matrixRowSize; ++i){ + reverse(matrix[i],0,matrixColSize-1); + } +} diff --git a/c/array/search-a-2d-matrix.c b/c/array/search-a-2d-matrix.c new file mode 100644 index 0000000..6b3703d --- /dev/null +++ b/c/array/search-a-2d-matrix.c @@ -0,0 +1,21 @@ +bool searchMatrix(int** matrix, int matrixRowSize, int matrixColSize, int target) { + int start,end; + int mid; + int tmp; + + start = 0; + end = matrixRowSize * matrixColSize - 1; + + while(start <= end){ + mid = (start + end) / 2; + tmp = matrix[mid / matrixColSize][mid % matrixColSize]; + if(tmp == target) + return true; + else if(tmp > target) + end = mid - 1; + else + start = mid + 1; + } + + return false; +} diff --git a/c/array/search-for-a-range.c b/c/array/search-for-a-range.c new file mode 100644 index 0000000..e65daa3 --- /dev/null +++ b/c/array/search-for-a-range.c @@ -0,0 +1,47 @@ +/** + * 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) { + int start, end, mid; + int *ret; + + ret = (int *)malloc(sizeof(int) * 2); + *returnSize = 2; + ret[0] = -1; + ret[1] = -1; + + start = 0; + end = numsSize - 1; + + while(start <= end){ + mid = (start + end) / 2; + if((mid - 1 < 0 || nums[mid-1] != target) && + target == nums[mid]){ + ret[0] = mid; + ret[1] = mid; + break; + }else if(nums[mid] >= target){ + end = mid - 1; + }else{ + start = mid + 1; + } + } + + start = mid+1; + end = numsSize - 1; + while(start <= end){ + mid = (start + end) / 2; + if((mid + 1 == numsSize || target != nums[mid+1]) && + target == nums[mid]){ + ret[1] = mid; + break; + }else if(nums[mid] > target){ + end = mid - 1; + }else{ + start = mid + 1; + } + } + + return ret; +} diff --git a/c/array/search-in-rotated-sorted-array-ii.c b/c/array/search-in-rotated-sorted-array-ii.c new file mode 100644 index 0000000..dbeda7e --- /dev/null +++ b/c/array/search-in-rotated-sorted-array-ii.c @@ -0,0 +1,28 @@ +bool search(int* nums, int numsSize, int target) { + int start,end,mid; + start = 0; + end = numsSize - 1; + + while(start <= end){ + mid = (start + end) / 2; + if(nums[mid] == target){ + return true; + } + + if(nums[mid] > nums[start]){ + if(target >= nums[start] && target < nums[mid]) + end = mid - 1; + else + start = mid + 1; + }else if(nums[mid] < nums[start]){ + if(target > nums[mid] && target <= nums[end]) + start = mid + 1; + else + end = mid - 1; + }else{ + ++start; + } + } + + return false; +} diff --git a/c/array/search-in-rotated-sorted-array.c b/c/array/search-in-rotated-sorted-array.c new file mode 100644 index 0000000..c88b092 --- /dev/null +++ b/c/array/search-in-rotated-sorted-array.c @@ -0,0 +1,29 @@ +int search(int* nums, int numsSize, int target) { + int start,end,mid; + + start = 0; + end = numsSize -1; + + while(start <= end){ + mid = (start + end) / 2; + if(nums[mid] == target){ + return mid; + } + + if(nums[start] < nums[mid]){ + if(target >= nums[start] && target < nums[mid]) + end = mid - 1; + else + start = mid + 1; + }else if(nums[start] > nums[mid]){ + if(target > nums[mid] && target <= nums[end]) + start = mid + 1; + else + end = mid - 1; + }else{ + start++; + } + } + + return -1; +} diff --git a/c/array/search-insert-position.c b/c/array/search-insert-position.c new file mode 100644 index 0000000..d267d04 --- /dev/null +++ b/c/array/search-insert-position.c @@ -0,0 +1,17 @@ +int searchInsert(int* nums, int numsSize, int target) { + int start,end,mid; + + start = 0; + end = numsSize - 1; + while(start < end){ + mid = (start + end) / 2; + if(nums[mid] == target) + return mid; + else if(nums[mid] > target) + end = mid - 1; + else + start = mid + 1; + } + + return nums[start] < target ? start + 1 : start; +} diff --git a/c/array/set-matrix-zeroes.c b/c/array/set-matrix-zeroes.c new file mode 100644 index 0000000..91238b6 --- /dev/null +++ b/c/array/set-matrix-zeroes.c @@ -0,0 +1,29 @@ +void setZeroes(int** matrix, int matrixRowSize, int matrixColSize) { + int *row; + int *col; + int i,j; + + row = (int *)malloc(sizeof(int) * matrixRowSize); + col = (int *)malloc(sizeof(int) * matrixColSize); + memset(row, 0, sizeof(int) * matrixRowSize); + memset(col, 0, sizeof(int) * matrixColSize); + + for(i = 0; i < matrixRowSize; ++i){ + for(j = 0; j < matrixColSize; ++j){ + if(matrix[i][j] == 0){ + row[i] = 1; + col[j] = 1; + } + } + } + + for(i = 0; i < matrixRowSize; ++i){ + for(j = 0; j < matrixColSize; ++j){ + if(row[i] || col[j]) + matrix[i][j] = 0; + } + } + + free(row); + free(col); +} diff --git a/c/array/set-matrix-zeroes[1].c b/c/array/set-matrix-zeroes[1].c new file mode 100644 index 0000000..14a5ecf --- /dev/null +++ b/c/array/set-matrix-zeroes[1].c @@ -0,0 +1,46 @@ +void setZeroes(int** matrix, int matrixRowSize, int matrixColSize) { + int row0 = 0; + int col0 = 0; + int i,j; + + for(i = 0; i < matrixRowSize; ++i){ + if(matrix[i][0] == 0){ + col0 = 1; + break; + } + } + + for(j = 0; j < matrixColSize; ++j){ + if(matrix[0][j] == 0){ + row0 = 1; + break; + } + } + + for(i = 1; i < matrixRowSize; ++i){ + for(j = 1; j < matrixColSize; ++j){ + if(matrix[i][j] == 0){ + matrix[0][j] = 0; + matrix[i][0] = 0; + } + } + } + + for(i = 1; i < matrixRowSize; ++i){ + for(j = 1; j < matrixColSize; ++j){ + if(matrix[0][j] == 0 || matrix[i][0] == 0) + matrix[i][j] = 0; + } + } + + if(row0){ + for(j = 0; j < matrixColSize; ++j) + matrix[0][j] = 0; + } + + if(col0){ + for(i = 0; i < matrixRowSize; ++i){ + matrix[i][0] = 0; + } + } +} diff --git a/c/array/sort-colors.c b/c/array/sort-colors.c new file mode 100644 index 0000000..3e6a701 --- /dev/null +++ b/c/array/sort-colors.c @@ -0,0 +1,26 @@ +void swap(int *a, int *b) +{ + int tmp = *a; + *a = *b; + *b = tmp; +} + +void sortColors(int* nums, int numsSize) { + int i,left,right; + + i = 0; + left = 0; + right = numsSize - 1; + while(i <= right){ + if(nums[i] == 0){ + swap(&nums[left],&nums[i]); + left++; + i++; + }else if(nums[i] == 1){ + i++; + }else{ + swap(&nums[right],&nums[i]); + right--; + } + } +} diff --git a/c/array/sort-colors[1].c b/c/array/sort-colors[1].c new file mode 100644 index 0000000..db5c686 --- /dev/null +++ b/c/array/sort-colors[1].c @@ -0,0 +1,19 @@ +void sortColors(int* nums, int numsSize) { + int i; + int zero = -1; + int one = -1; + int two = -1; + + for(i = 0; i < numsSize; ++i){ + if(nums[i] == 0){ + nums[++two] = 2; + nums[++one] = 1; + nums[++zero] = 0; + }else if(nums[i] == 1){ + nums[++two] = 2; + nums[++one] = 1; + }else{ + nums[++two] = 2; + } + } +} diff --git a/c/array/spiral-matrix-ii.c b/c/array/spiral-matrix-ii.c new file mode 100644 index 0000000..d9fedc3 --- /dev/null +++ b/c/array/spiral-matrix-ii.c @@ -0,0 +1,66 @@ +/** + * Return an array of arrays. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int** generateMatrix(int n) { + int **ret; + int i,j; + int left,right,up,down; + int direct = 0; + int size = n * n; + int cur = 1; + + ret = (int **)malloc(sizeof(int *) * n); + for(i = 0; i < n; ++i) + ret[i] = (int *)malloc(sizeof(int) * n); + + left = 0; + up = 0; + down = n - 1; + right = n - 1; + + i = 0; + j = 0; + while(cur <= size){ + ret[i][j] = cur++; + switch(direct){ + case 0: // left to right + if(j < right){ + j++; + }else{ + direct = (direct + 1) % 4; + up++; + i++; + } + break; + case 1: // up to down + if(i < down){ + i++; + }else{ + direct = (direct + 1) % 4; + right--; + j--; + } + break; + case 2: // right to left + if(j > left){ + --j; + }else{ + direct = (direct + 1) % 4; + down--; + i--; + } + break; + case 3: // down to up + if(i > up){ + i--; + }else{ + direct = (direct + 1) % 4; + left++; + j++; + } + } + } + + return ret; +} diff --git a/c/array/spiral-matrix-ii[1].c b/c/array/spiral-matrix-ii[1].c new file mode 100644 index 0000000..546f807 --- /dev/null +++ b/c/array/spiral-matrix-ii[1].c @@ -0,0 +1,36 @@ +/** + * Return an array of arrays. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int** generateMatrix(int n) { + int **ret; + int i; + int left,right,up,down; + int cur = 1; + + ret = (int **)malloc(sizeof(int *) * n); + for(i = 0; i < n; ++i) + ret[i] = (int *)malloc(sizeof(int) * n); + + left = 0; + up = 0; + down = n - 1; + right = n - 1; + + while(left <= right && up <= down){ + for(i = left; i <= right; ++i) + ret[up][i] = cur++; + for(i = up + 1; i <= down; ++i) + ret[i][right] = cur++; + for(i = right - 1; i >= left; --i) + ret[down][i] = cur++; + for(i = down - 1; i > up; --i) + ret[i][left] = cur++; + left++; + up++; + down--; + right--; + } + + return ret; +} diff --git a/c/array/spiral-matrix.c b/c/array/spiral-matrix.c new file mode 100644 index 0000000..2be68fa --- /dev/null +++ b/c/array/spiral-matrix.c @@ -0,0 +1,63 @@ +/** + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* spiralOrder(int** matrix, int matrixRowSize, int matrixColSize) { + int size = matrixRowSize * matrixColSize; + int i,j,count; + int *ret; + int left,right,up,down; + int direct = 0; //0 right,1 down, 2 left, 3 up + + ret = (int *)malloc(sizeof(int) * size); + i = 0; + j = 0; + count = 0; + left = 0; + up = 0; + right = matrixColSize - 1; + down = matrixRowSize - 1; + + while(count < size){ + ret[count++] = matrix[i][j]; + switch(direct){ + case 0: + if(j < right){ + ++j; + }else{ + direct = (direct + 1) % 4; + ++up; + ++i; + } + break; + case 1: + if(i < down){ + ++i; + }else{ + direct = (direct + 1) % 4; + --right; + --j; + } + break; + case 2: + if(j > left){ + --j; + }else{ + direct = (direct + 1) % 4; + --down; + --i; + } + break; + case 3: + if(i > up){ + --i; + }else{ + direct = (direct + 1) % 4; + ++left; + ++j; + } + break; + } + } + + return ret; +} diff --git a/c/array/spiral-matrix[1].c b/c/array/spiral-matrix[1].c new file mode 100644 index 0000000..adde1e1 --- /dev/null +++ b/c/array/spiral-matrix[1].c @@ -0,0 +1,42 @@ +/** + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* spiralOrder(int** matrix, int matrixRowSize, int matrixColSize) { + int size = matrixRowSize * matrixColSize; + int i,count; + int *ret; + int left,right,up,down; + + ret = (int *)malloc(sizeof(int) * size); + count = 0; + + left = 0; + up = 0; + right = matrixColSize - 1; + down = matrixRowSize - 1; + + while(left <= right && up <= down){ + for(i = left; i <= right; ++i) + ret[count++] = matrix[up][i]; + if(count == size) + break; + for(i = up + 1; i <= down; ++i) + ret[count++] = matrix[i][right]; + if(count == size) + break; + for(i = right - 1; i >= left; --i) + ret[count++] = matrix[down][i]; + if(count == size) + break; + for(i = down - 1; i > up; --i) + ret[count++] = matrix[i][left]; + if(count == size) + break; + left++; + up++; + right--; + down--; + } + + return ret; +} diff --git a/c/array/subsets-ii.c b/c/array/subsets-ii.c new file mode 100644 index 0000000..964ad56 --- /dev/null +++ b/c/array/subsets-ii.c @@ -0,0 +1,54 @@ +/** + * 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 **ret; +int *col; +int size; +int alloc_size; +int idx; + +void helper(int *arr, int len, int *nums, int pos) +{ + int i; + + ret[idx] = (int *)malloc(sizeof(int) * len); + for(i = 0; i < len; ++i){ + ret[idx][i] = arr[i]; + } + col[idx] = len; + idx++; + + for(i = pos; i < size; ++i){ + if(i > pos && nums[i-1] == nums[i]) + continue; + arr[len] = nums[i]; + helper(arr,len+1,nums,i+1); + } +} + +int cmp(const void *a, const void *b) +{ + return *(const int *)a - *(const int *)b; +} + +int** subsetsWithDup(int* nums, int numsSize, int** columnSizes, int* returnSize) { + int *arr; + size = numsSize; + alloc_size = 1 << numsSize; + idx = 0; + + ret = (int **)malloc(sizeof(int *) * alloc_size); + col = (int *)malloc(sizeof(int) * alloc_size); + arr = (int *)malloc(sizeof(int) * numsSize); + + qsort(nums,numsSize,sizeof(int), cmp); + + helper(arr,0,nums,0); + + free(arr); + *columnSizes = col; + *returnSize = idx; + return ret; +} diff --git a/c/array/subsets.c b/c/array/subsets.c new file mode 100644 index 0000000..4534343 --- /dev/null +++ b/c/array/subsets.c @@ -0,0 +1,39 @@ +/** + * 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 cmp(const void *a, const void *b) +{ + return *(const int *)a - *(const int *)b; +} + +int** subsets(int* nums, int numsSize, int** columnSizes, int* returnSize) { + int **ret; + int *col; + int count = 1 << numsSize; + int i,j; + int bit; + + ret = (int **)malloc(sizeof(int *) * count); + col = (int *)malloc(sizeof(int) * count); + + qsort(nums,numsSize,sizeof(int),cmp); + + for(i = 0; i < count; ++i){ + col[i] = 0; + ret[i] = (int *)malloc(sizeof(int *) * numsSize); + bit = i; + j = 0; + while(bit > 0){ + if(bit & 1) + ret[i][col[i]++] = nums[j]; + j++; + bit >>= 1; + } + } + + *returnSize = count; + *columnSizes = col; + return ret; +} diff --git a/c/array/subsets[1].c b/c/array/subsets[1].c new file mode 100644 index 0000000..1fdd554 --- /dev/null +++ b/c/array/subsets[1].c @@ -0,0 +1,51 @@ +/** + * 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 idx; +int **ret; +int *col; +int size; + +void helper(int *arr, int len, int *nums,int level) +{ + int i; + if(level == size){ + ret[idx] = (int *)malloc(sizeof(int) * len); + for(i = 0; i < len; ++i) + ret[idx][i] = arr[i]; + col[idx] = len; + idx++; + return ; + } + + helper(arr,len,nums,level+1); + arr[len] = nums[level]; + helper(arr,len+1,nums,level+1); +} + +int cmp(const void *a, const void *b) +{ + return *(const int *)a - *(const int *)b; +} + +int** subsets(int* nums, int numsSize, int** columnSizes, int* returnSize) { + int *arr; + int count = 1 << numsSize; + size = numsSize; + idx = 0; + + ret = (int **)malloc(sizeof(int *) * count); + col = (int *)malloc(sizeof(int) * count); + arr = (int *)malloc(sizeof(int) * numsSize); + + qsort(nums,numsSize,sizeof(int),cmp); + + helper(arr,0,nums,0); + + *returnSize = count; + *columnSizes = col; + free(arr); + return ret; +} diff --git a/c/array/subsets[2].c b/c/array/subsets[2].c new file mode 100644 index 0000000..b60da7d --- /dev/null +++ b/c/array/subsets[2].c @@ -0,0 +1,49 @@ +/** + * 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 idx; +int **ret; +int *col; +int size; + +void helper(int *arr, int len, int *nums,int pos) +{ + int i; + ret[idx] = (int *)malloc(sizeof(int) * len); + for(i = 0; i < len; ++i) + ret[idx][i] = arr[i]; + col[idx] = len; + idx++; + + for(i = pos; i < size; ++i){ + arr[len] = nums[i]; + helper(arr,len+1,nums,i+1); + } +} + +int cmp(const void *a, const void *b) +{ + return *(const int *)a - *(const int *)b; +} + +int** subsets(int* nums, int numsSize, int** columnSizes, int* returnSize) { + int *arr; + int count = 1 << numsSize; + size = numsSize; + idx = 0; + + ret = (int **)malloc(sizeof(int *) * count); + col = (int *)malloc(sizeof(int) * count); + arr = (int *)malloc(sizeof(int) * numsSize); + + qsort(nums,numsSize,sizeof(int),cmp); + + helper(arr,0,nums,0); + + *returnSize = count; + *columnSizes = col; + free(arr); + return ret; +} diff --git a/c/array/summary-ranges.c b/c/array/summary-ranges.c new file mode 100644 index 0000000..0bd19de --- /dev/null +++ b/c/array/summary-ranges.c @@ -0,0 +1,33 @@ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +char *get_range(int start, int end) +{ + char buf[32]; + if(start == end) + sprintf(buf,"%d",start); + else + sprintf(buf,"%d->%d",start,end); + return strdup(buf); +} + +char** summaryRanges(int* nums, int numsSize, int* returnSize) { + char **ret; + int i,count; + int start,end; + + count = 0; + ret = (char **)malloc(sizeof(char *) * numsSize); + + for(i = 0; i < numsSize; ++i){ + start = nums[i]; + while(i < numsSize-1 && nums[i+1] == nums[i]+1) + i++; + end = nums[i]; + ret[count++] = get_range(start,end); + } + + *returnSize = count; + return ret; +} diff --git a/c/array/trapping-rain-water.c b/c/array/trapping-rain-water.c new file mode 100644 index 0000000..0d6c3a4 --- /dev/null +++ b/c/array/trapping-rain-water.c @@ -0,0 +1,31 @@ +int trap(int* height, int heightSize) { + int sum = 0; + int max_index; + int max_height; + int i; + + max_height = 0; + for(i = 0; i < heightSize; ++i) + if(height[i] > max_height){ + max_height = height[i]; + max_index = i; + } + + max_height = 0; + for(i = 0; i < max_index; ++i){ + if(max_height > height[i]){ + sum += (max_height - height[i]); + } + max_height = height[i] > max_height ? height[i] : max_height; + } + + max_height = 0; + for(i = heightSize - 1; i > max_index; --i){ + if(max_height > height[i]){ + sum += (max_height - height[i]); + } + max_height = height[i] > max_height ? height[i] : max_height; + } + + return sum; +} diff --git a/c/array/triangle.c b/c/array/triangle.c new file mode 100644 index 0000000..83428ca --- /dev/null +++ b/c/array/triangle.c @@ -0,0 +1,26 @@ +int minimumTotal(int **triangle, int numRows) { + int *dp; + int *tmp; + int i,j,ret; + + dp = (int *)malloc(sizeof(int) * numRows); + tmp = (int *)malloc(sizeof(int) * numRows); + dp[0] = triangle[0][0]; + for(i = 1; i < numRows; ++i){ + memcpy(tmp,dp,sizeof(int) * i); + memcpy(dp,triangle[i],sizeof(int) * (i + 1)); + dp[0] += tmp[0]; + for(j = 1; j < i; ++j){ + dp[j] += tmp[j] < tmp[j-1] ? tmp[j] : tmp[j-1]; + } + dp[i] += tmp[i-1]; + } + + ret = dp[0]; + for(i = 1; i < numRows; ++i) + ret = dp[i] < ret ? dp[i] : ret; + + free(tmp); + free(dp); + return ret; +} diff --git a/c/array/triangle[1].c b/c/array/triangle[1].c new file mode 100644 index 0000000..40cb768 --- /dev/null +++ b/c/array/triangle[1].c @@ -0,0 +1,25 @@ +int minimumTotal(int **triangle, int numRows) { + int *dp; + int tmp,prev; + int i,j,ret; + + dp = (int *)malloc(sizeof(int) * numRows); + dp[0] = triangle[0][0]; + for(i = 1; i < numRows; ++i){ + prev = dp[0]; + dp[0] += triangle[i][0]; + for(j = 1; j < i; ++j){ + tmp = dp[j]; + dp[j] = prev < tmp ? prev : tmp; + dp[j] += triangle[i][j]; + prev = tmp; + } + dp[i] = triangle[i][i] + prev; + } + + ret = dp[0]; + for(i = 1; i < numRows; ++i) + ret = dp[i] < ret ? dp[i] : ret; + + return ret; +} diff --git a/c/array/two-sum.c b/c/array/two-sum.c new file mode 100644 index 0000000..6e8025e --- /dev/null +++ b/c/array/two-sum.c @@ -0,0 +1,55 @@ +/** + * Note: The returned array must be malloced, assume caller calls free(). + */ +struct node{ + int val; + int index; +}; + +int search(struct node *arr, int numsSize, int target) +{ + int start,end,mid; + start = 0; + end = numsSize - 1; + while(start <= end){ + mid = (start + end) / 2; + if(arr[mid].val == target) + return arr[mid].index; + else if(arr[mid].val > target) + end = mid - 1; + else + start = mid + 1; + } + return -1; +} + +int cmp(const void *a, const void *b) +{ + return ((struct node *)a)->val - ((struct node *)b)->val; +} + +int* twoSum(int* nums, int numsSize, int target) { + int *ret; + struct node *arr; + int i,index; + ret = (int *)malloc(sizeof(int) * 2); + arr = (struct node *)malloc(sizeof(struct node) * numsSize); + for(i = 0; i < numsSize; ++i){ + arr[i].val = nums[i]; + arr[i].index = i + 1; + } + + qsort(arr,numsSize,sizeof(struct node),cmp); + + for(i = 0; i < numsSize; ++i) + { + index = search(arr,numsSize,target - nums[i]); + if(index != -1 && index != i+1){ + ret[0] = i+1 < index ? i + 1 : index; + ret[1] = i+1 > index ? i + 1 : index; + } + } + + free(arr); + return ret; +} diff --git a/c/array/two-sum[1].c b/c/array/two-sum[1].c new file mode 100644 index 0000000..4cf7cb7 --- /dev/null +++ b/c/array/two-sum[1].c @@ -0,0 +1,46 @@ +/** + * Note: The returned array must be malloced, assume caller calls free(). + */ +struct node{ + int val; + int index; +}; + +int cmp(const void *a, const void *b) +{ + return ((struct node *)a)->val - ((struct node *)b)->val; +} + +int* twoSum(int* nums, int numsSize, int target) { + int *ret; + struct node *arr; + int i,j; + int sum; + ret = (int *)malloc(sizeof(int) * 2); + arr = (struct node *)malloc(sizeof(struct node) * numsSize); + for(i = 0; i < numsSize; ++i){ + arr[i].val = nums[i]; + arr[i].index = i + 1; + } + + qsort(arr,numsSize,sizeof(struct node),cmp); + + i = 0; + j = numsSize - 1; + while(i < j){ + sum = arr[i].val + arr[j].val; + if(sum == target){ + ret[0] = arr[i].index < arr[j].index ? arr[i].index : arr[j].index; + ret[1] = arr[i].index > arr[j].index ? arr[i].index : arr[j].index; + break; + } + if(sum > target){ + j--; + }else{ + i++; + } + } + + free(arr); + return ret; +} diff --git a/c/array/unique-paths-ii.c b/c/array/unique-paths-ii.c new file mode 100644 index 0000000..20cfbf1 --- /dev/null +++ b/c/array/unique-paths-ii.c @@ -0,0 +1,36 @@ +int uniquePathsWithObstacles(int** obstacleGrid, int obstacleGridRowSize, int obstacleGridColSize) { + int **dp; + int i,j; + int ret; + + dp = (int **)malloc(sizeof(int *) * obstacleGridRowSize); + for(i = 0; i < obstacleGridRowSize; ++i){ + dp[i] = (int *)malloc(sizeof(int) * obstacleGridColSize); + memset(dp[i],0,sizeof(int) * obstacleGridColSize); + } + + for(i = 0; i < obstacleGridRowSize; ++i){ + if(obstacleGrid[i][0]) + break; + dp[i][0] = 1; + } + + for(j = 0; j < obstacleGridColSize; ++j){ + if(obstacleGrid[0][j]) + break; + dp[0][j] = 1; + } + + for(i = 1; i < obstacleGridRowSize; ++i) + for(j = 1; j < obstacleGridColSize; ++j) + if(obstacleGrid[i][j] == 0) + dp[i][j] = dp[i-1][j] + dp[i][j-1]; + + ret = dp[obstacleGridRowSize-1][obstacleGridColSize-1]; + + for(i = 0; i < obstacleGridRowSize; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/c/array/unique-paths.c b/c/array/unique-paths.c new file mode 100644 index 0000000..cf2cc7d --- /dev/null +++ b/c/array/unique-paths.c @@ -0,0 +1,24 @@ +int uniquePaths(int m, int n) { + int **dp; + int i,j; + int ret; + + dp = (int **)malloc(sizeof(int *) * m); + for(i = 0; i < m; ++i) + dp[i] = (int *)malloc(sizeof(int) * n); + for(i = 0; i < m; ++i) + dp[i][0] = 1; + for(j = 0; j < n; ++j) + dp[0][j] = 1; + for(i = 1; i < m; ++i) + for(j = 1; j < n; ++j) + dp[i][j] = dp[i-1][j] + dp[i][j-1]; + + ret = dp[m-1][n-1]; + + for(i = 0; i < m; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/c/array/word-search.c b/c/array/word-search.c new file mode 100644 index 0000000..e66eeb6 --- /dev/null +++ b/c/array/word-search.c @@ -0,0 +1,64 @@ +int **visited; +int row,col; +int len; + +int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}}; + +bool helper(char **board, int x, int y, char *word, int pos) +{ + bool ret = false; + int i; + + if(pos == len) + return true; + + for(i = 0; i < 4; ++i){ + int x1 = x + dir[i][0]; + int y1 = y + dir[i][1]; + + if(x1 >= 0 && x1 < row && y1 >= 0 && y1 < col + && !visited[x1][y1] && board[x1][y1] == word[pos]){ + visited[x1][y1] = 1; + if(helper(board,x1,y1,word,pos+1)) + return true; + visited[x1][y1] = 0; + } + } + + return false; +} + +bool exist(char** board, int boardRowSize, int boardColSize, char* word) { + int i,j; + bool ret = false; + + row = boardRowSize; + col = boardColSize; + len = strlen(word); + + visited = (int **)malloc(sizeof(int *) * boardRowSize); + for(i = 0; i < boardRowSize; ++i){ + visited[i] = (int *)malloc(sizeof(int) * boardColSize); + memset(visited[i],0,sizeof(int) * boardColSize); + } + + for(i = 0; i < row; ++i) + for(j = 0; j < col; ++j){ + if(board[i][j] == word[0]){ + visited[i][j] = 1; + if(helper(board,i,j,word,1)){ + ret = true; + goto out; + } + + visited[i][j] = 0; + } + } + +out: + for(i = 0; i < row; ++i) + free(visited[i]); + free(visited); + + return ret; +} diff --git a/c/backtracking/regular-expression-matching.c b/c/backtracking/regular-expression-matching.c new file mode 100644 index 0000000..03ce32f --- /dev/null +++ b/c/backtracking/regular-expression-matching.c @@ -0,0 +1,16 @@ +bool isMatch(char* s, char* p) { + if(*p == 0) + return *s == 0; + + if(p[1] != '*') + return (*s == *p || (*p == '.' && *s != 0)) && + isMatch(s+1,p+1); + + while(*s == *p || (*p == '.' && *s != 0)){ + if(isMatch(s,p+2)) + return true; + s++; + } + + return isMatch(s,p+2); +} diff --git a/c/backtracking/regular-expression-matching[2].c b/c/backtracking/regular-expression-matching[2].c new file mode 100644 index 0000000..e42e49a --- /dev/null +++ b/c/backtracking/regular-expression-matching[2].c @@ -0,0 +1,38 @@ +bool isMatch(char* s, char* p) { + int **dp; + int len_s,len_p; + int i,j; + int ret; + + len_s = strlen(s); + len_p = strlen(p); + + dp = malloc(sizeof(int *) * (len_s + 1)); + for(i = 0; i <= len_s; ++i){ + dp[i] = malloc(sizeof(int) * (len_p + 1)); + memset(dp[i], 0, sizeof(int) * (len_p + 1)); + } + + dp[0][0] = 1; + for(i = 0; i <= len_s; ++i){ + for(j = 1; j <= len_p; ++j){ + if(p[j-1] != '.' && p[j-1] != '*'){ + dp[i][j] = (i > 0 && dp[i-1][j-1] && s[i-1] == p[j-1]); + }else if(p[j-1] == '.'){ + dp[i][j] = (i > 0 && dp[i-1][j-1]); + }else if(j > 1){ + if(dp[i][j-2] || dp[i][j-1]) //match 0 or 1 char + dp[i][j] = 1; + else if(i > 0 && (s[i-1] == p[j-2] || p[j-2] == '.') && dp[i-1][j]) + dp[i][j] = 1; + } + } + } + + ret = dp[len_s][len_p]; + for(i = 0; i <= len_s; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/c/binary-search/count-complete-tree-nodes.c b/c/binary-search/count-complete-tree-nodes.c new file mode 100644 index 0000000..177da0a --- /dev/null +++ b/c/binary-search/count-complete-tree-nodes.c @@ -0,0 +1,34 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +int countNodes(struct TreeNode* root) { + if(root == NULL) + return 0; + + int lh,rh; + struct TreeNode *tmp; + + tmp = root->left; + lh = 0; + while(tmp){ + lh++; + tmp = tmp->left; + } + + tmp = root->right; + rh = 0; + while(tmp){ + rh++; + tmp = tmp->right; + } + + if(lh == rh) + return (2<left) + countNodes(root->right); +} diff --git a/c/binary-search/divide-two-integers.c b/c/binary-search/divide-two-integers.c new file mode 100644 index 0000000..9abf355 --- /dev/null +++ b/c/binary-search/divide-two-integers.c @@ -0,0 +1,23 @@ +int divide(int dividend, int divisor) { + long ldd = labs(dividend); + long lds = labs(divisor); + int ret = 0; + int is_neg = 0; + + if(divisor == -1 && dividend == INT_MIN) + return INT_MAX; + + if((dividend > 0 && divisor < 0) || + (dividend < 0 && divisor > 0)) + is_neg = 1; + + while(ldd >= lds){ + int tmp = 0; + while(ldd >= (lds << tmp)) + tmp++; + ldd -= (lds << (tmp - 1)); + ret += (1 << (tmp - 1)); + } + + return is_neg ? -ret : ret; +} diff --git a/c/binary-search/dungeon-game.c b/c/binary-search/dungeon-game.c new file mode 100644 index 0000000..81a95f4 --- /dev/null +++ b/c/binary-search/dungeon-game.c @@ -0,0 +1,39 @@ +static inline int max(int a, int b) +{ + return a > b ? a : b; +} + +static inline int min(int a, int b) +{ + return a < b ? a : b; +} + +int calculateMinimumHP(int** dungeon, int row, int col) { + int **dp; + int i,j; + int ret; + + dp = (int **)malloc(sizeof(int *) * row); + for(i = 0; i < row; ++i) + dp[i] = (int *)malloc(sizeof(int *) * col); + + dp[row-1][col-1] = dungeon[row-1][col-1] < 0 ? -dungeon[row-1][col-1] : 0; + + for(i = row - 2; i >= 0; --i) + dp[i][col-1] = max(dp[i+1][col-1] - dungeon[i][col-1], 0); + + for(j = col - 2; j >= 0; --j) + dp[row-1][j] = max(dp[row-1][j+1] - dungeon[row-1][j], 0); + + for(i = row - 2; i >= 0; --i) + for(j = col - 2; j >= 0; --j) + dp[i][j] = max(min(dp[i+1][j],dp[i][j+1]) - dungeon[i][j], 0); + + ret = dp[0][0] + 1; + + for(i = 0; i < row; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/c/binary-search/find-minimum-in-rotated-sorted-array-ii.c b/c/binary-search/find-minimum-in-rotated-sorted-array-ii.c new file mode 100644 index 0000000..2616466 --- /dev/null +++ b/c/binary-search/find-minimum-in-rotated-sorted-array-ii.c @@ -0,0 +1,18 @@ +int findMin(int* nums, int numsSize) { + int start,end,mid; + + start = 0; + end = numsSize - 1; + + while(start < end){ + mid = (start + end) / 2; + if(nums[mid] > nums[end]) + start = mid + 1; + else if(nums[mid] < nums[end]) + end = mid; + else + --end; + } + + return nums[start]; +} diff --git a/c/binary-search/find-minimum-in-rotated-sorted-array.c b/c/binary-search/find-minimum-in-rotated-sorted-array.c new file mode 100644 index 0000000..4cac41b --- /dev/null +++ b/c/binary-search/find-minimum-in-rotated-sorted-array.c @@ -0,0 +1,15 @@ +int findMin(int* nums, int numsSize) { + int start,end; + start = 0; + end = numsSize - 1; + + while(start < end){ + int mid = (start + end) / 2; + if(nums[mid] > nums[end]) + start = mid + 1; + else + end = mid; + } + + return nums[start]; +} diff --git a/c/binary-search/find-peak-element.c b/c/binary-search/find-peak-element.c new file mode 100644 index 0000000..58f69cb --- /dev/null +++ b/c/binary-search/find-peak-element.c @@ -0,0 +1,9 @@ +int findPeakElement(int* nums, int numsSize) { + int i; + + for(i = 1; i < numsSize; ++i) + if(nums[i-1] > nums[i]) + return i - 1; + + return numsSize - 1; +} diff --git a/c/binary-search/find-peak-element[1].c b/c/binary-search/find-peak-element[1].c new file mode 100644 index 0000000..ec958fc --- /dev/null +++ b/c/binary-search/find-peak-element[1].c @@ -0,0 +1,15 @@ +int findPeakElement(int* nums, int numsSize) { + int start,end; + start = 0; + end = numsSize - 1; + + while(start < end){ + int mid = (start + end) / 2; + if(nums[mid] < nums[mid+1]) + start = mid + 1; + else + end = mid; + } + + return start; +} diff --git a/c/binary-search/find-the-duplicate-number.c b/c/binary-search/find-the-duplicate-number.c new file mode 100644 index 0000000..66de401 --- /dev/null +++ b/c/binary-search/find-the-duplicate-number.c @@ -0,0 +1,28 @@ +static int leq_count(int *nums, int numsSize, int target) +{ + int i,ret; + + ret = 0; + for(i = 0;i < numsSize; ++i) + if(nums[i] <= target) + ++ret; + + return ret; +} + +int findDuplicate(int* nums, int numsSize) { + int start,end,mid,c; + start = 1; + end = numsSize-1; + + while(start <= end){ + mid = (start + end) / 2; + c= leq_count(nums,numsSize,mid); + if(c <= mid) + start = mid + 1; + else + end = mid - 1; + } + + return start; +} diff --git a/c/binary-search/first-bad-version.c b/c/binary-search/first-bad-version.c new file mode 100644 index 0000000..843947d --- /dev/null +++ b/c/binary-search/first-bad-version.c @@ -0,0 +1,19 @@ +// Forward declaration of isBadVersion API. +bool isBadVersion(int version); + +int firstBadVersion(int n) { + int start,end,mid; + start = 1; + end = n; + + while(start < end){ + mid = start + (end - start) / 2; + if(isBadVersion(mid)){ + end = mid; + }else{ + start = mid + 1; + } + } + + return end; +} diff --git a/c/binary-search/kth-smallest-element-in-a-bst.c b/c/binary-search/kth-smallest-element-in-a-bst.c new file mode 100644 index 0000000..9861d24 --- /dev/null +++ b/c/binary-search/kth-smallest-element-in-a-bst.c @@ -0,0 +1,23 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +int helper(struct TreeNode *root){ + if(root == NULL) + return 0; + return helper(root->left) + helper(root->right) + 1; +} + +int kthSmallest(struct TreeNode* root, int k) { + int left; + left = helper(root->left); + if(left+1 > k) + return kthSmallest(root->left,k); + else if(left + 1 == k) + return root->val; + return kthSmallest(root->right,k - left - 1); +} diff --git a/c/binary-search/kth-smallest-element-in-a-bst[1].c b/c/binary-search/kth-smallest-element-in-a-bst[1].c new file mode 100644 index 0000000..6431b52 --- /dev/null +++ b/c/binary-search/kth-smallest-element-in-a-bst[1].c @@ -0,0 +1,30 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +int getKth(struct TreeNode *root, int k, int *val) +{ + if(root == NULL) + return 0; + + int left = getKth(root->left,k,val); + if(left + 1 > k) + return left; + if(left + 1 == k){ + *val = root->val; + return left+1; + } + + return left + 1 + getKth(root->right,k-left-1,val); +} + +int kthSmallest(struct TreeNode* root, int k) { + int val; + getKth(root,k, &val); + + return val; +} diff --git a/c/binary-search/longest-increasing-subsequence.c b/c/binary-search/longest-increasing-subsequence.c new file mode 100644 index 0000000..5d7a542 --- /dev/null +++ b/c/binary-search/longest-increasing-subsequence.c @@ -0,0 +1,20 @@ +int lengthOfLIS(int* nums, int numsSize) { + int *dp; + int i,j; + int max = 0; + + dp = (int *)malloc(sizeof(int) * numsSize); + for(i = 0; i < numsSize; ++i){ + dp[i] = 1; + for(j = 0; j < i; ++j) + if(nums[j] < nums[i]) + dp[i] = dp[j] + 1 > dp[i] ? dp[j] + 1 : dp[i]; + } + + for(i = 0; i < numsSize; ++i) + if(dp[i] > max) + max = dp[i]; + + free(dp); + return max; +} diff --git a/c/binary-search/median-of-two-sorted-arrays.c b/c/binary-search/median-of-two-sorted-arrays.c new file mode 100644 index 0000000..d16122c --- /dev/null +++ b/c/binary-search/median-of-two-sorted-arrays.c @@ -0,0 +1,35 @@ +int len1; +int len2; + +int findKth(int *a, int sa, int *b, int sb, int k) +{ + if(sa >= len1) + return b[sb + k - 1]; + if(sb >= len2) + return a[sa + k - 1]; + if(k == 1) + return a[sa] < b[sb] ? a[sa] : b[sb]; + + int ka = sa + k / 2 - 1 >= len1 ? INT_MAX + : a[sa + k / 2 - 1]; + int kb = sb + k / 2 - 1 >= len2 ? INT_MAX + : b[sb + k / 2 - 1]; + if(ka < kb) + return findKth(a, sa + k / 2, b, sb, k - k / 2); + else + return findKth(a, sa, b, sb + k / 2, k - k / 2); +} + +double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { + int len; + + len1 = nums1Size; + len2 = nums2Size; + len = len1 + len2; + + if(len % 2) + return findKth(nums1, 0, nums2, 0, len / 2 + 1); + else + return (findKth(nums1, 0, nums2, 0, len / 2) + + findKth(nums1, 0, nums2, 0, len / 2 + 1)) / 2.0; +} diff --git a/c/binary-search/minimum-size-subarray-sum.c b/c/binary-search/minimum-size-subarray-sum.c new file mode 100644 index 0000000..83799bb --- /dev/null +++ b/c/binary-search/minimum-size-subarray-sum.c @@ -0,0 +1,19 @@ +int minSubArrayLen(int s, int* nums, int numsSize) { + int ret = INT_MAX; + int sum,cur; + int i; + + sum = 0; + cur = 0; + for(i = 0; i < numsSize; ++i){ + cur++; + sum += nums[i]; + while(sum >= s){ + ret = cur < ret ? cur : ret; + sum -= nums[i - cur + 1]; + cur--; + } + } + + return ret == INT_MAX ? 0 : ret; +} diff --git a/c/binary-search/powx-n.c b/c/binary-search/powx-n.c new file mode 100644 index 0000000..2f85d04 --- /dev/null +++ b/c/binary-search/powx-n.c @@ -0,0 +1,22 @@ +double myPow(double x, int n) { + if(n == 0) + return 1; + if(n == 1) + return x; + + int is_neg = 0; + if(n < 0){ + is_neg = 1; + n = -n; + } + + double half = myPow(x,n/2); + double ret; + + if(n % 2) + ret = x * half * half; + else + ret = half * half; + + return is_neg ? 1/ret : ret; +} diff --git a/c/binary-search/search-a-2d-matrix-ii.c b/c/binary-search/search-a-2d-matrix-ii.c new file mode 100644 index 0000000..dffd132 --- /dev/null +++ b/c/binary-search/search-a-2d-matrix-ii.c @@ -0,0 +1,16 @@ +bool searchMatrix(int** matrix, int matrixRowSize, int matrixColSize, int target) { + int row,col; + + row = matrixRowSize - 1; + col = 0; + while(row >= 0 && col < matrixColSize){ + if(matrix[row][col] == target) + return true; + if(matrix[row][col] > target) + row--; + else + col++; + } + + return false; +} diff --git a/c/binary-search/search-a-2d-matrix.c b/c/binary-search/search-a-2d-matrix.c new file mode 100644 index 0000000..3c65e46 --- /dev/null +++ b/c/binary-search/search-a-2d-matrix.c @@ -0,0 +1,19 @@ +bool searchMatrix(int** matrix, int matrixRowSize, int matrixColSize, int target) { + int start,end,mid; + int tmp; + + start = 0; + end = matrixRowSize * matrixColSize - 1; + while(start <= end){ + mid = (start + end) / 2; + tmp= matrix[mid / matrixColSize][mid % matrixColSize]; + if(tmp == target) + return true; + else if(tmp > target) + end = mid - 1; + else + start = mid + 1; + } + + return false; +} diff --git a/c/binary-search/search-a-2d-matrix[2].c b/c/binary-search/search-a-2d-matrix[2].c new file mode 100644 index 0000000..e3d625b --- /dev/null +++ b/c/binary-search/search-a-2d-matrix[2].c @@ -0,0 +1,18 @@ +bool searchMatrix(int** matrix, int matrixRowSize, int matrixColSize, int target) { + int row,col; + + row = matrixRowSize - 1; + col = 0; + + while(row >= 0 && col < matrixColSize){ + if(matrix[row][col] == target) + return true; + + if(matrix[row][col] > target) + --row; + else + ++col; + } + + return false; +} diff --git a/c/binary-search/search-for-a-range.c b/c/binary-search/search-for-a-range.c new file mode 100644 index 0000000..5446220 --- /dev/null +++ b/c/binary-search/search-for-a-range.c @@ -0,0 +1,47 @@ +/** + * 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) { + int *ret; + int start, end, mid; + + ret = (int *)malloc(sizeof(int) * 2); + ret[0] = ret[1] = -1; + *returnSize = 2; + + start = 0; + end = numsSize - 1; + while(start <= end){ + mid = (start + end) / 2; + if(nums[mid] == target && + (mid == 0 || nums[mid] != nums[mid-1])){ + ret[0] = mid; + break; + }else if(nums[mid] >= target){ + end = mid - 1; + }else{ + start = mid + 1; + } + } + + if(ret[0] == -1) + return ret; + + start = mid; + end = numsSize - 1; + while(start <= end){ + mid = (start + end) / 2; + if(nums[mid] == target && + (mid == numsSize -1 || nums[mid] != nums[mid+1])){ + ret[1] = mid; + break; + }else if(nums[mid] <= target){ + start = mid + 1; + }else{ + end = mid - 1; + } + } + + return ret; +} diff --git a/c/binary-search/search-in-rotated-sorted-array-ii.c b/c/binary-search/search-in-rotated-sorted-array-ii.c new file mode 100644 index 0000000..0f45dbd --- /dev/null +++ b/c/binary-search/search-in-rotated-sorted-array-ii.c @@ -0,0 +1,28 @@ +bool search(int* nums, int numsSize, int target) { + int start, mid, end; + + start = 0; + end = numsSize - 1; + while(start <= end){ + mid = (start + end) / 2; + + if(nums[mid] == target) + return true; + + if(nums[start] < nums[mid]){ + if(target >= nums[start] && target < nums[mid]) + end = mid - 1; + else + start = mid + 1; + }else if(nums[start] > nums[mid]){ + if(target > nums[mid] && target <= nums[end]) + start = mid + 1; + else + end = mid - 1; + }else{ + start++; + } + } + + return false; +} diff --git a/c/binary-search/search-in-rotated-sorted-array.c b/c/binary-search/search-in-rotated-sorted-array.c new file mode 100644 index 0000000..5008aa5 --- /dev/null +++ b/c/binary-search/search-in-rotated-sorted-array.c @@ -0,0 +1,28 @@ +int search(int* nums, int numsSize, int target) { + int start, mid, end; + + start = 0; + end = numsSize - 1; + while(start <= end){ + mid = (start + end) / 2; + if(nums[mid] == target){ + return mid; + } + + if(nums[mid] > nums[start]){ + if(target >= nums[start] && target < nums[mid]) + end = mid - 1; + else + start = mid + 1; + }else if(nums[mid] < nums[start]){ + if(target > nums[mid] && target <= nums[end]) + start = mid + 1; + else + end = mid - 1; + }else{ + start++; + } + } + + return -1; +} diff --git a/c/binary-search/search-insert-position.c b/c/binary-search/search-insert-position.c new file mode 100644 index 0000000..eb8f2cb --- /dev/null +++ b/c/binary-search/search-insert-position.c @@ -0,0 +1,24 @@ +int searchInsert(int* nums, int numsSize, int target) { + int ret = -1; + int start,end,mid; + + start = 0; + end = numsSize - 1; + + while(start <= end){ + mid = (start + end) / 2; + if(nums[mid] == target){ + ret = mid; + break; + }else if(nums[mid] > target){ + end = mid - 1; + }else{ + start = mid + 1; + } + } + + if(ret == -1) + ret = nums[mid] > target ? mid : mid + 1; + + return ret; +} diff --git a/c/binary-search/sqrtx.c b/c/binary-search/sqrtx.c new file mode 100644 index 0000000..9584e18 --- /dev/null +++ b/c/binary-search/sqrtx.c @@ -0,0 +1,18 @@ +int mySqrt(int x) { + long start,end,mid; + + start = 0; + end = x; + + while(start <= end){ + mid = (start + end) / 2; + if(mid * mid <= x && (mid + 1) * (mid+1) > x) + break; + else if(mid * mid > x) + end = mid - 1; + else + start = mid + 1; + } + + return mid; +} diff --git a/c/divide-and-conquer/kth-largest-element-in-an-array.c b/c/divide-and-conquer/kth-largest-element-in-an-array.c new file mode 100644 index 0000000..b75c6e9 --- /dev/null +++ b/c/divide-and-conquer/kth-largest-element-in-an-array.c @@ -0,0 +1,34 @@ +int findKthLargest(int* nums, int numsSize, int k) { + int start,end; + int i,j; + int tmp,value; + + start = 0; + end = numsSize - 1; + --k; + + while(start < end){ + i = start - 1; + j = end + 1; + value = nums[(i+j)/2]; + + while(i < j){ + while(nums[++i] > value) ; + + while(value > nums[--j]) ; + + if(i < j){ + tmp = nums[i]; + nums[i] = nums[j]; + nums[j] = tmp; + } + } + + if(j >= k) + end = j; + else + start = j+1; + } + + return nums[k]; +} diff --git a/c/divide-and-conquer/majority-element.c b/c/divide-and-conquer/majority-element.c new file mode 100644 index 0000000..3c7116e --- /dev/null +++ b/c/divide-and-conquer/majority-element.c @@ -0,0 +1,17 @@ +int majorityElement(int* nums, int numsSize) { + int count,value,i; + + count = 0; + for(i = 0; i < numsSize; ++i){ + if(count == 0){ + ++count; + value = nums[i]; + }else if(value == nums[i]){ + ++count; + }else{ + --count; + } + } + + return value; +} diff --git a/c/divide-and-conquer/maximum-subarray.c b/c/divide-and-conquer/maximum-subarray.c new file mode 100644 index 0000000..1a081ef --- /dev/null +++ b/c/divide-and-conquer/maximum-subarray.c @@ -0,0 +1,13 @@ +int maxSubArray(int* nums, int numsSize) { + int i, ret, sum; + + sum = 0; + ret = INT_MIN; + for(i = 0; i < numsSize; ++i){ + sum += nums[i]; + ret = sum > ret ? sum : ret; + sum = sum > 0 ? sum : 0; + } + + return ret; +} diff --git a/c/divide-and-conquer/median-of-two-sorted-arrays.c b/c/divide-and-conquer/median-of-two-sorted-arrays.c new file mode 100644 index 0000000..24355bc --- /dev/null +++ b/c/divide-and-conquer/median-of-two-sorted-arrays.c @@ -0,0 +1,34 @@ +int len1; +int len2; + +double findKth(int *nums1, int start1, int *nums2, int start2, int k) +{ + if(start1 >= len1) + return nums2[start2 + k - 1]; + if(start2 >= len2) + return nums1[start1 + k - 1]; + if(k == 1) + return nums1[start1] < nums2[start2] ? nums1[start1] : nums2[start2]; + + int value1 = start1 + k / 2 - 1 < len1 ? + nums1[start1 + k / 2 - 1] : INT_MAX; + int value2 = start2 + k / 2 - 1 < len2 ? + nums2[start2 + k / 2 - 1] : INT_MAX; + if(value1 < value2) + return findKth(nums1, start1 + k / 2, nums2, start2, k - k / 2); + else + return findKth(nums1, start1, nums2, start2 + k / 2, k - k / 2); +} + +double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { + int len; + + len1 = nums1Size; + len2 = nums2Size; + len = len1 + len2; + + if(len % 2) + return findKth(nums1,0,nums2,0,len / 2 + 1); + else + return (findKth(nums1,0,nums2,0,len / 2) + findKth(nums1,0,nums2,0,len / 2 + 1)) / 2.0; +} diff --git a/c/divide-and-conquer/merge-k-sorted-lists.c b/c/divide-and-conquer/merge-k-sorted-lists.c new file mode 100644 index 0000000..e71b43a --- /dev/null +++ b/c/divide-and-conquer/merge-k-sorted-lists.c @@ -0,0 +1,56 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode *merge_two_list(struct ListNode *l1, struct ListNode *l2) +{ + struct ListNode head; + struct ListNode *cursor,*tmp; + + cursor = &head; + + while(l1 && l2){ + if(l1->val < l2->val){ + cursor->next = l1; + l1 = l1->next; + }else{ + cursor->next = l2; + l2 = l2->next; + } + cursor = cursor->next; + } + + + if(l1) + cursor->next = l1; + else + cursor->next = l2; + + return head.next; +} + +struct ListNode* merge_list_range(struct ListNode **lists, int start, int end) +{ + struct ListNode *left, *right; + int mid; + + if(start == end) + return lists[start]; + + mid = (start + end) / 2; + + left = merge_list_range(lists, start, mid); + right = merge_list_range(lists, mid+1, end); + + return merge_two_list(left,right); +} + +struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) { + if(listsSize == 0) + return NULL; + + return merge_list_range(lists, 0, listsSize-1); +} diff --git a/c/divide-and-conquer/search-a-2d-matrix-ii.c b/c/divide-and-conquer/search-a-2d-matrix-ii.c new file mode 100644 index 0000000..9ae9dbc --- /dev/null +++ b/c/divide-and-conquer/search-a-2d-matrix-ii.c @@ -0,0 +1,17 @@ +bool searchMatrix(int** matrix, int matrixRowSize, int matrixColSize, int target) { + int row,col; + + row = matrixRowSize - 1; + col = 0; + + while(row >= 0 && col < matrixColSize){ + if(matrix[row][col] == target) + return true; + if(matrix[row][col] > target) + --row; + else + ++col; + } + + return false; +} diff --git a/c/dynamic-programming/Mem-Limit-Exceeded_wildcard-matching.c b/c/dynamic-programming/Mem-Limit-Exceeded_wildcard-matching.c new file mode 100644 index 0000000..843dcfe --- /dev/null +++ b/c/dynamic-programming/Mem-Limit-Exceeded_wildcard-matching.c @@ -0,0 +1,38 @@ +bool isMatch(char* s, char* p) { + int lens,lenp; + int i,j; + int **dp; + int ret; + + lens = strlen(s); + lenp = strlen(p); + + dp = malloc(sizeof(int *) * (lens + 1)); + for(i = 0; i <= lens; ++i){ + dp[i] = malloc(sizeof(int) * (lenp + 1)); + dp[i][0] = 0; + } + dp[0][0] = 1; + + for(i = 1; i <= lenp; ++i) + dp[0][i] = dp[0][i-1] && (p[i-1] == '*'); + + for(i = 1; i <= lens; ++i){ + for(j = 1; j <= lenp; ++j){ + if(p[j-1] == '*'){ + dp[i][j] = dp[i-1][j] || dp[i][j-1]; + }else if(p[j-1] == '?'){ + dp[i][j] = dp[i-1][j-1]; + }else{ + dp[i][j] = dp[i-1][j-1] && (s[i-1] == p[j-1]); + } + } + } + + ret = dp[lens][lenp]; + for(i = 0; i <= lens; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/c/dynamic-programming/best-time-to-buy-and-sell-stock-iii.c b/c/dynamic-programming/best-time-to-buy-and-sell-stock-iii.c new file mode 100644 index 0000000..fde8e61 --- /dev/null +++ b/c/dynamic-programming/best-time-to-buy-and-sell-stock-iii.c @@ -0,0 +1,27 @@ +int maxProfit(int* prices, int pricesSize) { + int i; + int min,max,ret; + int *left,*right; + left = (int *)malloc(sizeof(int) * pricesSize); + right = (int *)malloc(sizeof(int) * pricesSize); + + min = prices[0]; + left[0] = 0; + for(i = 1; i < pricesSize; ++i){ + min = prices[i] < min ? prices[i] : min; + left[i] = (prices[i] - min) > left[i-1] ? (prices[i] - min) : left[i-1]; + } + + max = prices[pricesSize - 1]; + right[pricesSize - 1] = 0; + ret = 0; + for(i = pricesSize - 2; i >= 0; --i){ + max = prices[i] > max ? prices[i] : max; + right[i] = (max - prices[i]) > right[i+1] ? (max - prices[i]) : right[i+1]; + ret = (left[i] + right[i]) > ret ? (left[i] + right[i]) : ret; + } + + free(left); + free(right); + return ret; +} diff --git a/c/dynamic-programming/best-time-to-buy-and-sell-stock-iv.c b/c/dynamic-programming/best-time-to-buy-and-sell-stock-iv.c new file mode 100644 index 0000000..548b31b --- /dev/null +++ b/c/dynamic-programming/best-time-to-buy-and-sell-stock-iv.c @@ -0,0 +1,37 @@ +int max_2(int a, int b) +{ + return a > b ? a : b; +} + +int maxProfit(int k, int* prices, int pricesSize) { + int *local,*global; + int ret = 0; + int i,j; + + if(k >= pricesSize){ + for(i = 1; i < pricesSize; ++i) + if(prices[i] - prices[i-1] > 0) + ret += prices[i] - prices[i-1]; + return ret; + } + + local = (int *)malloc(sizeof(int) * (k + 1)); + global= (int *)malloc(sizeof(int) * (k + 1)); + + memset(local,0,sizeof(int) * (k + 1)); + memset(global,0,sizeof(int) * (k + 1)); + + for(i = 0; i < pricesSize - 1; ++i){ + ret = prices[i+1] - prices[i]; + + for(j = k; j >= 1; --j){ + local[j] = max_2(global[j-1] + max_2(ret,0), local[j]+ret); + global[j] = max_2(global[j],local[j]); + } + } + + ret = global[k]; + free(local); + free(global); + return ret; +} diff --git a/c/dynamic-programming/best-time-to-buy-and-sell-stock-iv[2].c b/c/dynamic-programming/best-time-to-buy-and-sell-stock-iv[2].c new file mode 100644 index 0000000..d0c930b --- /dev/null +++ b/c/dynamic-programming/best-time-to-buy-and-sell-stock-iv[2].c @@ -0,0 +1,47 @@ +int max_2(int a, int b) +{ + return a > b ? a : b; +} + +int maxProfit(int k, int* prices, int pricesSize) { + int **local,**global; + int i,j; + int value; + + value = 0; + if(k >= pricesSize){ + for(i = 0; i < pricesSize-1; ++i) + if(prices[i+1] - prices[i] > 0) + value += (prices[i+1] - prices[i]); + return value; + } + + local = (int **)malloc(sizeof(int *) * pricesSize); + global = (int **)malloc(sizeof(int *) * pricesSize); + for(i = 0; i < pricesSize; ++i){ + local[i] = (int *)malloc(sizeof(int) * (k + 1)); + global[i] = (int *)malloc(sizeof(int) * (k + 1)); + + memset(local[i],0,sizeof(int) * (k + 1)); + memset(global[i],0,sizeof(int) * (k + 1)); + } + + for(i = 1; i < pricesSize; ++i){ + value = prices[i] - prices[i-1]; + + for(j = 1; j <= k; ++j){ + local[i][j] = max_2(global[i-1][j-1] + max_2(value,0), local[i-1][j] + value); + global[i][j] = max_2(global[i-1][j], local[i][j]); + } + } + + value = global[pricesSize-1][k]; + for(i = 0; i < pricesSize; ++i){ + free(local[i]); + free(global[i]); + } + + free(local); + free(global); + return value; +} diff --git a/c/dynamic-programming/best-time-to-buy-and-sell-stock-with-cooldown.c b/c/dynamic-programming/best-time-to-buy-and-sell-stock-with-cooldown.c new file mode 100644 index 0000000..3a2278b --- /dev/null +++ b/c/dynamic-programming/best-time-to-buy-and-sell-stock-with-cooldown.c @@ -0,0 +1,33 @@ +/* + * buy[i]表示在第i天之前最后一个操作是买,此时的最大收益。 + * sell[i]表示在第i天之前最后一个操作是卖,此时的最大收益。 + * rest[i]表示在第i天之前最后一个操作是冷冻期,此时的最大收益。 + * buy[i] = max(rest[i-1] - price, buy[i-1]); + * sell[i] = max(buy[i-1] + price, sell[i-1]); + * rest[i] = max(buy[i-1], sell[i-1], rest[i-1]); + * 注意: + * rest[i] = max(sell[i-1], rest[i-1]),这保证了[buy, rest, buy]不会出现。 + * + * 由于冷冻期的存在,可知rest[i] = sell[i-1],可以将上面三个递推式精简到两个: + * buy[i] = max(sell[i-2] - price, buy[i-1]); + * sell[i] = max(buy[i-1] + price, sell[i-1]); +*/ + +int max_2(int a, int b) +{ + return a > b ? a : b; +} + +int maxProfit(int* prices, int pricesSize) { + int i; + int buy = INT_MIN, pre_buy = 0, sell = 0, pre_sell = 0; + + for(i = 0; i < pricesSize; ++i){ + pre_buy = buy; + buy = max_2(pre_sell - prices[i],pre_buy); + pre_sell = sell; + sell = max_2(pre_buy + prices[i], pre_sell); + } + + return sell; +} diff --git a/c/dynamic-programming/best-time-to-buy-and-sell-stock.c b/c/dynamic-programming/best-time-to-buy-and-sell-stock.c new file mode 100644 index 0000000..a130497 --- /dev/null +++ b/c/dynamic-programming/best-time-to-buy-and-sell-stock.c @@ -0,0 +1,26 @@ +int maxProfit(int* prices, int pricesSize) { + int i; + int *min,*max; + int ret; + + min = (int *)malloc(sizeof(int) * pricesSize); + max = (int *)malloc(sizeof(int) * pricesSize); + + min[0] = prices[0]; + for(i = 1; i < pricesSize; ++i){ + min[i] = prices[i] < min[i-1] ? prices[i] : min[i-1]; + } + + max[pricesSize-1] = prices[pricesSize-1]; + for(i = pricesSize - 2; i >= 0; --i) + max[i] = prices[i] > max[i+1] ? prices[i] : max[i+1]; + + ret = 0; + for(i = 0; i < pricesSize; ++i) + if(max[i] - min[i] > ret) + ret = max[i] - min[i]; + + free(min); + free(max); + return ret; +} diff --git a/c/dynamic-programming/best-time-to-buy-and-sell-stock[2].c b/c/dynamic-programming/best-time-to-buy-and-sell-stock[2].c new file mode 100644 index 0000000..29e39a5 --- /dev/null +++ b/c/dynamic-programming/best-time-to-buy-and-sell-stock[2].c @@ -0,0 +1,13 @@ +int maxProfit(int* prices, int pricesSize) { + int i; + int ret,min; + + min = INT_MAX; + ret = 0; + for(i = 0; i < pricesSize; ++i){ + min = prices[i] < min ? prices[i] : min; + ret = (prices[i] - min) > ret ? (prices[i] - min) : ret; + } + + return ret; +} diff --git a/c/dynamic-programming/burst-balloons.c b/c/dynamic-programming/burst-balloons.c new file mode 100644 index 0000000..65d24e7 --- /dev/null +++ b/c/dynamic-programming/burst-balloons.c @@ -0,0 +1,36 @@ +int maxCoins(int* nums, int numsSize) { + int *arr; + int **dp; + int i,j,k,step; + int tmp; + + arr = malloc(sizeof(int) * (numsSize + 2)); + dp = malloc(sizeof(int *) * (numsSize + 2)); + for(i = 0; i < numsSize + 2; ++i){ + dp[i] = malloc(sizeof(int) * (numsSize + 2)); + memset(dp[i], 0, sizeof(int) * (numsSize + 2)); + } + + arr[0] = arr[numsSize + 1] = 1; + for(i = 1; i <= numsSize; ++i) + arr[i] = nums[i-1]; + + for(step = 1; step <= numsSize; ++step){ + for(i = 1; i <= numsSize - step + 1; ++i){ + j = i + step - 1; + for(k = i; k <= j; ++k){ + tmp = dp[i][k-1] + arr[i-1] * arr[k] * arr[j+1] + dp[k+1][j]; + if(tmp > dp[i][j]) + dp[i][j] = tmp; + } + } + } + + tmp = dp[1][numsSize]; + free(arr); + for(i = 0; i < numsSize + 2; ++i) + free(dp[i]); + free(dp); + + return tmp; +} diff --git a/c/dynamic-programming/climbing-stairs.c b/c/dynamic-programming/climbing-stairs.c new file mode 100644 index 0000000..1453c22 --- /dev/null +++ b/c/dynamic-programming/climbing-stairs.c @@ -0,0 +1,14 @@ +int climbStairs(int n) { + int *dp; + int i,ret; + + dp = (int *)malloc(sizeof(int) * (n + 1)); + dp[0] = 1; + dp[1] = 1; + for(i = 2; i <= n; ++i) + dp[i] = dp[i-1] + dp[i-2]; + + ret = dp[n]; + free(dp); + return ret; +} diff --git a/c/dynamic-programming/climbing-stairs[2].c b/c/dynamic-programming/climbing-stairs[2].c new file mode 100644 index 0000000..178b7f5 --- /dev/null +++ b/c/dynamic-programming/climbing-stairs[2].c @@ -0,0 +1,15 @@ +int climbStairs(int n) { + int d1,d2; + int i,ret; + + d1 = 0; + d2 = 1; + ret = 1; + for(i = 1; i <= n; ++i){ + ret = d1 + d2; + d1 = d2; + d2 = ret; + } + + return ret; +} diff --git a/c/dynamic-programming/coin-change.c b/c/dynamic-programming/coin-change.c new file mode 100644 index 0000000..2e4caea --- /dev/null +++ b/c/dynamic-programming/coin-change.c @@ -0,0 +1,30 @@ +#define min_2(x,y) ({ \ + int _x = (x); \ + int _y = (y); \ + _x < _y ? _x : _y; \ +}) + +#define MAX_VALUE (INT_MAX - 1) + +int coinChange(int* coins, int coinsSize, int amount) { + int *dp; + int i,j; + int ret; + + dp = (int *)malloc(sizeof(int) * (amount+1)); + + dp[0] = 0; + for(i = 1; i <= amount; ++i) + dp[i] = MAX_VALUE; + + for(i = 0; i <=amount; ++i){ + for(j = 0; j < coinsSize; j++) + if(i + coins[j] <= amount) + dp[i+coins[j]] = min_2(dp[i+coins[j]], dp[i] + 1); + } + + ret = dp[amount]; + free(dp); + + return ret == MAX_VALUE ? -1 : ret; +} diff --git a/c/dynamic-programming/counting-bits.c b/c/dynamic-programming/counting-bits.c new file mode 100644 index 0000000..836c8c9 --- /dev/null +++ b/c/dynamic-programming/counting-bits.c @@ -0,0 +1,25 @@ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* countBits(int num, int* returnSize) { + int *dp; + int cnt; + int i; + int tmp; + + dp = (int *)malloc(sizeof(int) * (num + 1)); + for(i = 0; i <= num; ++i){ + cnt = 0; + tmp = i; + while(tmp){ + cnt += (tmp & 0x1); + tmp >>= 1; + } + + dp[i] = cnt; + } + + *returnSize = num + 1; + return dp; +} diff --git a/c/dynamic-programming/counting-bits[2].c b/c/dynamic-programming/counting-bits[2].c new file mode 100644 index 0000000..9fcc546 --- /dev/null +++ b/c/dynamic-programming/counting-bits[2].c @@ -0,0 +1,16 @@ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* countBits(int num, int* returnSize) { + int *dp; + int i; + + dp = (int *)malloc(sizeof(int) * (num + 1)); + dp[0] = 0; + for(i = 1; i <= num; ++i) + dp[i] = dp[i >> 1] + (i & 0x1); + + *returnSize = num + 1; + return dp; +} diff --git a/c/dynamic-programming/decode-ways.c b/c/dynamic-programming/decode-ways.c new file mode 100644 index 0000000..3382852 --- /dev/null +++ b/c/dynamic-programming/decode-ways.c @@ -0,0 +1,23 @@ +int numDecodings(char* s) { + int *dp; + int i,len,value; + + len = strlen(s); + if(len == 0) + return 0; + + dp = (int *)malloc(sizeof(int) * (len + 1)); + dp[0] = 1; + dp[1] = s[0] != '0' ? 1 : 0; + for(i = 2; i <= len; ++i){ + dp[i] = s[i-1] != '0' ? dp[i-1] : 0; + + value = (s[i-2] - '0') * 10 + (s[i-1] - '0'); + if(value >= 10 && value <= 26) + dp[i] += dp[i-2]; + } + + value = dp[len]; + free(dp); + return value; +} diff --git a/c/dynamic-programming/distinct-subsequences.c b/c/dynamic-programming/distinct-subsequences.c new file mode 100644 index 0000000..ec6fc45 --- /dev/null +++ b/c/dynamic-programming/distinct-subsequences.c @@ -0,0 +1,30 @@ +int numDistinct(char* s, char* t) { + int **dp; + int i,j,len_s,len_t; + int ret; + + len_s = strlen(s); + len_t = strlen(t); + + dp = (int **)malloc(sizeof(int *) * (len_s + 1)); + for(i = 0; i <= len_s; ++i){ + dp[i] = (int *)malloc(sizeof(int) * (len_t + 1)); + memset(dp[i], 0, sizeof(int) * (len_t + 1)); + dp[i][0] = 1; + } + + for(i = 1; i <= len_s; ++i){ + for(j = 1; j <= len_t; ++j){ + dp[i][j] = dp[i-1][j]; + if(s[i-1] == t[j-1]) + dp[i][j] += dp[i-1][j-1]; + } + } + + ret = dp[len_s][len_t]; + for(i = 0; i <= len_s; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/c/dynamic-programming/dungeon-game.c b/c/dynamic-programming/dungeon-game.c new file mode 100644 index 0000000..bc49dae --- /dev/null +++ b/c/dynamic-programming/dungeon-game.c @@ -0,0 +1,44 @@ +int max(int a, int b) +{ + return a > b ? a : b; +} + +int min(int a, int b) +{ + return a < b ? a : b; +} + +int calculateMinimumHP(int** dungeon, int dungeonRowSize, int dungeonColSize) { + int **dp; + int i,j,value; + + dp = (int **)malloc(sizeof(int *) * dungeonRowSize); + for(i = 0; i < dungeonRowSize; ++i){ + dp[i] = (int *)malloc(sizeof(int) * dungeonColSize); + memset(dp[i], 0, sizeof(int) * dungeonColSize); + } + + dp[dungeonRowSize-1][dungeonColSize-1] = dungeon[dungeonRowSize-1][dungeonColSize-1] < 0 ? + - dungeon[dungeonRowSize-1][dungeonColSize-1] : 0; + + for(j = dungeonColSize - 2; j >= 0; --j) + dp[dungeonRowSize-1][j] = max(dp[dungeonRowSize-1][j+1] - dungeon[dungeonRowSize-1][j],0); + + for(i = dungeonRowSize - 2; i >= 0; --i) + dp[i][dungeonColSize-1] = max(dp[i+1][dungeonColSize-1] - dungeon[i][dungeonColSize-1],0); + + for(i = dungeonRowSize - 2; i >= 0; --i){ + for(j = dungeonColSize - 2; j >= 0; --j){ + value = min(dp[i+1][j], dp[i][j+1]); + dp[i][j] = max(value - dungeon[i][j],0); + } + } + + value = dp[0][0] + 1; + + for(i = 0; i < dungeonRowSize; ++i) + free(dp[i]); + free(dp); + + return value; +} diff --git a/c/dynamic-programming/edit-distance.c b/c/dynamic-programming/edit-distance.c new file mode 100644 index 0000000..df9ac49 --- /dev/null +++ b/c/dynamic-programming/edit-distance.c @@ -0,0 +1,47 @@ +int minDistance(char* word1, char* word2) { + int **dp; + int len1,len2; + int i,j,value; + + len1 = strlen(word1); + len2 = strlen(word2); + + if(len1 == 0 || len2 == 0) + return len1 == 0 ? len2 : len1; + + dp = (int **)malloc(sizeof(int *) * (len1+1)); + for(i = 0; i <= len1; ++i){ + dp[i] = (int *)malloc(sizeof(int) * (len2 + 1)); + memset(dp[i],0,sizeof(int) * (len2 + 1)); + } + + for(i = 1; i <= len1; ++i) + dp[i][0] = i; + for(j = 1; j <= len2; ++j) + dp[0][j] = j; + + for(i = 1; i <= len1; ++i){ + for(j = 1; j <= len2; ++j){ + if(word1[i-1] == word2[j-1]){ + dp[i][j] = dp[i-1][j-1]; + continue; + } + + /* dp[i-1][j-1]: repleace a char + * dp[i][j-1]: insert a char after word1[i] + * dp[i-1][j]: delet the char word1[i] + */ + value = dp[i][j-1] < dp[i-1][j-1] ? dp[i][j-1] : dp[i-1][j-1]; + value = dp[i-1][j] < value ? dp[i-1][j] : value; + + dp[i][j] = value + 1; + } + } + + value = dp[len1][len2]; + for(i = 0; i <= len1; ++i) + free(dp[i]); + free(dp); + + return value; +} diff --git a/c/dynamic-programming/house-robber-ii.c b/c/dynamic-programming/house-robber-ii.c new file mode 100644 index 0000000..24db053 --- /dev/null +++ b/c/dynamic-programming/house-robber-ii.c @@ -0,0 +1,33 @@ +int max_2(int a, int b) +{ + return a > b ? a : b; +} + +int rob(int* nums, int numsSize) { + int *dp0, *dp1; + int value; + int i; + + dp0 = (int *)malloc(sizeof(int) * (numsSize + 1)); + dp1 = (int *)malloc(sizeof(int) * (numsSize + 1)); + + dp0[0] = 0; + dp0[1] = nums[0]; + for(i = 2; i < numsSize; ++i) + dp0[i] = max_2(dp0[i-1], dp0[i-2] + nums[i-1]); + + if(numsSize > 1) + dp0[numsSize] = dp0[numsSize - 1]; + + dp1[0] = 0; + dp1[1] = 0; + for(i = 2; i <= numsSize; ++i) + dp1[i] = max_2(dp1[i-1], dp1[i-2] + nums[i-1]); + + value = max_2(dp0[numsSize], dp1[numsSize]); + + free(dp0); + free(dp1); + + return value; +} diff --git a/c/dynamic-programming/house-robber-ii[2].c b/c/dynamic-programming/house-robber-ii[2].c new file mode 100644 index 0000000..653fa37 --- /dev/null +++ b/c/dynamic-programming/house-robber-ii[2].c @@ -0,0 +1,31 @@ +int max_2(int a, int b) +{ + return a > b ? a : b; +} + +int rob(int* nums, int numsSize) { + int value,pre_value; + int i,tmp; + int val0; + + pre_value = 0; + value = nums[0]; + for(i = 2; i < numsSize; ++i){ + tmp = value; + value = max_2(value,pre_value + nums[i-1]); + pre_value = tmp; + } + + val0 = value; + + pre_value = 0; + value = 0; + for(i = 2; i <= numsSize; ++i){ + tmp = value; + value = max_2(value, pre_value + nums[i-1]); + pre_value = tmp; + } + + + return max_2(value,val0); +} diff --git a/c/dynamic-programming/house-robber.c b/c/dynamic-programming/house-robber.c new file mode 100644 index 0000000..69a7483 --- /dev/null +++ b/c/dynamic-programming/house-robber.c @@ -0,0 +1,14 @@ +int rob(int* nums, int numsSize) { + int *dp; + int i,value; + + dp = (int *)malloc(sizeof(int) * (numsSize + 1)); + dp[0] = 0; + dp[1] = nums[0]; + for(i = 2; i <= numsSize; ++i) + dp[i] = dp[i-2] + nums[i-1] > dp[i-1] ? dp[i-2] + nums[i-1] : dp[i-1]; + + value = dp[numsSize]; + free(dp); + return value; +} diff --git a/c/dynamic-programming/house-robber[2].c b/c/dynamic-programming/house-robber[2].c new file mode 100644 index 0000000..2603b97 --- /dev/null +++ b/c/dynamic-programming/house-robber[2].c @@ -0,0 +1,15 @@ +int rob(int* nums, int numsSize) { + int value,pre_value,tmp; + int i; + + pre_value = 0; + value = 0; + + for(i = 0; i < numsSize; ++i){ + tmp = value; + value = pre_value + nums[i] > value ? pre_value + nums[i] : value; + pre_value = tmp; + } + + return value; +} diff --git a/c/dynamic-programming/interleaving-string.c b/c/dynamic-programming/interleaving-string.c new file mode 100644 index 0000000..ae4b680 --- /dev/null +++ b/c/dynamic-programming/interleaving-string.c @@ -0,0 +1,39 @@ +bool isInterleave(char* s1, char* s2, char* s3) { + int len1,len2,len3; + int **dp; + int i,j; + bool ret; + + len1 = strlen(s1); + len2 = strlen(s2); + len3 = strlen(s3); + + if(len1 + len2 != len3) + return false; + + dp = (int **)malloc(sizeof(int *) * (len1 + 1)); + for(i = 0; i <= len1; ++i) + dp[i] = (int *)malloc(sizeof(int) * (len2 + 1)); + + dp[0][0] = 1; + for(i = 1; i <= len1; ++i) + dp[i][0] = dp[i-1][0] && (s1[i-1] == s3[i-1]); + + for(j = 1; j <= len2; ++j) + dp[0][j] = dp[0][j-1] && (s2[j-1] == s3[j-1]); + + + for(i = 1; i <= len1; ++i){ + for(j = 1; j <= len2; ++j){ + dp[i][j] = (dp[i-1][j] && (s1[i-1] == s3[i + j - 1])) || + (dp[i][j-1] && (s2[j-1] == s3[i + j - 1])); + } + } + + ret = dp[len1][len2]; + for(i = 0; i <= len1; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/c/dynamic-programming/longest-increasing-subsequence.c b/c/dynamic-programming/longest-increasing-subsequence.c new file mode 100644 index 0000000..866f072 --- /dev/null +++ b/c/dynamic-programming/longest-increasing-subsequence.c @@ -0,0 +1,29 @@ +int max_2(int a, int b) +{ + return a > b ? a : b; +} + +int lengthOfLIS(int* nums, int numsSize) { + int *dp; + int i,j; + int ret; + + dp = (int *)malloc(sizeof(int) * numsSize); + + for(i = 0; i < numsSize; ++i) + dp[i] = 1; + + for(i = 0; i < numsSize; ++i){ + for(j = 0; j < i; ++j) + if(nums[i] > nums[j]) + dp[i] = max_2(dp[i],dp[j] + 1); + } + + ret = 0; + for(i = 0; i < numsSize; ++i) + if(dp[i] > ret) + ret = dp[i]; + + free(dp); + return ret; +} diff --git a/c/dynamic-programming/longest-increasing-subsequence[2].c b/c/dynamic-programming/longest-increasing-subsequence[2].c new file mode 100644 index 0000000..a96424f --- /dev/null +++ b/c/dynamic-programming/longest-increasing-subsequence[2].c @@ -0,0 +1,35 @@ +int get_first_greater_index(int *arr, int start, int end, int target) +{ + int mid; + + while(start < end){ + mid = (start + end) / 2; + if(arr[mid] >= target) + end = mid; + else + start = mid + 1; + } + + return end; +} + +int lengthOfLIS(int* nums, int numsSize) { + int *dp; + int top; + int i,index; + + top = -1; + dp = (int *)malloc(sizeof(int) * numsSize); + + for(i = 1; i <= numsSize; ++i){ + if(top == -1 || nums[i-1] > dp[top]){ + dp[++top] = nums[i-1]; + }else{ + index = get_first_greater_index(dp,0,top,nums[i-1]); + dp[index] = nums[i-1]; + } + } + + free(dp); + return top+1; +} diff --git a/c/dynamic-programming/longest-valid-parentheses.c b/c/dynamic-programming/longest-valid-parentheses.c new file mode 100644 index 0000000..95c1782 --- /dev/null +++ b/c/dynamic-programming/longest-valid-parentheses.c @@ -0,0 +1,35 @@ +int longestValidParentheses(char* s) { + int *match,*st; + int i,top,len,cur_count,max_count; + + len = strlen(s); + match = (int *)malloc(sizeof(int) * len); + st = (int *)malloc(sizeof(int) * len); + memset(match, 0, sizeof(int) * len); + top = -1; + + for(i = 0; i < len; ++i){ + if(s[i] == '('){ + st[++top] = i; + }else if(top > -1){ + match[i] = 1; + match[st[top]] = 1; + top--; + } + } + + cur_count = 0; + max_count = 0; + for(i = 0; i < len; ++i){ + if(match[i]) + ++cur_count; + else + cur_count = 0; + max_count = cur_count > max_count ? cur_count : max_count; + } + + free(match); + free(st); + + return max_count; +} diff --git a/c/dynamic-programming/longest-valid-parentheses[2].c b/c/dynamic-programming/longest-valid-parentheses[2].c new file mode 100644 index 0000000..b39bea0 --- /dev/null +++ b/c/dynamic-programming/longest-valid-parentheses[2].c @@ -0,0 +1,22 @@ +int longestValidParentheses(char* s) { + int *dp; + int i,len,j,max_count; + + len = strlen(s); + dp = (int *)malloc(sizeof(int) * (len + 1)); + dp[0] = 0; + max_count = 0; + + for(i = 1; i <= len; ++i){ + j = i - dp[i-1] - 2; + if(s[i-1] == '(' || j < 0 || s[j] != '('){ + dp[i] = 0; + }else{ + dp[i] = dp[j] + dp[i-1] + 2; + max_count = dp[i] > max_count ? dp[i] : max_count; + } + } + + free(dp); + return max_count; +} diff --git a/c/dynamic-programming/maximal-rectangle.c b/c/dynamic-programming/maximal-rectangle.c new file mode 100644 index 0000000..e158e54 --- /dev/null +++ b/c/dynamic-programming/maximal-rectangle.c @@ -0,0 +1,55 @@ +int *stack; + +int maxArea(int *height, int col) +{ + int top; + int i; + int max_area,cur; + + max_area = 0; + top = -1; + i = 0; + for(i = 0; i <= col; ++i){ + cur = i == col ? -1 : height[i]; + while(top != -1 && cur <= height[stack[top]]){ + int h = height[stack[top--]]; + int w = top == -1 ? i : i - stack[top] - 1; + + if(h * w > max_area) + max_area = h * w; + } + + stack[++top] = i; + } + + return max_area; +} + +int maximalRectangle(char** matrix, int matrixRowSize, int matrixColSize) { + int *height; + int i, j, area, max_area; + + height = (int *)malloc(sizeof(int) * matrixColSize); + stack = (int *)malloc(sizeof(int) * matrixColSize); + memset(height, 0,sizeof(int) * matrixColSize); + + max_area = 0; + for(i = 0; i < matrixRowSize; ++i){ + for(j = 0; j < matrixColSize; ++j){ + if(matrix[i][j] == '0') + height[j] = 0; + else + height[j]++; + } + + area = maxArea(height,matrixColSize); + + if(area > max_area) + max_area = area; + } + + free(stack); + free(height); + + return max_area; +} diff --git a/c/dynamic-programming/maximal-square.c b/c/dynamic-programming/maximal-square.c new file mode 100644 index 0000000..ccffd1a --- /dev/null +++ b/c/dynamic-programming/maximal-square.c @@ -0,0 +1,51 @@ +/* +#define max_2(x, y) ({ \ + typeof(x) _max1 = (x); \ + typeof(y) _max2 = (y); \ + (void) (&_max1 == &_max2); \ + _max1 > _max2 ? _max1 : _max2; \ +}) + + +#define min_2(x, y) ({ \ + typeof(x) _min1 = (x); \ + typeof(y) _min2 = (y); \ + (void) (&_min1 == &_min2); \ + _min1 < _min2 ? _min1 : _min2; \ +}) +*/ + +#define max_2(x, y) ((x) > (y)) ? (x) : (y) +#define min_2(x, y) ((x) < (y)) ? (x) : (y) + +int maximalSquare(char** matrix, int matrixRowSize, int matrixColSize) { + int **dp; + int i,j,max_square,min_value; + + dp = (int **)malloc(sizeof(int *) * (matrixRowSize + 1)); + for(i = 0; i <= matrixRowSize; ++i){ + dp[i] = (int *)malloc(sizeof(int) * (matrixColSize + 1)); + memset(dp[i], 0, sizeof(int) * (matrixColSize + 1)); + } + + for(i = 1; i <= matrixRowSize; ++i) + for(j = 1; j <= matrixColSize; ++j){ + if(matrix[i-1][j-1] == '0') + continue; + + min_value = min_2(dp[i-1][j], dp[i-1][j-1]); + min_value = min_2(dp[i][j-1], min_value); + dp[i][j] = min_value + 1; + } + + max_square = 0; + for(i = 1; i <= matrixRowSize; ++i) + for(j = 1; j <= matrixColSize; ++j) + max_square = max_2(max_square,dp[i][j] * dp[i][j]); + + for(i = 0; i <= matrixRowSize; ++i) + free(dp[i]); + free(dp); + + return max_square; +} diff --git a/c/dynamic-programming/maximum-product-subarray.c b/c/dynamic-programming/maximum-product-subarray.c new file mode 100644 index 0000000..a5eb779 --- /dev/null +++ b/c/dynamic-programming/maximum-product-subarray.c @@ -0,0 +1,40 @@ +#define max_2(x, y) ({ \ + int _x = (x); \ + int _y = (y); \ + _x > _y ? _x : _y; \ +}) + +#define min_2(x, y) ({ \ + int _x = (x); \ + int _y = (y); \ + _x < _y ? _x : _y; \ +}) + +int maxProduct(int* nums, int numsSize) { + int cur_min, cur_max; + int prev_min, prev_max; + int max_value; + int i; + + cur_min = nums[0]; + cur_max = nums[0]; + max_value = nums[0]; + for(i = 1; i < numsSize; ++i){ + prev_min = cur_min; + prev_max = cur_max; + cur_min = nums[i]; + cur_max = nums[i]; + + if(nums[i] > 0){ + cur_max = max_2(cur_max, prev_max * nums[i]); + cur_min = min_2(cur_min, prev_min * nums[i]); + }else{ + cur_max = max_2(cur_max, prev_min * nums[i]); + cur_min = min_2(cur_min, prev_max * nums[i]); + } + + max_value = max_2(max_value, cur_max); + } + + return max_value; +} diff --git a/c/dynamic-programming/maximum-subarray.c b/c/dynamic-programming/maximum-subarray.c new file mode 100644 index 0000000..f44aa56 --- /dev/null +++ b/c/dynamic-programming/maximum-subarray.c @@ -0,0 +1,20 @@ +#define max_2(x, y) ({ \ + int _x = (x); \ + int _y = (y); \ + _x > _y ? _x : _y; \ +}) + +int maxSubArray(int* nums, int numsSize) { + int max_sum, cur_sum; + int i; + + max_sum = nums[0]; + cur_sum = 0; + for(i = 0; i < numsSize; ++i){ + cur_sum += nums[i]; + max_sum = max_2(cur_sum, max_sum); + cur_sum = max_2(0, cur_sum); + } + + return max_sum; +} diff --git a/c/dynamic-programming/maximum-subarray[2].c b/c/dynamic-programming/maximum-subarray[2].c new file mode 100644 index 0000000..bc659c5 --- /dev/null +++ b/c/dynamic-programming/maximum-subarray[2].c @@ -0,0 +1,22 @@ +#define max_2(x, y) ({ \ + int _x = (x); \ + int _y = (y); \ + _x > _y ? _x : _y; \ +}) + +int maxSubArray(int* nums, int numsSize) { + int *sum; + int i,ret; + + sum = (int *)malloc(sizeof(int) * numsSize); + sum[0] = nums[0]; + for(i = 1; i < numsSize; ++i) + sum[i] = max_2(nums[i], nums[i] + sum[i-1]); + + ret = INT_MIN; + for(i = 0; i < numsSize; ++i) + ret = max_2(sum[i], ret); + + free(sum); + return ret; +} diff --git a/c/dynamic-programming/maximum-subarray[3].c b/c/dynamic-programming/maximum-subarray[3].c new file mode 100644 index 0000000..9a4d2e7 --- /dev/null +++ b/c/dynamic-programming/maximum-subarray[3].c @@ -0,0 +1,22 @@ +#define max_2(x, y) ({ \ + int _x = (x); \ + int _y = (y); \ + _x > _y ? _x : _y; \ +}) + +//DP +int maxSubArray(int* nums, int numsSize) { + int cur_sum,pre_sum; + int max_value; + int i; + + cur_sum = nums[0]; + max_value = nums[0]; + for(i = 1; i < numsSize; ++i){ + pre_sum = cur_sum; + cur_sum = max_2(nums[i], nums[i] + pre_sum); + max_value = max_2(cur_sum, max_value); + } + + return max_value; +} diff --git a/c/dynamic-programming/minimum-path-sum.c b/c/dynamic-programming/minimum-path-sum.c new file mode 100644 index 0000000..1155486 --- /dev/null +++ b/c/dynamic-programming/minimum-path-sum.c @@ -0,0 +1,33 @@ +#define min_2(x, y) ({ \ + int _x = (x); \ + int _y = (y); \ + _x < _y ? _x : _y; \ +}) + +int minPathSum(int** grid, int gridRowSize, int gridColSize) { + int **dp; + int i,j,ret; + + dp = (int **)malloc(sizeof(int *) * gridRowSize); + for(i = 0; i < gridRowSize; ++i) + dp[i] = (int *)malloc(sizeof(int) * gridColSize); + + dp[0][0] = grid[0][0]; + for(i = 1; i < gridRowSize; ++i) + dp[i][0] = grid[i][0] + dp[i-1][0]; + + for(j = 1; j < gridColSize; ++j) + dp[0][j] = grid[0][j] + dp[0][j-1]; + + for(i = 1; i < gridRowSize; ++i) + for(j = 1; j < gridColSize; ++j) + dp[i][j] = min_2(dp[i-1][j], dp[i][j-1]) + grid[i][j]; + + ret = dp[gridRowSize-1][gridColSize-1]; + + for(i = 0; i < gridRowSize; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/c/dynamic-programming/palindrome-partitioning-ii.c b/c/dynamic-programming/palindrome-partitioning-ii.c new file mode 100644 index 0000000..2afac83 --- /dev/null +++ b/c/dynamic-programming/palindrome-partitioning-ii.c @@ -0,0 +1,42 @@ +#define min_2(x, y) ({ \ + int _x = (x); \ + int _y = (y); \ + _x < _y ? _x : _y; \ +}) + +int minCut(char* s) { + int i,j; + int len; + int *dp; + int **p; + int ret; + + len = strlen(s); + dp = (int *)malloc(sizeof(int) * (len + 1)); + p = (int **)malloc(sizeof(int *) * len); + for(i = 0; i < len; ++i){ + p[i] = (int *)malloc(sizeof(int) * len); + memset(p[i], 0, sizeof(int) * len); + p[i][i] = 1; + } + + dp[len] = -1; + for(i = len-1; i >= 0; --i){ + dp[i] = dp[i+1] + 1; + for(j = i+1; j <= len-1; ++j){ + if(s[i] == s[j] && (j - i < 2 || p[i+1][j-1])){ + p[i][j] = 1; + dp[i] = min_2(dp[i], 1 + dp[j+1]); + } + } + } + + ret = dp[0]; + + free(dp); + for(i = 0; i < len; ++i) + free(p[i]); + free(p); + + return ret; +} diff --git a/c/dynamic-programming/perfect-squares.c b/c/dynamic-programming/perfect-squares.c new file mode 100644 index 0000000..83a291d --- /dev/null +++ b/c/dynamic-programming/perfect-squares.c @@ -0,0 +1,26 @@ +#define min_2(x, y) ({ \ + int _x = (x); \ + int _y = (y); \ + _x < _y ? _x : _y; \ +}) + + +int numSquares(int n) { + int ret; + int i,j; + int *dp; + + dp = (int *)malloc(sizeof(int) * (n + 1)); + dp[0] = 0; + dp[1] = 1; + + for(i = 2; i <= n; ++i){ + dp[i] = i; + for(j = 1; j*j <= i; ++j) + dp[i] = min_2(1 + dp[i-j*j], dp[i]); + } + + ret = dp[n]; + free(dp); + return ret; +} diff --git a/c/dynamic-programming/range-sum-query-2d-immutable.c b/c/dynamic-programming/range-sum-query-2d-immutable.c new file mode 100644 index 0000000..52c4fb5 --- /dev/null +++ b/c/dynamic-programming/range-sum-query-2d-immutable.c @@ -0,0 +1,51 @@ +struct NumMatrix { + int row; + int col; + int **arr; +}; + +/** Initialize your data structure here. */ +struct NumMatrix* NumMatrixCreate(int** matrix, int matrixRowSize, int matrixColSize) { + struct NumMatrix *nm; + int i,j; + nm = malloc(sizeof(struct NumMatrix)); + nm->row = matrixRowSize + 1; + nm->col = matrixColSize + 1; + nm->arr = malloc(sizeof(int *) * nm->row); + for(i = 0; i < nm->row; ++i){ + nm->arr[i] = malloc(sizeof(int) * nm->col); + nm->arr[i][0] = 0; + } + + memset(nm->arr[0], 0, sizeof(int) * nm->col); + + for(i = 1; i < nm->row; ++i){ + for(j = 1; j < nm->col; ++j){ + nm->arr[i][j] = matrix[i-1][j-1] + nm->arr[i][j-1] + + nm->arr[i-1][j] - nm->arr[i-1][j-1]; + } + } + + return nm; +} + +int sumRegion(struct NumMatrix* numMatrix, int row1, int col1, int row2, int col2) { + int **arr = numMatrix->arr; + + return arr[row2+1][col2+1] - arr[row1][col2+1] - arr[row2+1][col1] + arr[row1][col1]; +} + +/** Deallocates memory previously allocated for the data structure. */ +void NumMatrixFree(struct NumMatrix* numMatrix) { + int i,j; + for(i = 0; i < numMatrix->row; ++i) + free(numMatrix->arr[i]); + free(numMatrix->arr); + free(numMatrix); +} + +// Your NumMatrix object will be instantiated and called as such: +// struct NumMatrix* numMatrix = NumMatrixCreate(matrix, matrixRowSize, matrixColSize); +// sumRegion(numMatrix, 0, 1, 2, 3); +// sumRegion(numMatrix, 1, 2, 3, 4); +// NumMatrixFree(numMatrix); diff --git a/c/dynamic-programming/range-sum-query-immutable.c b/c/dynamic-programming/range-sum-query-immutable.c new file mode 100644 index 0000000..b5bee5f --- /dev/null +++ b/c/dynamic-programming/range-sum-query-immutable.c @@ -0,0 +1,38 @@ +struct NumArray { + int size; + int *dp; +}; + +/** Initialize your data structure here. */ +struct NumArray* NumArrayCreate(int* nums, int numsSize) { + struct NumArray* na; + int i; + int *dp; + + na = malloc(sizeof(struct NumArray)); + na->size = numsSize + 1; + na->dp = malloc(sizeof(int) * na->size); + dp = na->dp; + + dp[0] = 0; + for(i = 0; i < numsSize; ++i) + dp[i+1] = dp[i] + nums[i]; + + return na; +} + +int sumRange(struct NumArray* numArray, int i, int j) { + return numArray->dp[j+1] - numArray->dp[i]; +} + +/** Deallocates memory previously allocated for the data structure. */ +void NumArrayFree(struct NumArray* numArray) { + free(numArray->dp); + free(numArray); +} + +// Your NumArray object will be instantiated and called as such: +// struct NumArray* numArray = NumArrayCreate(nums, numsSize); +// sumRange(numArray, 0, 1); +// sumRange(numArray, 1, 2); +// NumArrayFree(numArray); diff --git a/c/dynamic-programming/regular-expression-matching.c b/c/dynamic-programming/regular-expression-matching.c new file mode 100644 index 0000000..aed67b1 --- /dev/null +++ b/c/dynamic-programming/regular-expression-matching.c @@ -0,0 +1,38 @@ +bool isMatch(char* s, char* p) { + int **dp; + int len_s, len_p; + int i,j; + int ret; + + len_s = strlen(s); + len_p = strlen(p); + dp = (int **)malloc(sizeof(int *) * (len_s + 1)); + for(i = 0; i <= len_s; ++i){ + dp[i] = (int *)malloc(sizeof(int) * (len_p + 1)); + memset(dp[i], 0, sizeof(int) * (len_p + 1)); + } + + dp[0][0] = 1; + for(i = 0; i <= len_s; ++i){ + for(j = 1; j <= len_p; ++j){ + if(p[j-1] != '.' && p[j-1] != '*'){ + dp[i][j] = (i > 0 && dp[i-1][j-1] && s[i-1] == p[j-1]); + } else if(p[j-1] == '.'){ + dp[i][j] = (i > 0 && dp[i-1][j-1]); + }else if(j > 1){ + if(dp[i][j-1] || dp[i][j-2]) + dp[i][j] = 1; + else if(i>0 && (p[j-2]==s[i-1] || p[j-2]=='.') && dp[i-1][j]) + dp[i][j] = 1; + } + } + } + + ret = dp[len_s][len_p]; + + for(i = 0; i <= len_s; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/c/dynamic-programming/regular-expression-matching[2].c b/c/dynamic-programming/regular-expression-matching[2].c new file mode 100644 index 0000000..1ee7104 --- /dev/null +++ b/c/dynamic-programming/regular-expression-matching[2].c @@ -0,0 +1,15 @@ +bool isMatch(char* s, char* p) { + if(*p == 0) + return *s == 0; + if(p[1] != '*') + return (*s == *p || (*p == '.' && *s != 0)) && + isMatch(s+1,p+1); + + while((*s == *p) || (*p == '.' && *s != 0)){ + if(isMatch(s,p+2)) + return true; + s++; + } + + return isMatch(s,p+2); +} diff --git a/c/dynamic-programming/triangle.c b/c/dynamic-programming/triangle.c new file mode 100644 index 0000000..3f29079 --- /dev/null +++ b/c/dynamic-programming/triangle.c @@ -0,0 +1,35 @@ +#define min_2(x, y) ({ \ + int _x = (x); \ + int _y = (y); \ + _x < _y ? _x : y; \ +}) + +int minimumTotal(int** triangle, int triangleRowSize, int *triangleColSizes) { + int i,j,prev,tmp; + int *dp; + int ret; + int max_num; + + max_num = triangleColSizes[triangleRowSize-1]; + dp = (int *)malloc(sizeof(int) * max_num); + for(j = 0; j < triangleColSizes[0]; ++j) + dp[j] = triangle[0][j]; + + for(i = 1; i < triangleRowSize; ++i){ + prev = dp[0]; + dp[0] += triangle[i][0]; + for(j = 1; j < triangleColSizes[i] - 1; ++j){ + tmp = dp[j]; + dp[j] = min_2(prev, dp[j]) + triangle[i][j]; + prev = tmp; + } + dp[j] = prev + triangle[i][j]; + } + + ret = dp[0]; + for(j = 1; j < max_num; ++j) + ret = min_2(ret, dp[j]); + + free(dp); + return ret; +} diff --git a/c/dynamic-programming/ugly-number-ii.c b/c/dynamic-programming/ugly-number-ii.c new file mode 100644 index 0000000..b17d69c --- /dev/null +++ b/c/dynamic-programming/ugly-number-ii.c @@ -0,0 +1,35 @@ +#define min_3(x, y, z) ({ \ + int _x = (x); \ + int _y = (y); \ + int _z = (z); \ + int _min = _x < _y ? _x : _y; \ + _z < _min ? _z : _min; \ +}) + +int nthUglyNumber(int n) { + int *arr; + int ret; + int t2,t3,t5; + int c; + + arr = (int *)malloc(sizeof(int) * n); + arr[0] = 1; + t2 = t3 = t5 = 0; + c = 1; + + while(c < n){ + int tmp = min_3(arr[t2] * 2, arr[t3] * 3, arr[t5] * 5); + arr[c++] = tmp; + + while(arr[t2] * 2 <= tmp) + t2++; + while(arr[t3] * 3 <= tmp) + t3++; + while(arr[t5] * 5 <= tmp) + t5++; + } + + ret = arr[n-1]; + free(arr); + return ret; +} diff --git a/c/dynamic-programming/unique-binary-search-trees.c b/c/dynamic-programming/unique-binary-search-trees.c new file mode 100644 index 0000000..5d6acfe --- /dev/null +++ b/c/dynamic-programming/unique-binary-search-trees.c @@ -0,0 +1,18 @@ +int numTrees(int n) { + int *dp; + int i,j; + int ret; + + dp = (int *)malloc(sizeof(int) * (n + 1)); + dp[0] = 1; + + for(i = 1; i <= n; ++i){ + dp[i] = 0; + for(j = 1; j <= i; ++j) + dp[i] += (dp[j-1] * dp[i-j]); + } + + ret = dp[n]; + free(dp); + return ret; +} diff --git a/c/dynamic-programming/unique-paths-ii.c b/c/dynamic-programming/unique-paths-ii.c new file mode 100644 index 0000000..18f0098 --- /dev/null +++ b/c/dynamic-programming/unique-paths-ii.c @@ -0,0 +1,26 @@ +int uniquePathsWithObstacles(int** obstacleGrid, int obstacleGridRowSize, int obstacleGridColSize) { + int **dp; + int i,j; + int ret; + + dp = malloc(sizeof(int *) * obstacleGridRowSize); + for(i = 0; i < obstacleGridRowSize; ++i) + dp[i] = malloc(sizeof(int) * obstacleGridColSize); + + dp[0][0] = ((obstacleGrid[0][0] == 1) ? 0 : 1); + for(i = 1; i < obstacleGridRowSize; ++i) + dp[i][0] = (dp[i-1][0] != 0 && obstacleGrid[i][0] != 1) ? 1 : 0; + for(j = 1; j < obstacleGridColSize; ++j) + dp[0][j] = (dp[0][j-1] != 0 && obstacleGrid[0][j] != 1) ? 1 : 0; + + for(i = 1; i < obstacleGridRowSize; ++i) + for(j = 1; j < obstacleGridColSize; ++j) + dp[i][j] = ((obstacleGrid[i][j] == 1) ? 0 : (dp[i-1][j] + dp[i][j-1])); + + ret = dp[obstacleGridRowSize-1][obstacleGridColSize-1]; + for(i = 0; i < obstacleGridRowSize; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/c/dynamic-programming/unique-paths-ii[2].c b/c/dynamic-programming/unique-paths-ii[2].c new file mode 100644 index 0000000..7c61a3a --- /dev/null +++ b/c/dynamic-programming/unique-paths-ii[2].c @@ -0,0 +1,29 @@ +int uniquePathsWithObstacles(int** obstacleGrid, int obstacleGridRowSize, int obstacleGridColSize) { + int *dp; + int i,j,ret; + + dp = malloc(sizeof(int) * obstacleGridColSize); + + dp[0] = ((obstacleGrid[0][0] == 1) ? 0 : 1); + for(j = 1;j < obstacleGridColSize; ++j){ + if(obstacleGrid[0][j] == 1) + dp[j] = 0; + else + dp[j] = dp[j-1]; + } + + for(i = 1; i < obstacleGridRowSize; ++i){ + if(obstacleGrid[i][0] == 1) + dp[0] = 0; + for(j = 1; j < obstacleGridColSize; ++j){ + if(obstacleGrid[i][j] == 1) + dp[j] = 0; + else + dp[j] = dp[j-1]+dp[j]; + } + } + + ret = dp[obstacleGridColSize-1]; + free(dp); + return ret; +} diff --git a/c/dynamic-programming/unique-paths.c b/c/dynamic-programming/unique-paths.c new file mode 100644 index 0000000..56278fc --- /dev/null +++ b/c/dynamic-programming/unique-paths.c @@ -0,0 +1,26 @@ +int uniquePaths(int m, int n) { + int **dp; + int i,j; + int ret; + + dp = (int **)malloc(sizeof(int *) * m); + for(i = 0; i < m; ++i) + dp[i] = (int *)malloc(sizeof(int) * n); + + for(i = 0; i < m; ++i) + dp[i][0] = 1; + for(j = 0; j < n; ++j) + dp[0][j] = 1; + + for(i = 1; i < m; ++i){ + for(j = 1; j < n; ++j) + dp[i][j] = dp[i][j-1] + dp[i-1][j]; + } + + ret = dp[m-1][n-1]; + for(i = 0; i < m; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/c/dynamic-programming/unique-paths[2].c b/c/dynamic-programming/unique-paths[2].c new file mode 100644 index 0000000..2a6411f --- /dev/null +++ b/c/dynamic-programming/unique-paths[2].c @@ -0,0 +1,17 @@ +int uniquePaths(int m, int n) { + int *dp; + int i,j; + int ret; + + dp = malloc(sizeof(int) * n); + for(i = 0; i < n; ++i) + dp[i] = 1; + + for(i = 1; i < m; ++i) + for(j = 1; j < n; ++j) + dp[j] += dp[j-1]; + + ret = dp[n-1]; + free(dp); + return ret; +} diff --git a/c/dynamic-programming/wildcard-matching.c b/c/dynamic-programming/wildcard-matching.c new file mode 100644 index 0000000..643ab76 --- /dev/null +++ b/c/dynamic-programming/wildcard-matching.c @@ -0,0 +1,40 @@ +bool isMatch(char* s, char* p) { + int lens, lenp; + int index_s, index_p; + int back; + int prev_s, prev_p; + + lens = strlen(s); + lenp = strlen(p); + index_s = 0; + index_p = 0; + back = 0; + + while(index_s < lens){ + if(index_p < lenp && (p[index_p] == '?' || p[index_p] == s[index_s])){ + index_s++; + index_p++; + }else if(p[index_p] == '*'){ + while(index_p < lenp && p[index_p] == '*') + index_p++; + + if(index_p == lenp) + return true; + + back = 1; + prev_s = index_s; + prev_p = index_p; + }else if(back){ + prev_s++; + index_s = prev_s; + index_p = prev_p; + }else{ + return false; + } + } + + while(index_p < lenp && p[index_p] == '*') + index_p++; + + return index_p == lenp; +} diff --git a/c/greedy/assign-cookies.c b/c/greedy/assign-cookies.c new file mode 100644 index 0000000..9cacbbd --- /dev/null +++ b/c/greedy/assign-cookies.c @@ -0,0 +1,23 @@ +int cmp(const void *a, const void *b) +{ + return *(int *)a - *(int *)b; +} + +int findContentChildren(int* g, int gSize, int* s, int sSize) { + int i = gSize - 1; + int j = sSize - 1; + int ret = 0; + + qsort(g, gSize, sizeof(int), cmp); + qsort(s, sSize, sizeof(int), cmp); + + while(i >= 0 && j >= 0){ + if(s[j] >= g[i]){ + j--; + ret++; + } + i--; + } + + return ret; +} diff --git a/c/hash-table/4sum-ii.c b/c/hash-table/4sum-ii.c new file mode 100644 index 0000000..ef19981 --- /dev/null +++ b/c/hash-table/4sum-ii.c @@ -0,0 +1,82 @@ +struct node { + int key; + int value; + struct node *left; + struct node *right; +}; + +struct node *add_node(struct node *head, int key) +{ + struct node *new_node, *cur; + new_node = malloc(sizeof(struct node)); + new_node->key = key; + new_node->value = 1; + new_node->left = NULL; + new_node->right = NULL; + if(head == NULL) + return new_node; + + cur = head; + while(cur){ + if(cur->key == key){ + free(new_node); + cur->value++; + break; + }else if(cur->key > key){ + if(cur->left == NULL){ + cur->left = new_node; + break; + } + cur = cur->left; + }else{ + if(cur->right == NULL){ + cur->right = new_node; + break; + } + cur = cur->right; + } + } + + return head; +} + +int get_value_by_key(struct node *head, int key) +{ + while(head){ + if(head->key == key) + break; + if(head->key > key) + head = head->left; + else + head = head->right; + } + + return head ? head->value : 0; +} + +void free_node(struct node *head) +{ + if(head){ + free_node(head->left); + free_node(head->right); + free(head); + } +} + +int fourSumCount(int* A, int ASize, int* B, int BSize, int* C, int CSize, int* D, int DSize) +{ + int i,j; + struct node *head = NULL; + int ret = 0; + + for(i = 0; i < ASize; ++i) + for(j = 0; j < BSize; ++j) + head = add_node(head, A[i] + B[j]); + + for(i = 0; i < CSize; ++i) + for(j = 0; j < DSize; ++j) + ret += get_value_by_key(head, -(C[i] + D[j])); + + free_node(head); + return ret; +} diff --git a/c/hash-table/4sum.c b/c/hash-table/4sum.c new file mode 100644 index 0000000..dfad55e --- /dev/null +++ b/c/hash-table/4sum.c @@ -0,0 +1,66 @@ +/** + * Return an array of arrays of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ + +int cmp(const void *a, const void *b) +{ + return *(const int *)a - *(const int *)b; +} + +int* get_4sum(int a, int b, int c, int d) +{ + int *arr = malloc(sizeof(int) * 4); + arr[0] = a; + arr[1] = b; + arr[2] = c; + arr[3] = d; + + return arr; +} + +int** fourSum(int* nums, int numsSize, int target, int* returnSize) { + int **ret; + int idx = 0; + int count = 32; + int i,j, start, end,sum; + + ret = malloc(sizeof(int *) * count); + qsort(nums,numsSize, sizeof(int), cmp); + + for(i = 0; i < numsSize - 3; ++i){ + if(i > 0 && nums[i] == nums[i-1]) + continue; + + for(j = i + 1; j < numsSize - 2; ++j){ + if(j > i + 1 && nums[j] == nums[j-1]) + continue; + + start = j + 1; + end = numsSize - 1; + while(start < end){ + sum = nums[i] + nums[j] + nums[start] + nums[end]; + if(sum == target){ + if(idx == count){ + count <<= 1; + ret = realloc(ret, sizeof(int *) * count); + } + ret[idx++] = get_4sum(nums[i], nums[j], nums[start], nums[end]); + ++start; + --end; + while(start < end && nums[start] == nums[start - 1]) + ++start; + while(start < end && nums[end] == nums[end + 1]) + --end; + }else if(sum > target){ + --end; + }else{ + ++start; + } + } + } + } + + *returnSize = idx; + return ret; +} diff --git a/c/hash-table/binary-tree-inorder-traversal.c b/c/hash-table/binary-tree-inorder-traversal.c new file mode 100644 index 0000000..00af43f --- /dev/null +++ b/c/hash-table/binary-tree-inorder-traversal.c @@ -0,0 +1,43 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ + +int *arr; +int count; +int idx; + +void dfs(struct TreeNode* root) +{ + if(root == NULL) + return; + + dfs(root->left); + + if(idx == 0 || idx == count){ + count <<= 1; + arr = realloc(arr,sizeof(int) * count); + } + arr[idx++] = root->val; + + dfs(root->right); +} + +int* inorderTraversal(struct TreeNode* root, int* returnSize) { + arr = NULL; + count = 32; + idx = 0; + + dfs(root); + + *returnSize = idx; + return arr; +} diff --git a/c/hash-table/binary-tree-inorder-traversal[1].c b/c/hash-table/binary-tree-inorder-traversal[1].c new file mode 100644 index 0000000..c7532c3 --- /dev/null +++ b/c/hash-table/binary-tree-inorder-traversal[1].c @@ -0,0 +1,38 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* inorderTraversal(struct TreeNode* root, int* returnSize) { + struct TreeNode *st[1000]; + int top = -1; + int *arr; + int idx = 0; + int count = 32; + + arr = malloc(sizeof(int) * count); + while(root != NULL || top > -1){ + while(root){ + st[++top] = root; + root = root->left; + } + + root = st[top--]; + if(idx == count){ + count <<= 1; + arr = realloc(arr, sizeof(int) * count); + } + arr[idx++] = root->val; + root = root->right; + } + + *returnSize = idx; + return arr; +} diff --git a/c/hash-table/bulls-and-cows.c b/c/hash-table/bulls-and-cows.c new file mode 100644 index 0000000..644d44b --- /dev/null +++ b/c/hash-table/bulls-and-cows.c @@ -0,0 +1,29 @@ +char* getHint(char* secret, char* guess) { + int *ret; + int a = 0; + int b = 0; + int len = strlen(guess); + int m[256] = {0}; + + ret = malloc(sizeof(int) * (len+2)); + + for(int i = 0; i < len; ++i){ + if(secret[i] == guess[i]){ + ++a; + }else{ + m[secret[i]]++; + } + } + + for(int i = 0; i < len; ++i){ + if(secret[i] != guess[i] && m[guess[i]]){ + m[guess[i]]--; + ++b; + } + } + + len = sprintf(ret, "%dA%dB", a, b); + ret[len] = 0; + + return ret; +} diff --git a/c/hash-table/contains-duplicate-ii.c b/c/hash-table/contains-duplicate-ii.c new file mode 100644 index 0000000..959fb79 --- /dev/null +++ b/c/hash-table/contains-duplicate-ii.c @@ -0,0 +1,10 @@ +bool containsNearbyDuplicate(int* nums, int numsSize, int k) { + int i,j; + for(i = 0; i < numsSize; ++i){ + for(j = i + 1; j <= i + k && j < numsSize; ++j) + if(nums[i] == nums[j]) + return true; + } + + return false; +} diff --git a/c/hash-table/contains-duplicate.c b/c/hash-table/contains-duplicate.c new file mode 100644 index 0000000..97e369f --- /dev/null +++ b/c/hash-table/contains-duplicate.c @@ -0,0 +1,14 @@ +int cmp(const void *a, const void *b) +{ + return *(const int *)a - *(const int *)b; +} + +bool containsDuplicate(int* nums, int numsSize) { + qsort(nums, numsSize, sizeof(int),cmp); + + for(int i = 0; i < numsSize -1; ++i) + if(nums[i] == nums[i+1]) + return true; + + return false; +} diff --git a/c/hash-table/copy-list-with-random-pointer.c b/c/hash-table/copy-list-with-random-pointer.c new file mode 100644 index 0000000..afd5c3f --- /dev/null +++ b/c/hash-table/copy-list-with-random-pointer.c @@ -0,0 +1,48 @@ +/** + * Definition for singly-linked list with a random pointer. + * struct RandomListNode { + * int label; + * struct RandomListNode *next; + * struct RandomListNode *random; + * }; + */ +struct RandomListNode *copyRandomList(struct RandomListNode *head) { + struct RandomListNode root; + struct RandomListNode *pre; + struct RandomListNode *new_node; + + root.next = head; + while(head){ + new_node = malloc(sizeof(struct RandomListNode)); + new_node->next = head->next; + new_node->label = head->label; + head->next = new_node; + head = head->next->next; + } + + head = root.next; + while(head){ + new_node = head->next; + if(head->random) + new_node->random = head->random->next; + else + new_node->random = NULL; + + head = head->next->next; + } + + head = root.next; + pre = &root; + while(head){ + new_node = head->next; + head->next = new_node->next; + head = head->next; + + pre->next = new_node; + pre = new_node; + } + + pre->next = NULL; + + return root.next; +} diff --git a/c/hash-table/count-primes.c b/c/hash-table/count-primes.c new file mode 100644 index 0000000..1d06e73 --- /dev/null +++ b/c/hash-table/count-primes.c @@ -0,0 +1,18 @@ +int countPrimes(int n) { + int *arr; + int count = 0; + int i,j; + + arr = malloc(sizeof(int) * n); + memset(arr, 0, sizeof(int) * n); + for(i = 2; i < n; ++i){ + if(arr[i]) + continue; + ++count; + for(j = i * 2; j < n; j += i) + arr[j] = 1; + } + + free(arr); + return count; +} diff --git a/c/hash-table/find-all-anagrams-in-a-string.c b/c/hash-table/find-all-anagrams-in-a-string.c new file mode 100644 index 0000000..12e9299 --- /dev/null +++ b/c/hash-table/find-all-anagrams-in-a-string.c @@ -0,0 +1,36 @@ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* findAnagrams(char* s, char* p, int* returnSize) { + int *ret; + int hp[256] = {0}; + int i; + int ls, lp; + int count, index = 0; + + ls = strlen(s); + lp = strlen(p); + count = lp; + ret = malloc(sizeof(int) * ls); + + for(i = 0; i < lp; ++i) + hp[p[i]]++; + + for(i = 0; i < ls; ++i){ + if(hp[s[i]] > 0) + count--; + hp[s[i]]--; + if(i >= lp){ + if(hp[s[i - lp]] >= 0) + count++; + hp[s[i - lp]]++; + } + + if(count == 0) + ret[index++] = i - lp + 1; + } + + *returnSize = index; + return ret; +} diff --git a/c/hash-table/find-the-difference.c b/c/hash-table/find-the-difference.c new file mode 100644 index 0000000..b19ffc1 --- /dev/null +++ b/c/hash-table/find-the-difference.c @@ -0,0 +1,16 @@ +char findTheDifference(char* s, char* t) { + int hash[256] = {0}; + int len = strlen(s); + int i; + + for(i = 0; i < len; ++i) + hash[s[i]]++; + + for(i = 0; i <= len; ++i) + if(hash[t[i]] == 0) + break; + else + --hash[t[i]]; + + return t[i]; +} diff --git a/c/hash-table/happy-number.c b/c/hash-table/happy-number.c new file mode 100644 index 0000000..410247b --- /dev/null +++ b/c/hash-table/happy-number.c @@ -0,0 +1,23 @@ +bool happy(int n, int *count) +{ + if(n == 1) + return true; + if(*count == 100 || n == 0) + return false; + + int tmp = 0; + int d; + while(n > 0){ + d = n % 10; + n /= 10; + tmp += d * d; + } + + *count++; + return happy(tmp,count); +} + +bool isHappy(int n) { + int count = 0; + return happy(n,&count); +} diff --git a/c/hash-table/happy-number[1].c b/c/hash-table/happy-number[1].c new file mode 100644 index 0000000..c0b583a --- /dev/null +++ b/c/hash-table/happy-number[1].c @@ -0,0 +1,28 @@ +bool isHappy(int n) { + int *flag; + int tmp; + const int N = 100; + + flag = malloc(sizeof(int) * N); + memset(flag, 0, sizeof(int) * N); + + while(1){ + if(n == 1) + break; + if(n < 100 && flag[n]) + break; + + if(n < 100) + flag[n] = 1; + + tmp = 0; + while(n > 0){ + tmp += (n % 10) * (n % 10); + n /= 10; + } + n = tmp; + } + + free(flag); + return n == 1; +} diff --git a/c/hash-table/island-perimeter.c b/c/hash-table/island-perimeter.c new file mode 100644 index 0000000..54fee2b --- /dev/null +++ b/c/hash-table/island-perimeter.c @@ -0,0 +1,22 @@ +int islandPerimeter(int** grid, int gridRowSize, int gridColSize) { + int perimeter = 0; + int i,j; + + for(i = 0; i < gridRowSize; ++i){ + for(j = 0; j < gridColSize; ++j){ + if(grid[i][j] == 0) + continue; + + if(j == 0 || grid[i][j-1] == 0) + perimeter++; + if(i == 0 || grid[i-1][j] == 0) + perimeter++; + if(j == gridColSize -1 || grid[i][j+1] == 0) + perimeter++; + if(i == gridRowSize -1 || grid[i+1][j] == 0) + perimeter++; + } + } + + return perimeter; +} diff --git a/c/hash-table/isomorphic-strings.c b/c/hash-table/isomorphic-strings.c new file mode 100644 index 0000000..4fc5c8d --- /dev/null +++ b/c/hash-table/isomorphic-strings.c @@ -0,0 +1,19 @@ +bool isIsomorphic(char* s, char* t) { + int flag[256] = {0}; + int visited[256] = {0}; + int len = strlen(s); + + for(int i = 0; i < len; ++i){ + if(flag[s[i]] == 0){ + if(visited[t[i]]) + return false; + + flag[s[i]] = t[i]; + visited[t[i]] = 1; + }else if(flag[s[i]] != t[i]){ + return false; + } + } + + return true; +} diff --git a/c/hash-table/isomorphic-strings[1].c b/c/hash-table/isomorphic-strings[1].c new file mode 100644 index 0000000..cd5aff3 --- /dev/null +++ b/c/hash-table/isomorphic-strings[1].c @@ -0,0 +1,16 @@ +bool isIsomorphic(char* s, char* t) { + int ms[256] = {0}; + int mt[256] = {0}; + + int len = strlen(s); + + for(int i = 0; i < len; ++i){ + if(ms[s[i]] != mt[t[i]]) + return false; + + ms[s[i]] = i + 1; + mt[t[i]] = i + 1; + } + + return true; +} diff --git a/c/hash-table/keyboard-row.c b/c/hash-table/keyboard-row.c new file mode 100644 index 0000000..5a5f047 --- /dev/null +++ b/c/hash-table/keyboard-row.c @@ -0,0 +1,34 @@ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +char** findWords(char** words, int wordsSize, int* returnSize) { + char **res; + char *word; + int count = 0; + int i,j,len; + char *line[3] = {"qwertyuiopQWERTYUIOP", "asdfghjklASDFGHJKL", + "zxcvbnmZXCVBNM"}; + int map[256] = {0}; + for(i = 0; i < 3; ++i){ + len = strlen(line[i]); + for(j = 0; j < len; ++j) + map[line[i][j]] = i; + } + res = malloc(sizeof(char *) * wordsSize); + + for(i = 0; i < wordsSize; ++i){ + word = words[i]; + len = strlen(word); + int f = map[word[0]]; + for(j = 0; j < len; ++j) + if(map[word[j]] != f) + break; + + if(j == len) + res[count++] = strdup(word); + } + + *returnSize = count; + return res; +} diff --git a/c/hash-table/longest-palindrome.c b/c/hash-table/longest-palindrome.c new file mode 100644 index 0000000..bfc3b11 --- /dev/null +++ b/c/hash-table/longest-palindrome.c @@ -0,0 +1,19 @@ +int longestPalindrome(char* s) { + int map[256] = {0}; + int i,len,ret = 0; + int plus = 0; + + len = strlen(s); + for(i = 0; i < len; ++i) + map[s[i]]++; + + for(i = 0; i < 256; ++i){ + ret += map[i]; + if(map[i] % 2 == 1){ + plus = 1; + ret--; + } + } + + return ret + plus; +} diff --git a/c/hash-table/longest-substring-without-repeating-characters.c b/c/hash-table/longest-substring-without-repeating-characters.c new file mode 100644 index 0000000..73fc26b --- /dev/null +++ b/c/hash-table/longest-substring-without-repeating-characters.c @@ -0,0 +1,14 @@ +int lengthOfLongestSubstring(char* s) { + int index[256] = {0}; + int last_index = -1; + int len = strlen(s); + int ret = 0; + + for(int i = 0; i < len; ++i){ + last_index = index[s[i]] > last_index ? index[s[i]] : last_index; + index[s[i]] = i + 1; + ret = (i - last_index + 1) > ret ? (i - last_index + 1) : ret; + } + + return ret; +} diff --git a/c/hash-table/maximal-rectangle.c b/c/hash-table/maximal-rectangle.c new file mode 100644 index 0000000..29cdc13 --- /dev/null +++ b/c/hash-table/maximal-rectangle.c @@ -0,0 +1,35 @@ +int maximalRectangle(char** matrix, int matrixRowSize, int matrixColSize) { + int max_area = 0; + int h,w; + int *height; + int *st; + int i,j; + int top; + + height = malloc(sizeof(int) * (matrixColSize + 1)); + st = malloc(sizeof(int) * (matrixColSize + 1)); + memset(height, 0, sizeof(int) * (matrixColSize + 1)); + + for(i = 0; i < matrixRowSize; ++i){ + top = -1; + for(j = 0; j <= matrixColSize; ++j){ + if(j < matrixColSize) + height[j] = matrix[i][j] == '1' ? height[j] + 1 : 0; + + while(top > -1 && height[j] <= height[st[top]]){ + h = height[st[top--]]; + w = ((top == -1) ? j : (j - st[top] - 1)); + + if(h * w > max_area) + max_area = h * w; + } + + st[++top] = j; + } + } + + free(height); + free(st); + + return max_area; +} diff --git a/c/hash-table/minimum-window-substring.c b/c/hash-table/minimum-window-substring.c new file mode 100644 index 0000000..c01b430 --- /dev/null +++ b/c/hash-table/minimum-window-substring.c @@ -0,0 +1,48 @@ +char* minWindow(char* s, char* t) { + int i, start = 0; + int s_len = strlen(s); + int t_len = strlen(t); + int min_index, min_window = s_len + 1; + int cur_match = 0; + char *ret = ""; + int t_map[256] = {0}; + int cur_map[256] = {0}; + + for(i = 0; i < t_len; ++i) + t_map[t[i]]++; + + for(i = 0; i < s_len; ++i){ + if(t_map[s[i]] == 0) + continue; + + cur_map[s[i]]++; + if(cur_map[s[i]] <= t_map[s[i]]) + cur_match++; + + if(cur_match != t_len) + continue; + + while(!t_map[s[start]] || + cur_map[s[start]] > t_map[s[start]]){ + if(t_map[s[start]]) + cur_map[s[start]]--; + start++; + } + + if(i - start + 1 < min_window){ + min_window = i - start + 1; + min_index = start; + } + cur_map[s[start]]--; + start++; + cur_match--; + } + + if(min_window != s_len + 1){ + ret = malloc(sizeof(char) * (min_window + 1)); + memcpy(ret, s + min_index, min_window); + ret[min_window] = 0; + } + + return ret; +} diff --git a/c/hash-table/number-of-boomerangs.c b/c/hash-table/number-of-boomerangs.c new file mode 100644 index 0000000..7ca7da3 --- /dev/null +++ b/c/hash-table/number-of-boomerangs.c @@ -0,0 +1,91 @@ +struct node { + int key; + int value; + struct node *left; + struct node *right; +}; + +struct node * node_add(struct node *head, int key) +{ + struct node *new_node, *cur; + new_node = malloc(sizeof(struct node)); + new_node->key = key; + new_node->value = 1; + new_node->left = NULL; + new_node->right = NULL; + if(head == NULL) + return new_node; + + cur = head; + while(cur){ + if(cur->key == key){ + free(new_node); + cur->value++; + break; + }else if(cur->key > key){ + if(cur->left == NULL){ + cur->left = new_node; + break; + } + cur = cur->left; + }else{ + if(cur->right == NULL){ + cur->right = new_node; + break; + } + cur = cur->right; + } + } + + return head; +} + +void node_free(struct node *head) +{ + if(head == NULL) + return ; + node_free(head->left); + node_free(head->right); + free(head); +} + +int get_value_by_key(struct node *head, int key) +{ + struct node *cur = head; + while(cur){ + if(cur->key == key) + break; + if(cur->key > key) + cur = cur->left; + else + cur = cur->right; + } + + return cur ? cur->value : 0; +} + +int dist(int x1, int y1, int x2, int y2) +{ + return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1); +} + +int numberOfBoomerangs(int** points, int pointsRowSize, int pointsColSize) { + int i,j; + struct node *head; + int ret = 0; + int key; + + for(i = 0; i < pointsRowSize; ++i){ + head = NULL; + for(j = 0; j < pointsRowSize; ++j){ + if(i == j) + continue; + key = dist(points[i][0], points[i][1], points[j][0], points[j][1]); + ret += (2 * get_value_by_key(head, key)); + head = node_add(head, key); + } + node_free(head); + } + + return ret; +} diff --git a/c/hash-table/single-number.c b/c/hash-table/single-number.c new file mode 100644 index 0000000..9595c1c --- /dev/null +++ b/c/hash-table/single-number.c @@ -0,0 +1,8 @@ +int singleNumber(int* nums, int numsSize) { + int ret = 0; + + for(int i = 0; i < numsSize; ++i) + ret ^= nums[i]; + + return ret; +} diff --git a/c/hash-table/two-sum.c b/c/hash-table/two-sum.c new file mode 100644 index 0000000..9c55477 --- /dev/null +++ b/c/hash-table/two-sum.c @@ -0,0 +1,16 @@ +/** + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* twoSum(int* nums, int numsSize, int target) { + int *ret = malloc(sizeof(int) * 2); + + for(int i = 0; i < numsSize; ++i) + for(int j = i + 1; j < numsSize; ++j) + if(nums[i] + nums[j] == target){ + ret[0] = i; + ret[1] = j; + return ret; + } + + return ret; +} diff --git a/c/hash-table/valid-anagram.c b/c/hash-table/valid-anagram.c new file mode 100644 index 0000000..a5cbbf4 --- /dev/null +++ b/c/hash-table/valid-anagram.c @@ -0,0 +1,19 @@ +bool isAnagram(char* s, char* t) { + int hash[26] = {0}; + int s_len = strlen(s); + int t_len = strlen(t); + int i; + if(s_len != t_len) + return false; + + for(i = 0; i < s_len; ++i){ + hash[s[i] - 'a']++; + hash[t[i] - 'a']--; + } + + for(i = 0; i < 26; ++i) + if(hash[i]) + return false; + + return true; +} diff --git a/c/hash-table/word-pattern.c b/c/hash-table/word-pattern.c new file mode 100644 index 0000000..c2af480 --- /dev/null +++ b/c/hash-table/word-pattern.c @@ -0,0 +1,38 @@ +int is_pattern(char *d[], char c, char *word) +{ + if(strcmp(d[c-'a'], word) != 0) + return false; + + for(int i = 0; i < 26; ++i) + if(d[i] && strcmp(d[i], word) == 0 && 'a' + i != c) + return false; + + return true; +} + +bool wordPattern(char* pattern, char* str) { + char *d[26]; + char *sep = " "; + char *word; + int i = 0; + char c; + int len = strlen(pattern); + memset(d, 0, sizeof(char *) * 26); + word = strtok(str, sep); + while(word != NULL){ + if(i >= len) + return false; + c = pattern[i++]; + if(d[c - 'a'] == NULL) + d[c - 'a'] = strdup(word); + + if(!is_pattern(d, c, word)) + return false; + word = strtok(NULL, sep); + } + + if(i != len) + return false; + + return true; +} diff --git a/c/linked-list/add-two-numbers.c b/c/linked-list/add-two-numbers.c new file mode 100644 index 0000000..c59b3cd --- /dev/null +++ b/c/linked-list/add-two-numbers.c @@ -0,0 +1,48 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode *get_node(int val) +{ + struct ListNode *ret = (struct ListNode *)malloc(sizeof(struct ListNode)); + ret->val = val; + ret->next = NULL; + + return ret; +} + +struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) { + struct ListNode root; + struct ListNode *cur = &root; + struct ListNode *l; + int carry = 0; + int sum; + + while(l1 && l2){ + sum = l1->val + l2->val + carry; + carry = sum / 10; + cur->next = get_node(sum % 10); + cur = cur->next; + + l1 = l1->next; + l2 = l2->next; + } + + l = l1 ? l1 : l2; + while(l){ + sum = carry + l->val; + carry = sum / 10; + cur->next = get_node(sum % 10); + cur = cur->next; + + l = l->next; + } + + if(carry) + cur->next = get_node(carry); + + return root.next; +} diff --git a/c/linked-list/convert-sorted-list-to-binary-search-tree.c b/c/linked-list/convert-sorted-list-to-binary-search-tree.c new file mode 100644 index 0000000..d573415 --- /dev/null +++ b/c/linked-list/convert-sorted-list-to-binary-search-tree.c @@ -0,0 +1,47 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +int get_size(struct ListNode *head) +{ + int size = 0; + while(head){ + head = head->next; + ++size; + } + + return size; +} + +struct TreeNode* bst_helper(struct ListNode **head, int size) +{ + if(size == 0) + return NULL; + + struct TreeNode *root = (struct TreeNode *)malloc(sizeof(struct TreeNode)); + root->left = bst_helper(head,size/2); + root->val = (*head)->val; + (*head) = (*head)->next; + root->right = bst_helper(head,size - size/2 - 1); + + return root; +} + +struct TreeNode* sortedListToBST(struct ListNode* head) { + int size = get_size(head); + if(head == NULL) + return NULL; + + return bst_helper(&head,size); +} diff --git a/c/linked-list/copy-list-with-random-pointer.c b/c/linked-list/copy-list-with-random-pointer.c new file mode 100644 index 0000000..df15ad8 --- /dev/null +++ b/c/linked-list/copy-list-with-random-pointer.c @@ -0,0 +1,61 @@ +/** + * Definition for singly-linked list with a random pointer. + * struct RandomListNode { + * int label; + * struct RandomListNode *next; + * struct RandomListNode *random; + * }; + */ +struct RandomListNode *get_node(int label) +{ + struct RandomListNode *ret; + + ret = malloc(sizeof(struct RandomListNode *)); + ret->label = label; + ret->next = NULL; + ret->random = NULL; +} + +void copyList(struct RandomListNode *head){ + struct RandomListNode *next_node; + while(head){ + struct RandomListNode *new_node = get_node(head->label); + next_node = head->next; + head->next = new_node; + new_node->next = next_node; + head = next_node; + } +} + +void copyRandom(struct RandomListNode *head){ + while(head){ + if(head->random){ + head->next->random = head->random->next; + } + head = head->next->next; + } +} + +struct RandomListNode *spiltList(struct RandomListNode *head) +{ + struct RandomListNode *next_node; + struct RandomListNode *new_node; + struct RandomListNode root; + + root.next = head ? head->next : NULL; + while(head){ + next_node = head->next->next; + new_node = head->next; + head->next = next_node; + new_node->next = next_node ? next_node->next : NULL; + head = next_node; + } + + return root.next; +} + +struct RandomListNode *copyRandomList(struct RandomListNode *head) { + copyList(head); + copyRandom(head); + return spiltList(head); +} diff --git a/c/linked-list/delete-node-in-a-linked-list.c b/c/linked-list/delete-node-in-a-linked-list.c new file mode 100644 index 0000000..ead0764 --- /dev/null +++ b/c/linked-list/delete-node-in-a-linked-list.c @@ -0,0 +1,11 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +void deleteNode(struct ListNode* node) { + node->val = node->next->val; + node->next = node->next->next; +} diff --git a/c/linked-list/insertion-sort-list.c b/c/linked-list/insertion-sort-list.c new file mode 100644 index 0000000..32e237c --- /dev/null +++ b/c/linked-list/insertion-sort-list.c @@ -0,0 +1,26 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode* insertionSortList(struct ListNode* head) { + struct ListNode root; + struct ListNode *cur; + struct ListNode *tmp; + + root.next = NULL; + while(head){ + cur = &root; + while(cur->next && cur->next->val < head->val) + cur = cur->next; + + tmp = head->next; + head->next = cur->next; + cur->next = head; + head = tmp; + } + + return root.next; +} diff --git a/c/linked-list/intersection-of-two-linked-lists.c b/c/linked-list/intersection-of-two-linked-lists.c new file mode 100644 index 0000000..8478c01 --- /dev/null +++ b/c/linked-list/intersection-of-two-linked-lists.c @@ -0,0 +1,41 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) { + int len_a = 0; + int len_b = 0; + int n; + struct ListNode *la = headA; + struct ListNode *lb = headB; + + while(la){ + len_a++; + la = la->next; + } + while(lb){ + len_b++; + lb = lb->next; + } + + la = (len_a > len_b) ? headA : headB; + lb = (la == headA) ? headB : headA; + + n = abs(len_a - len_b); + while(n){ + la = la->next; + n--; + } + + while(la && lb){ + if(la == lb) + return la; + la = la->next; + lb = lb->next; + } + + return NULL; +} diff --git a/c/linked-list/linked-list-cycle-ii.c b/c/linked-list/linked-list-cycle-ii.c new file mode 100644 index 0000000..2dbeae7 --- /dev/null +++ b/c/linked-list/linked-list-cycle-ii.c @@ -0,0 +1,26 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode *detectCycle(struct ListNode *head) { + struct ListNode *slow = head; + struct ListNode *fast = head; + + do { + if(!slow || !fast || !fast->next) + return NULL; + + slow = slow->next; + fast = fast->next->next; + }while(slow != fast); + + while(head != slow){ + head = head->next; + slow = slow->next; + } + + return head; +} diff --git a/c/linked-list/linked-list-cycle.c b/c/linked-list/linked-list-cycle.c new file mode 100644 index 0000000..c997256 --- /dev/null +++ b/c/linked-list/linked-list-cycle.c @@ -0,0 +1,26 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +bool hasCycle(struct ListNode *head) { + struct ListNode *one; + struct ListNode *two; + + one = head; + two = head; + + while(one && two){ + one = one->next; + two = two->next; + + if(two) + two = two->next; + if(one && one == two) + return true; + } + + return false; +} diff --git a/c/linked-list/merge-k-sorted-lists.c b/c/linked-list/merge-k-sorted-lists.c new file mode 100644 index 0000000..8db0ff0 --- /dev/null +++ b/c/linked-list/merge-k-sorted-lists.c @@ -0,0 +1,45 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ + +struct ListNode *merge(struct ListNode *left, struct ListNode *right) +{ + struct ListNode root; + struct ListNode *cur; + cur = &root; + + while(left && right){ + if(left->val < right->val){ + cur->next = left; + left = left->next; + }else{ + cur->next = right; + right = right->next; + } + cur = cur->next; + } + + cur->next = left ? left : right; + return root.next; +} + +struct ListNode* split(struct ListNode **lists, int start, int end) +{ + if(end < start) + return NULL; + if(start == end) + return lists[start]; + int mid = (start + end) / 2; + struct ListNode *left = split(lists,start,mid); + struct ListNode *right = split(lists,mid+1,end); + + return merge(left,right); +} + +struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) { + return split(lists,0,listsSize-1); +} diff --git a/c/linked-list/merge-two-sorted-lists.c b/c/linked-list/merge-two-sorted-lists.c new file mode 100644 index 0000000..4d006b7 --- /dev/null +++ b/c/linked-list/merge-two-sorted-lists.c @@ -0,0 +1,26 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) { + struct ListNode root; + struct ListNode *cur = &root; + + while(l1 && l2){ + if(l1->val < l2->val){ + cur->next = l1; + l1 = l1->next; + }else{ + cur->next = l2; + l2 = l2->next; + } + cur = cur->next; + } + + cur->next = l1 ? l1 : l2; + + return root.next; +} diff --git a/c/linked-list/palindrome-linked-list.c b/c/linked-list/palindrome-linked-list.c new file mode 100644 index 0000000..c8e85f5 --- /dev/null +++ b/c/linked-list/palindrome-linked-list.c @@ -0,0 +1,48 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +int get_length(struct ListNode *head) +{ + int ret = 0; + while(head){ + head = head->next; + ret++; + } + return ret; +} + +bool isPalindrome(struct ListNode* head) { + int len; + int i; + struct ListNode root; + struct ListNode *left; + struct ListNode *tmp; + + root.next = NULL; + left = head; + len = get_length(head); + + for(i = 0; i < (len+1) / 2; i++) + head = head->next; + + while(head){ + tmp = head->next; + head->next = root.next; + root.next = head; + head = tmp; + } + + tmp = root.next; + while(tmp){ + if(tmp->val != left->val) + return false; + tmp = tmp->next; + left = left->next; + } + + return true; +} diff --git a/c/linked-list/palindrome-linked-list[2].c b/c/linked-list/palindrome-linked-list[2].c new file mode 100644 index 0000000..b2ddedc --- /dev/null +++ b/c/linked-list/palindrome-linked-list[2].c @@ -0,0 +1,25 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode *glist; +bool helper(struct ListNode *head) +{ + if(head == NULL) + return true; + if(!helper(head->next)) + return false; + if(head->val != glist->val) + return false; + + glist = glist->next; + return true; +} + +bool isPalindrome(struct ListNode* head) { + glist = head; + return helper(head); +} diff --git a/c/linked-list/partition-list.c b/c/linked-list/partition-list.c new file mode 100644 index 0000000..9121cec --- /dev/null +++ b/c/linked-list/partition-list.c @@ -0,0 +1,31 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode* partition(struct ListNode* head, int x) { + struct ListNode left; + struct ListNode right; + struct ListNode *lit; + struct ListNode *rit; + + lit = &left; + rit = &right; + while(head){ + if(head->val < x){ + lit->next = head; + lit = lit->next; + }else{ + rit->next = head; + rit = rit->next; + } + head = head->next; + } + + rit->next = NULL; + lit->next = right.next; + + return left.next; +} diff --git a/c/linked-list/remove-duplicates-from-sorted-list-ii.c b/c/linked-list/remove-duplicates-from-sorted-list-ii.c new file mode 100644 index 0000000..8fa6720 --- /dev/null +++ b/c/linked-list/remove-duplicates-from-sorted-list-ii.c @@ -0,0 +1,35 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode* deleteDuplicates(struct ListNode* head) { + struct ListNode root; + struct ListNode *cur; + int count; + int val; + + cur = &root; + while(head){ + count = 1; + val = head->val; + while(head->next && head->next->val == val){ + head = head->next; + count++; + } + + if(count > 1) + goto next_loop; + + cur->next = head; + cur = cur->next; + +next_loop: + head = head->next; + } + + cur->next = NULL; + return root.next; +} diff --git a/c/linked-list/remove-duplicates-from-sorted-list.c b/c/linked-list/remove-duplicates-from-sorted-list.c new file mode 100644 index 0000000..fb83a14 --- /dev/null +++ b/c/linked-list/remove-duplicates-from-sorted-list.c @@ -0,0 +1,23 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode* deleteDuplicates(struct ListNode* head) { + struct ListNode *ret; + struct ListNode *prev; + ret = head; + + while(head && head->next){ + prev = head; + head = head->next; + if(prev->val == head->val){ + prev->next = head->next; + head = prev; + } + } + + return ret; +} diff --git a/c/linked-list/remove-linked-list-elements.c b/c/linked-list/remove-linked-list-elements.c new file mode 100644 index 0000000..c7aceb3 --- /dev/null +++ b/c/linked-list/remove-linked-list-elements.c @@ -0,0 +1,22 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode* removeElements(struct ListNode* head, int val) { + struct ListNode root; + struct ListNode *cur; + + root.next = head; + cur = &root; + while(cur->next){ + if(cur->next->val == val) + cur->next = cur->next->next; + else + cur = cur->next; + } + + return root.next; +} diff --git a/c/linked-list/remove-nth-node-from-end-of-list.c b/c/linked-list/remove-nth-node-from-end-of-list.c new file mode 100644 index 0000000..bd6ab95 --- /dev/null +++ b/c/linked-list/remove-nth-node-from-end-of-list.c @@ -0,0 +1,27 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode* removeNthFromEnd(struct ListNode* head, int n) { + struct ListNode *prev; + struct ListNode root; + int i; + + root.next = head; + prev = &root; + + for(i = 0; i < n; ++i) + head = head->next; + + while(head){ + head = head->next; + prev = prev->next; + } + + prev->next = prev->next->next; + + return root.next; +} diff --git a/c/linked-list/reorder-list.c b/c/linked-list/reorder-list.c new file mode 100644 index 0000000..672c498 --- /dev/null +++ b/c/linked-list/reorder-list.c @@ -0,0 +1,81 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +int get_length(struct ListNode *head) +{ + int ret = 0; + while(head){ + ret++; + head = head->next; + } + + return ret; +} + +struct ListNode* reverse(struct ListNode *head) +{ + struct ListNode root; + root.next = NULL; + while(head){ + struct ListNode *tmp = head->next; + head->next = root.next; + root.next = head; + head = tmp; + } + + return root.next; +} + +struct ListNode* merge(struct ListNode *h1, struct ListNode *h2) +{ + int index = 0; + struct ListNode root; + struct ListNode *cur; + cur = &root; + while(h1 && h2){ + if(index % 2 == 0){ + cur->next = h1; + h1 = h1->next; + }else{ + cur->next = h2; + h2 = h2->next; + } + cur = cur->next; + index++; + } + + if(h1){ + cur->next = h1; + }else{ + cur->next = h2; + } + + return root.next; +} + +void reorderList(struct ListNode* head) { + int len,i; + struct ListNode *cur; + struct ListNode *tail; + struct ListNode *tmp; + + if(head == NULL || head->next == NULL) + return ; + + tmp = NULL; + cur = head; + + len = get_length(head); + for(i = 0; i < (len+1)/2; ++i){ + tmp = cur; + cur = cur->next; + } + tmp->next = NULL; + tail = reverse(cur); + + merge(head,tail); +} diff --git a/c/linked-list/reorder-list[2].c b/c/linked-list/reorder-list[2].c new file mode 100644 index 0000000..8aed30f --- /dev/null +++ b/c/linked-list/reorder-list[2].c @@ -0,0 +1,74 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode *get_mid(struct ListNode *head) +{ + struct ListNode *slow,*fast; + slow = head; + fast = head->next; + while(fast != NULL && fast->next != NULL){ + slow = slow->next; + fast = fast->next->next; + } + + return slow; +} + +struct ListNode* reverse(struct ListNode *head) +{ + struct ListNode root; + root.next = NULL; + while(head){ + struct ListNode *tmp = head->next; + head->next = root.next; + root.next = head; + head = tmp; + } + + return root.next; +} + +struct ListNode* merge(struct ListNode *h1, struct ListNode *h2) +{ + int index = 0; + struct ListNode root; + struct ListNode *cur; + cur = &root; + while(h1 && h2){ + if(index % 2 == 0){ + cur->next = h1; + h1 = h1->next; + }else{ + cur->next = h2; + h2 = h2->next; + } + cur = cur->next; + index++; + } + + if(h1){ + cur->next = h1; + }else{ + cur->next = h2; + } + + return root.next; +} + +void reorderList(struct ListNode* head) { + struct ListNode *tail; + struct ListNode *mid; + + if(head == NULL || head->next == NULL) + return ; + + mid = get_mid(head); + tail = reverse(mid->next); + mid->next = NULL; + + merge(head,tail); +} diff --git a/c/linked-list/reverse-linked-list-ii.c b/c/linked-list/reverse-linked-list-ii.c new file mode 100644 index 0000000..e101247 --- /dev/null +++ b/c/linked-list/reverse-linked-list-ii.c @@ -0,0 +1,37 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode* reverseBetween(struct ListNode* head, int m, int n) { + struct ListNode root; + struct ListNode *cur; + struct ListNode *tmp; + struct ListNode *tail; + int i = 1; + + root.next = head; + cur = &root; + + while(i < m){ + i++; + cur = cur->next; + } + + head = cur->next; + tail = head; + cur->next = NULL; + while(i <= n){ + i++; + tmp = head->next; + head->next = cur->next; + cur->next = head; + head = tmp; + } + + tail->next = head; + + return root.next; +} diff --git a/c/linked-list/reverse-linked-list.c b/c/linked-list/reverse-linked-list.c new file mode 100644 index 0000000..6a8d001 --- /dev/null +++ b/c/linked-list/reverse-linked-list.c @@ -0,0 +1,21 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode* reverseList(struct ListNode* head) { + struct ListNode root; + struct ListNode *tmp; + root.next = NULL; + + while(head){ + tmp = head->next; + head->next = root.next; + root.next = head; + head = tmp; + } + + return root.next; +} diff --git a/c/linked-list/reverse-nodes-in-k-group.c b/c/linked-list/reverse-nodes-in-k-group.c new file mode 100644 index 0000000..7fdadb3 --- /dev/null +++ b/c/linked-list/reverse-nodes-in-k-group.c @@ -0,0 +1,51 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode *reverseNode(struct ListNode *head) +{ + struct ListNode root; + root.next = NULL; + while(head){ + struct ListNode *tmp = head->next; + head->next = root.next; + root.next = head; + head = tmp; + } + + return root.next; +} + +struct ListNode* reverseKGroup(struct ListNode* head, int k) { + struct ListNode *begin; + struct ListNode *tail; + struct ListNode root; + struct ListNode *prev; + int i; + + root.next = head; + prev = &root; + while(head){ + i = 1; + begin = head; + while(head && i < k){ + head = head->next; + i++; + } + + if(head == NULL) + goto out; + tail = head->next; + head->next = NULL; + prev->next = reverseNode(begin); + prev = begin; + prev->next = tail; + head = prev->next; + } + +out: + return root.next; +} diff --git a/c/linked-list/rotate-list.c b/c/linked-list/rotate-list.c new file mode 100644 index 0000000..ed019e6 --- /dev/null +++ b/c/linked-list/rotate-list.c @@ -0,0 +1,39 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode* rotateRight(struct ListNode* head, int k) { + struct ListNode root; + struct ListNode *prev; + struct ListNode *tail; + int i; + int count; + + if(head == NULL) + return NULL; + + root.next = head; + prev = &root; + + count = 0; + while(head){ + tail = head; + head = head->next; + count++; + } + head = root.next; + k %= count; + + for(i = 0; i < count-k; ++i){ + prev = prev->next; + } + + tail->next = root.next; + root.next = prev->next; + prev->next = NULL; + + return root.next; +} diff --git a/c/linked-list/rotate-list[2].c b/c/linked-list/rotate-list[2].c new file mode 100644 index 0000000..9351a7c --- /dev/null +++ b/c/linked-list/rotate-list[2].c @@ -0,0 +1,47 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +int get_length(struct ListNode *head) +{ + int ret = 0; + while(head){ + ret++; + head = head->next; + } + + return ret; +} + +struct ListNode* rotateRight(struct ListNode* head, int k) { + int len; + int i; + struct ListNode root; + struct ListNode *prev; + + if(head == NULL) + return NULL; + + root.next = head; + prev = root.next; + + len = get_length(head); + k %= len; + + for(i = 0; i < k; ++i) + head = head->next; + + while(head->next){ + head = head->next; + prev = prev->next; + } + + head->next = root.next; + root.next = prev->next; + prev->next = NULL; + + return root.next; +} diff --git a/c/linked-list/sort-list.c b/c/linked-list/sort-list.c new file mode 100644 index 0000000..c41ffdb --- /dev/null +++ b/c/linked-list/sort-list.c @@ -0,0 +1,47 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode *merge(struct ListNode *left, struct ListNode *right) +{ + struct ListNode root; + struct ListNode *cur = &root; + while(left && right){ + if(left->val < right->val){ + cur->next = left; + left = left->next; + }else{ + cur->next = right; + right = right->next; + } + cur = cur->next; + } + cur->next = left ? left : right; + return root.next; +} + +struct ListNode *split(struct ListNode *head) +{ + if(head == NULL || head->next == NULL) + return head; + + struct ListNode *slow = head; + struct ListNode *fast = head->next; + while(fast && fast->next){ + fast = fast->next->next; + slow = slow->next; + } + + struct ListNode *right = split(slow->next); + slow->next = NULL; + struct ListNode *left = split(head); + + return merge(left,right); +} + +struct ListNode* sortList(struct ListNode* head) { + return split(head); +} diff --git a/c/linked-list/swap-nodes-in-pairs.c b/c/linked-list/swap-nodes-in-pairs.c new file mode 100644 index 0000000..63966d7 --- /dev/null +++ b/c/linked-list/swap-nodes-in-pairs.c @@ -0,0 +1,26 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode* swapPairs(struct ListNode* head) { + struct ListNode root; + struct ListNode *cur; + + root.next = head; + cur = &root; + while(head && head->next){ + struct ListNode *tmp = head->next->next; + + cur->next = head->next; + head->next->next = head; + head->next = tmp; + + cur = head; + head = head->next; + } + + return root.next; +} diff --git a/c/math/add-binary.c b/c/math/add-binary.c new file mode 100644 index 0000000..1f7e7ac --- /dev/null +++ b/c/math/add-binary.c @@ -0,0 +1,38 @@ +char* addBinary(char* a, char* b) { + char *ret; + int len_a = strlen(a); + int len_b = strlen(b); + int max_len = (len_a > len_b ? len_a : len_b) + 2; + int i,carry; + int ai,bi; + int value; + + ret = (char *)malloc(sizeof(char) * max_len); + memset(ret,0,sizeof(char) * max_len); + carry = 0; + ai = len_a - 1; + bi = len_b - 1; + i = max_len - 2; + while(ai >= 0 && bi >= 0){ + value = (a[ai--] - '0') + (b[bi--] - '0') + carry; + carry = value / 2; + value %= 2; + ret[i--] = '0' + value; + } + + if(bi >= 0){ + ai = bi; + a = b; + } + + while(ai >= 0){ + value = (a[ai--] - '0') + carry; + carry = value / 2; + value %= 2; + ret[i--] = '0' + value; + } + + if(carry) + ret[i--] = '1'; + return ret+i+1; +} diff --git a/c/math/add-digits.c b/c/math/add-digits.c new file mode 100644 index 0000000..5b4b775 --- /dev/null +++ b/c/math/add-digits.c @@ -0,0 +1,13 @@ +int addDigits(int num) { + int ret = num; + while(num > 9){ + ret = 0; + while(num){ + ret += (num % 10); + num /= 10; + } + num = ret; + } + + return ret; +} diff --git a/c/math/add-digits[1].c b/c/math/add-digits[1].c new file mode 100644 index 0000000..7cbdd31 --- /dev/null +++ b/c/math/add-digits[1].c @@ -0,0 +1,3 @@ +int addDigits(int num) { + return 1 + (num - 1) % 9; +} diff --git a/c/math/add-two-numbers.c b/c/math/add-two-numbers.c new file mode 100644 index 0000000..b82cdbb --- /dev/null +++ b/c/math/add-two-numbers.c @@ -0,0 +1,51 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode* get_node(int val) +{ + struct ListNode *ret = (struct ListNode *)malloc(sizeof(struct ListNode)); + ret->val = val; + ret->next = NULL; + return ret; +} + +struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) { + int carry; + int val; + struct ListNode root; + struct ListNode *cursor; + + carry = 0; + cursor = &root; + while(l1 && l2){ + val = l1->val + l2->val + carry; + carry = val / 10; + val %= 10; + cursor->next = get_node(val); + cursor = cursor->next; + l1 = l1->next; + l2 = l2->next; + } + + if(l2) + l1 = l2; + + while(l1){ + val = l1->val + carry; + carry = val / 10; + val %= 10; + cursor->next = get_node(val); + cursor = cursor->next; + + l1 = l1->next; + } + + if(carry) + cursor->next = get_node(carry); + + return root.next; +} diff --git a/c/math/basic-calculator.c b/c/math/basic-calculator.c new file mode 100644 index 0000000..a964ce8 --- /dev/null +++ b/c/math/basic-calculator.c @@ -0,0 +1,51 @@ +#define NUM 1000 + +int calculate(char* s) { + char op[NUM]; + int val[NUM]; + int top_op,top_val; + int value = 0; + + top_op = top_val = -1; + while(*s){ + if(*s == ' '){ + ++s; + continue; + } + + if(*s == '+' || *s == '-' || *s == '('){ + op[++top_op] = *s; + ++s; + continue; + } + + if(*s == ')'){ + top_op--; + value = val[top_val--]; + s++; + }else{ + value = 0; + while(isdigit(*s)){ + value = value * 10 + (*s - '0'); + s++; + } + } + + if(top_op > -1 && op[top_op] != '('){ + switch(op[top_op]){ + case '+': + value = val[top_val] + value; + break; + case '-': + value = val[top_val] - value; + break; + } + top_op--; + top_val--; + } + + val[++top_val] = value; + } + + return val[top_val]; +} diff --git a/c/math/basic-calculator[1].c b/c/math/basic-calculator[1].c new file mode 100644 index 0000000..59f9283 --- /dev/null +++ b/c/math/basic-calculator[1].c @@ -0,0 +1,37 @@ +int calculate(char* s) { + int stack[1000]; + int value; + int top = -1; + int ret = 0; + int type = 1; + + while(*s){ + if(isdigit(*s)){ + value = 0; + while(isdigit(*s)){ + value = value * 10 + *s - '0'; + s++; + } + + ret += (type * value); + } + + if(*s == '+'){ + type = 1; + }else if(*s == '-'){ + type = -1; + }else if(*s == '('){ + stack[++top] = ret; + stack[++top] = type; + ret = 0; + type = 1; + }else if(*s == ')'){ + type = stack[top--]; + ret = stack[top--] + type * ret; + } + + s++; + } + + return ret; +} diff --git a/c/math/count-primes.c b/c/math/count-primes.c new file mode 100644 index 0000000..ce32fc2 --- /dev/null +++ b/c/math/count-primes.c @@ -0,0 +1,18 @@ +int countPrimes(int n) { + int ret = 0; + int i,j; + int *prime; + prime = (int *)malloc(sizeof(int) * n); + memset(prime,0,sizeof(int) * n); + + for(i = 2; i < n; ++i){ + if(prime[i]) + continue; + ret++; + for(j = 2*i; j < n; j += i) + prime[j] = 1; + } + + free(prime); + return ret; +} diff --git a/c/math/divide-two-integers.c b/c/math/divide-two-integers.c new file mode 100644 index 0000000..4c2a5e6 --- /dev/null +++ b/c/math/divide-two-integers.c @@ -0,0 +1,19 @@ +iint divide(int dividend, int divisor) { + if(dividend == INT_MIN && divisor == -1) + return INT_MAX; + + long a = labs(dividend); + long b = labs(divisor); + bool is_neg = ((dividend > 0 && divisor < 0) + || (dividend < 0 && divisor > 0)); + int ret = 0; + while(a >= b){ + int tmp = 0; + while(a >= (b << tmp)) + tmp++; + a -= (b << (tmp - 1)); + ret += (1 << (tmp - 1)); + } + + return is_neg ? -ret : ret; +} diff --git a/c/math/excel-sheet-column-number.c b/c/math/excel-sheet-column-number.c new file mode 100644 index 0000000..62b04ac --- /dev/null +++ b/c/math/excel-sheet-column-number.c @@ -0,0 +1,8 @@ +int titleToNumber(char* s) { + int ret = 0; + while(*s){ + ret = ret * 26 + (*s - 'A' + 1); + s++; + } + return ret; +} diff --git a/c/math/excel-sheet-column-title.c b/c/math/excel-sheet-column-title.c new file mode 100644 index 0000000..63b4c98 --- /dev/null +++ b/c/math/excel-sheet-column-title.c @@ -0,0 +1,14 @@ +char* convertToTitle(int n) { + char *ret; + int i; + + ret = (char *)malloc(sizeof(char) * 26); + memset(ret,0,sizeof(char) * 26); + i = 24; + while(n){ + ret[i--] = (n-1) % 26 + 'A'; + n = (n-1) / 26; + } + + return ret + i + 1; +} diff --git a/c/math/factorial-trailing-zeroes.c b/c/math/factorial-trailing-zeroes.c new file mode 100644 index 0000000..b7cfb1a --- /dev/null +++ b/c/math/factorial-trailing-zeroes.c @@ -0,0 +1,9 @@ +int trailingZeroes(int n) { + int ret = 0; + while(n){ + ret += n/5; + n /= 5; + } + + return ret; +} diff --git a/c/math/happy-number.c b/c/math/happy-number.c new file mode 100644 index 0000000..ae4c50a --- /dev/null +++ b/c/math/happy-number.c @@ -0,0 +1,24 @@ +bool isHappy(int n) { + int flag[100]; + int result; + + memset(flag,0,sizeof(int) * 100); + + while(n){ + if(n == 1) + return true; + if(n < 100 && !flag[n]) + flag[n] = 1; + else if(n < 100 && flag[n]) + break; + result = 0; + while(n){ + result += (n % 10) * (n % 10); + n /= 10; + } + + n = result; + } + + return false; +} diff --git a/c/math/integer-to-roman.c b/c/math/integer-to-roman.c new file mode 100644 index 0000000..080b152 --- /dev/null +++ b/c/math/integer-to-roman.c @@ -0,0 +1,33 @@ +char* intToRoman(int num) { + char symbols[][3] = { + "M", "CM", "D", "CD", + "C", "XC", "L", "XL", + "X", "IX", "V", "IV", + "I", + }; + + int values[] = { + 1000, 900, 500, 400, + 100, 90, 50, 40, + 10, 9, 5, 4, + 1, + }; + + char *ret; + int i,j; + + i = 0; + ret = (char *)malloc(sizeof(char) * 32); + memset(ret,0,sizeof(char) * 32); + + while(num > 0){ + int k = num / values[i]; + for(j = 0; j < k; ++j) + strcat(ret,symbols[i]); + + num -= k* values[i]; + i++; + } + + return ret; +} diff --git a/c/math/missing-number.c b/c/math/missing-number.c new file mode 100644 index 0000000..ac35b1c --- /dev/null +++ b/c/math/missing-number.c @@ -0,0 +1,20 @@ +int missingNumber(int* nums, int numsSize) { + int *arr; + int i; + int ret; + + arr = (int *)malloc(sizeof(int) * (numsSize + 1)); + memset(arr,0,sizeof(int) * (numsSize+1)); + + for(i = 0; i < numsSize; ++i) + arr[nums[i]] = 1; + + for(i = 0; i <= numsSize; ++i) + if(arr[i] == 0){ + ret = i; + break; + } + + free(arr); + return ret; +} diff --git a/c/math/missing-number[1].c b/c/math/missing-number[1].c new file mode 100644 index 0000000..e401710 --- /dev/null +++ b/c/math/missing-number[1].c @@ -0,0 +1,10 @@ +int missingNumber(int* nums, int numsSize) { + int i; + int sum; + + sum = numsSize * (1 + numsSize) / 2; + for(i = 0; i < numsSize; ++i) + sum -= nums[i]; + + return sum; +} diff --git a/c/math/number-of-digit-one.c b/c/math/number-of-digit-one.c new file mode 100644 index 0000000..83aaf45 --- /dev/null +++ b/c/math/number-of-digit-one.c @@ -0,0 +1,14 @@ +int countDigitOne(int n) { + int ret = 0; + long m; + + for(m = 1; m <= n; m *= 10){ + long a = n / m; + long b = n % m; + ret += (a + 8) / 10 * m; + if(a % 10 == 1) + ret += (b + 1); + } + + return ret; +} diff --git a/c/math/palindrome-number.c b/c/math/palindrome-number.c new file mode 100644 index 0000000..a855077 --- /dev/null +++ b/c/math/palindrome-number.c @@ -0,0 +1,13 @@ +bool isPalindrome(int x) { + if(x < 0) + return false; + + int rx = 0; + int tmp = x; + while(tmp){ + rx = 10 * rx + (tmp % 10); + tmp /= 10; + } + + return rx == x; +} diff --git a/c/math/perfect-squares.c b/c/math/perfect-squares.c new file mode 100644 index 0000000..36d5226 --- /dev/null +++ b/c/math/perfect-squares.c @@ -0,0 +1,35 @@ +void get_square(int *arr, int k) +{ + int i; + int min; + int x; + + if(arr[k]) + return ; + + min = k; + for(i = 1; i*i < k; ++i){ + x = i * i; + if(arr[k-x] == 0) + get_square(arr,k-x); + min = 1 + arr[k-x] < min ? 1 + arr[k-x] : min; + } + + arr[k] = min; +} + +int numSquares(int n) { + int *arr; + int i,ret; + + arr = (int *)malloc(sizeof(int) * (n+1)); + memset(arr,0,sizeof(int) * (n+1)); + for(i = 1; i * i <= n; ++i) + arr[i*i] = 1; + + get_square(arr, n); + ret = arr[n]; + + free(arr); + return ret; +} diff --git a/c/math/perfect-squares[1].c b/c/math/perfect-squares[1].c new file mode 100644 index 0000000..a66e6b4 --- /dev/null +++ b/c/math/perfect-squares[1].c @@ -0,0 +1,23 @@ +int numSquares(int n) { + int *arr; + int i,j; + int min,ret; + + arr = (int *)malloc(sizeof(int) * (n + 1)); + arr[0] = 0; + arr[1] = 1; + + for(i = 2; i <= n; ++i){ + min = i; + j = 1; + while(j * j <= i){ + min = arr[i - j * j] + 1 < min ? arr[i - j * j] + 1 : min; + j++; + } + arr[i] = min; + } + + ret = arr[n]; + free(arr); + return ret; +} diff --git a/c/math/plus-one.c b/c/math/plus-one.c new file mode 100644 index 0000000..d58a6e9 --- /dev/null +++ b/c/math/plus-one.c @@ -0,0 +1,25 @@ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* plusOne(int* digits, int digitsSize, int* returnSize) { + int carry = 1; + int *ret; + int count; + int i; + + count = digitsSize + 1; + ret = (int *)malloc(sizeof(int) * count); + + for(i = digitsSize - 1; i >= 0; --i){ + ret[--count] = (digits[i] + carry) % 10; + carry = (digits[i] + carry) / 10; + } + + if(carry) + ret[--count] = 1; + + *returnSize = digitsSize + 1 - count; + + return ret + count; +} diff --git a/c/math/power-of-two.c b/c/math/power-of-two.c new file mode 100644 index 0000000..b21fff9 --- /dev/null +++ b/c/math/power-of-two.c @@ -0,0 +1,9 @@ +bool isPowerOfTwo(int n) { + int ret = 0; + while(n > 0){ + ret += n & 0x1; + n >>= 1; + } + + return ret == 1; +} diff --git a/c/math/power-of-two[1].c b/c/math/power-of-two[1].c new file mode 100644 index 0000000..83db405 --- /dev/null +++ b/c/math/power-of-two[1].c @@ -0,0 +1,3 @@ +bool isPowerOfTwo(int n) { + return n > 0 && ((n & (n - 1)) == 0); +} diff --git a/c/math/powx-n.c b/c/math/powx-n.c new file mode 100644 index 0000000..4c691da --- /dev/null +++ b/c/math/powx-n.c @@ -0,0 +1,19 @@ +double myPow(double x, int n) { + if(n == 0) + return 1; + if(n == 1) + return x; + + int is_neg = 0; + if(n < 0){ + n = -n; + is_neg = 1; + } + + double df = myPow(x,n/2); + df *= df; + if(n % 2 == 1) + df *= x; + + return is_neg ? 1 / df : df; +} diff --git a/c/math/reverse-integer.c b/c/math/reverse-integer.c new file mode 100644 index 0000000..e53a4e5 --- /dev/null +++ b/c/math/reverse-integer.c @@ -0,0 +1,15 @@ +int reverse(int x) { + int rx = 0; + int ret = 0; + while(x){ + ret = rx * 10 + x % 10; + if(ret / 10 != rx){ + ret = 0; + break; + } + rx = ret; + x /= 10; + } + + return ret; +} diff --git a/c/math/sqrtx.c b/c/math/sqrtx.c new file mode 100644 index 0000000..33c9118 --- /dev/null +++ b/c/math/sqrtx.c @@ -0,0 +1,18 @@ +int mySqrt(int x) { + long start,end,mid; + start = 0; + end = x; + mid = 0; + + while(start <= end){ + mid = (start + end) / 2; + if(mid * mid == x || (mid * mid < x && (mid + 1) * (mid + 1) > x)) + break; + if(mid * mid < x) + start = mid+1; + else + end = mid-1; + } + + return mid; +} diff --git a/c/math/string-to-integer-atoi.c b/c/math/string-to-integer-atoi.c new file mode 100644 index 0000000..4935518 --- /dev/null +++ b/c/math/string-to-integer-atoi.c @@ -0,0 +1,24 @@ +int myAtoi(char* str) { + int ret = 0; + int tmp = 0; + int is_neg = 1; + + while(*str && *str == ' ') + str++; + + if(*str == '-') + is_neg = -1; + + if(*str == '+' || *str == '-') + str++; + + while(*str >= '0' && *str <= '9'){ + tmp = ret * 10 + (*str - '0'); + str++; + if(tmp / 10 != ret) + return is_neg == -1 ? INT_MIN : INT_MAX; + ret = tmp; + } + + return is_neg * ret; +} diff --git a/c/math/ugly-number-ii.c b/c/math/ugly-number-ii.c new file mode 100644 index 0000000..e2f2a4c --- /dev/null +++ b/c/math/ugly-number-ii.c @@ -0,0 +1,30 @@ +int min_3(int a, int b, int c) +{ + int m = a < b ? a : b; + return m < c ? m : c; +} + +int nthUglyNumber(int n) { + int *arr; + int t2,t3,t5; + int c; + + arr = (int *)malloc(sizeof(int) * n); + t2 = t3 = t5 = 0; + arr[0] = 1; + c = 1; + + while(c < n){ + int m = min_3(arr[t2] * 2, arr[t3] * 3, arr[t5] * 5); + arr[c++] = m; + + if(arr[t2] * 2 == m) + t2++; + if(arr[t3] * 3 == m) + t3++; + if(arr[t5] * 5 == m) + t5++; + } + + return arr[n-1]; +} diff --git a/c/math/ugly-number.c b/c/math/ugly-number.c new file mode 100644 index 0000000..5a2c78d --- /dev/null +++ b/c/math/ugly-number.c @@ -0,0 +1,15 @@ +bool isUgly(int num) { + if(num == 0) + return false; + + while(num % 5 == 0) + num /= 5; + + while(num % 3 == 0) + num /= 3; + + while(num % 2 == 0) + num /= 2; + + return num == 1; +} diff --git a/c/math/valid-number.c b/c/math/valid-number.c new file mode 100644 index 0000000..dbec37b --- /dev/null +++ b/c/math/valid-number.c @@ -0,0 +1,48 @@ +bool isNumber(char* s) { + int len; + int i,e; + bool num = false; + bool exp = false; + bool dot = false; + i = 0; + len = strlen(s); + e = len - 1; + + while(i <= e && s[i] == ' ') + i++; + + if(i > len - 1) + return false; + + while(e >= i && s[e] == ' ') + e--; + + if(s[i] == '+' || s[i] == '-') + i++; + + while(i <= e){ + char c = s[i]; + + if(isdigit(c)){ + num = true; + }else if(c == '.'){ + if(exp || dot) + return false; + dot = true; + }else if(c == 'e'){ + if(exp || !num) + return false; + num = false; + exp = true; + }else if(c == '+' || c == '-'){ + if(s[i-1] != 'e') + return false; + }else{ + return false; + } + + i++; + } + + return num; +} diff --git a/c/stack/basic-calculator.c b/c/stack/basic-calculator.c new file mode 100644 index 0000000..6440a94 --- /dev/null +++ b/c/stack/basic-calculator.c @@ -0,0 +1,85 @@ +int get_value(int left, int right, int op) +{ + if(op == '-') + return left - right; + else if(op == '+') + return left + right; + + return 0; +} + +int calculate(char* s) { + int *op_st; + int *val_st; + int op_top; + int val_top; + int left,right; + int len; + int tmp; + int op; + + len = strlen(s); + + op_st = malloc(sizeof(int) * len); + val_st = malloc(sizeof(int) * len); + op_top = val_top = -1; + + while(*s){ + if(*s == ' '){ + s++; + continue; + } + + if(isdigit(*s)){ + tmp = 0; + while(isdigit(*s)){ + tmp = 10 * tmp + *s - '0'; + s++; + } + val_st[++val_top] = tmp; + continue; + } + + switch(*s){ + case '+': + case '-': + if(op_top > -1 && (op_st[op_top] == '+' || + op_st[op_top] == '-')){ + right = val_st[val_top--]; + left = val_st[val_top--]; + tmp = get_value(left, right, op_st[op_top--]); + val_st[++val_top] = tmp; + } + + op_st[++op_top] = *s; + break; + case '(': + op_st[++op_top] = *s; + break; + case ')': + while(op_top > -1 && ((op = op_st[op_top--]) != '(')){ + right = val_st[val_top--]; + left = val_st[val_top--]; + tmp = get_value(left, right, op); + val_st[++val_top] = tmp; + } + break; + default: + break; + } + s++; + } + + while(op_top > -1){ + right = val_st[val_top--]; + left = val_st[val_top--]; + tmp = get_value(left, right, op_st[op_top--]); + val_st[++val_top] = tmp; + } + + tmp = val_st[val_top]; + free(op_st); + free(val_st); + + return tmp; +} diff --git a/c/stack/basic-calculator[2].c b/c/stack/basic-calculator[2].c new file mode 100644 index 0000000..1799d5a --- /dev/null +++ b/c/stack/basic-calculator[2].c @@ -0,0 +1,38 @@ +int calculate(char* s) { + int st[1000]; + int top = -1; + int result = 0; + int type = 1; + int value; + + while(*s){ + if(isdigit(*s)){ + value = 0; + while(isdigit(*s)){ + value = value * 10 + *s - '0'; + s++; + } + + result += (type * value); + } + + if(*s == '+'){ + type = 1; + }else if(*s == '-'){ + type = -1; + }else if(*s == '('){ + st[++top] = result; + st[++top] = type; + result = 0; + type = 1; + }else if(*s == ')'){ + type = st[top--]; + value = st[top--]; + + result = value + (type * result); + } + s++; + } + + return result; +} diff --git a/c/stack/binary-search-tree-iterator.c b/c/stack/binary-search-tree-iterator.c new file mode 100644 index 0000000..e3bffdb --- /dev/null +++ b/c/stack/binary-search-tree-iterator.c @@ -0,0 +1,59 @@ +/** + * Definition for binary tree + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +struct BSTIterator { + struct TreeNode **st; + struct TreeNode *cur; + int top; + int count; +}; + +struct BSTIterator *bstIteratorCreate(struct TreeNode *root) { + struct BSTIterator *iter; + iter = malloc(sizeof(struct BSTIterator)); + iter->count = 20; + iter->cur = root; + iter->top = -1; + iter->st = malloc(sizeof(struct TreeNode *) * iter->count); + + return iter; +} + +/** @return whether we have a next smallest number */ +bool bstIteratorHasNext(struct BSTIterator *iter) { + return iter->cur != NULL || iter->top > -1; +} + +/** @return the next smallest number */ +int bstIteratorNext(struct BSTIterator *iter) { + while(iter->cur){ + if(iter->top + 1 == iter->count){ + iter->count <<= 1; + iter->st = realloc(iter->st, iter->count * sizeof(struct TreeNode *)); + } + iter->st[++iter->top] = iter->cur; + iter->cur = iter->cur->left; + } + struct TreeNode *t = iter->st[iter->top]; + iter->top--; + iter->cur = t->right; + + return t->val; +} + +/** Deallocates memory previously allocated for the iterator */ +void bstIteratorFree(struct BSTIterator *iter) { + free(iter->st); +} + +/** + * Your BSTIterator will be called like this: + * struct BSTIterator *i = bstIteratorCreate(root); + * while (bstIteratorHasNext(i)) printf("%d\n", bstIteratorNext(i)); + * bstIteratorFree(i); + */ diff --git a/c/stack/binary-tree-inorder-traversal.c b/c/stack/binary-tree-inorder-traversal.c new file mode 100644 index 0000000..eaeed1d --- /dev/null +++ b/c/stack/binary-tree-inorder-traversal.c @@ -0,0 +1,51 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* inorderTraversal(struct TreeNode* root, int* returnSize) { + struct TreeNode **st; + struct TreeNode *cur; + int *arr; + int top; + int idx = 0; + int st_count = 50; + int arr_count = 50; + + st = malloc(sizeof(struct TreeNode *) * st_count); + arr = malloc(sizeof(int) * arr_count); + top = -1; + + cur = root; + while(cur || top > -1){ + while(cur){ + if(top + 1 == st_count){ + st_count <<= 1; + st = realloc(st,st_count * sizeof(struct TreeNode *)); + } + st[++top] = cur; + cur = cur->left; + } + + cur = st[top]; + top--; + arr[idx++] = cur->val; + cur = cur->right; + if(idx == arr_count){ + arr_count <<= 1; + arr = realloc(arr, arr_count * sizeof(int)); + } + } + + free(st); + *returnSize = idx; + + return arr; +} diff --git a/c/stack/binary-tree-postorder-traversal.c b/c/stack/binary-tree-postorder-traversal.c new file mode 100644 index 0000000..f26e966 --- /dev/null +++ b/c/stack/binary-tree-postorder-traversal.c @@ -0,0 +1,56 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* postorderTraversal(struct TreeNode* root, int* returnSize) { + struct TreeNode **st; + struct TreeNode *cur, *pre = NULL; + int top; + int *data; + int idx; + int st_count = 32; + int data_count = 32; + + data = malloc(sizeof(int) * data_count); + st = malloc(sizeof(struct TreeNode *) * st_count); + top = -1; + idx = 0; + + if(root) + st[++top] = root; + + while(top > -1){ + cur = st[top]; + if((cur->left == NULL && cur->right == NULL) || + (pre != NULL && (pre == cur->left || pre == cur->right))){ + if(idx == data_count) { + data_count <<= 1; + data = realloc(data,sizeof(int) * data_count); + } + data[idx++] = cur->val; + top--; + pre = cur; + }else{ + if(top + 2 >= st_count){ + st_count <<= 1; + st = realloc(st, sizeof(struct TreeNode *) * st_count); + } + if(cur->right != NULL) + st[++top] = cur->right; + if(cur->left != NULL) + st[++top] = cur->left; + } + } + + free(st); + *returnSize = idx; + return data; +} diff --git a/c/stack/binary-tree-preorder-traversal.c b/c/stack/binary-tree-preorder-traversal.c new file mode 100644 index 0000000..ffdb1e0 --- /dev/null +++ b/c/stack/binary-tree-preorder-traversal.c @@ -0,0 +1,53 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* preorderTraversal(struct TreeNode* root, int* returnSize) { + struct TreeNode **st; + struct TreeNode *cur; + int *data; + int idx = 0; + int top = -1; + int data_count = 32; + int st_count = 32; + + st = malloc(sizeof(struct TreeNode *) * st_count); + data = malloc(sizeof(int) * data_count); + + if(root) + st[++top] = cur; + + while(top > -1){ + cur = st[top--]; + + data[idx++] = cur->val; + if(idx == data_count){ + data_count <<= 1; + data = realloc(data, sizeof(int) * data_count); + } + + if(cur->right) + st[++top] = cur->right; + + if(cur->left) + st[++top] = cur->left; + + if(top+1 == st_count){ + st_count <<= 1; + st = realloc(st, sizeof(struct TreeNode *) * st_count); + } + } + + *returnSize = idx; + + free(st); + return data; +} diff --git a/c/stack/binary-tree-zigzag-level-order-traversal.c b/c/stack/binary-tree-zigzag-level-order-traversal.c new file mode 100644 index 0000000..df9f3d6 --- /dev/null +++ b/c/stack/binary-tree-zigzag-level-order-traversal.c @@ -0,0 +1,73 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +/** + * 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** zigzagLevelOrder(struct TreeNode* root, int** columnSizes, int* returnSize) { + int **data; + int *arr_count; + int data_count = 500; + int idx = 0; + struct TreeNode **cur_st; + struct TreeNode **next_st; + int cur_top = -1; + int next_top = -1; + int left2right = 0; + struct TreeNode* cur; + + data = malloc(sizeof(int *) * data_count); + arr_count = malloc(sizeof(int) * data_count); + + cur_st = malloc(sizeof(struct TreeNode *) * 500); + next_st = malloc(sizeof(struct TreeNode *) * 500); + + if(root) + cur_st[++cur_top] = root; + + while(cur_top > -1){ + int c = 0; + struct TreeNode **swap; + + next_top = -1; + data[idx] = malloc(sizeof(int) * data_count); + while(cur_top > -1){ + cur = cur_st[cur_top--]; + data[idx][c++] = cur->val; + if(left2right){ + if(cur->right) + next_st[++next_top] = cur->right; + if(cur->left) + next_st[++next_top] = cur->left; + }else{ + if(cur->left) + next_st[++next_top] = cur->left; + if(cur->right) + next_st[++next_top] = cur->right; + } + } + arr_count[idx] = c; + idx++; + left2right ^= 1; + + swap = cur_st; + cur_st = next_st; + next_st = swap; + + cur_top = next_top; + } + + *columnSizes = arr_count; + *returnSize = idx; + + free(cur_st); + free(next_st); + return data; +} diff --git a/c/stack/evaluate-reverse-polish-notation.c b/c/stack/evaluate-reverse-polish-notation.c new file mode 100644 index 0000000..4d34e82 --- /dev/null +++ b/c/stack/evaluate-reverse-polish-notation.c @@ -0,0 +1,45 @@ +int is_op(char *s) +{ + return !strcmp(s, "+") || !strcmp(s, "-") || + !strcmp(s, "*") || !strcmp(s, "/"); +} + +int evalRPN(char** tokens, int tokensSize) { + int *st; + int top = -1; + int res,left,right; + int i; + + st = malloc(sizeof(int) * tokensSize); + for(i = 0; i < tokensSize; ++i){ + char *s = tokens[i]; + if(!is_op(s)){ + st[++top] = atoi(s); + }else{ + right = st[top--]; + left = st[top--]; + switch(s[0]){ + case '+': + res = left + right; + break; + case '-': + res = left - right; + break; + case '*': + res = left * right; + break; + case '/': + res = left / right; + break; + default: + break; + } + + st[++top] = res; + } + } + + res = st[top]; + free(st); + return res; +} diff --git a/c/stack/implement-queue-using-stacks.c b/c/stack/implement-queue-using-stacks.c new file mode 100644 index 0000000..a09b463 --- /dev/null +++ b/c/stack/implement-queue-using-stacks.c @@ -0,0 +1,48 @@ +typedef struct { + int *front_st; + int *back_st; + int front_top; + int back_top; +} Queue; + +/* Create a queue */ +void queueCreate(Queue *queue, int maxSize) { + queue->front_st = malloc(sizeof(int) * maxSize); + queue->back_st = malloc(sizeof(int) * maxSize); + queue->front_top = -1; + queue->back_top = -1; +} + +/* Push element x to the back of queue */ +void queuePush(Queue *queue, int element) { + queue->back_st[++queue->back_top] = element; +} + +/* Removes the element from front of queue */ +void queuePop(Queue *queue) { + if(queue->front_top == -1) + while(queue->back_top > -1) + queue->front_st[++queue->front_top] = queue->back_st[queue->back_top--]; + + return queue->front_st[queue->front_top--]; +} + +/* Get the front element */ +int queuePeek(Queue *queue) { + if(queue->front_top == -1) + while(queue->back_top > -1) + queue->front_st[++queue->front_top] = queue->back_st[queue->back_top--]; + + return queue->front_st[queue->front_top]; +} + +/* Return whether the queue is empty */ +bool queueEmpty(Queue *queue) { + return queue->front_top == -1 && queue->back_top == -1; +} + +/* Destroy the queue */ +void queueDestroy(Queue *queue) { + free(queue->front_st); + free(queue->back_st); +} diff --git a/c/stack/implement-stack-using-queues.c b/c/stack/implement-stack-using-queues.c new file mode 100644 index 0000000..7979b2d --- /dev/null +++ b/c/stack/implement-stack-using-queues.c @@ -0,0 +1,64 @@ +typedef struct { + int *q1; + int *q2; + int f1; + int e1; + int f2; + int e2; +} Stack; + +/* Create a stack */ +void stackCreate(Stack *stack, int maxSize) { + stack->q1 = malloc(sizeof(int) * maxSize); + stack->q2 = malloc(sizeof(int) * maxSize); + stack->f1 = 0; + stack->e1 = 0; + stack->f2 = 0; + stack->e2 = 0; +} + +/* Push element x onto stack */ +void stackPush(Stack *stack, int element) { + if(stack->f1 == stack->e1){ + stack->q1[stack->e1++] = element; + while(stack->f2 != stack->e2){ + int value = stack->q2[stack->f2++]; + stack->q1[stack->e1++] = value; + } + stack->f2= stack->e2 = 0; + }else{ + stack->q2[stack->e2++] = element; + while(stack->f1 != stack->e1){ + int value = stack->q1[stack->f1++]; + stack->q2[stack->e2++] = value; + } + stack->f1 = stack->e1 = 0; + } +} + +/* Removes the element on top of the stack */ +void stackPop(Stack *stack) { + if(stack->f1 != stack->e1) + stack->f1++; + else + stack->f2++; +} + +/* Get the top element */ +int stackTop(Stack *stack) { + if(stack->f1 != stack->e1) + return stack->q1[stack->f1]; + else + return stack->q2[stack->f2]; +} + +/* Return whether the stack is empty */ +bool stackEmpty(Stack *stack) { + return stack->f1 == stack->e1 && stack->f2 == stack->e2; +} + +/* Destroy the stack */ +void stackDestroy(Stack *stack) { + free(stack->q1); + free(stack->q2); +} diff --git a/c/stack/largest-rectangle-in-histogram.c b/c/stack/largest-rectangle-in-histogram.c new file mode 100644 index 0000000..d710be1 --- /dev/null +++ b/c/stack/largest-rectangle-in-histogram.c @@ -0,0 +1,23 @@ +int largestRectangleArea(int* heights, int heightsSize) { + int *st; + int top = -1; + int maxArea = 0; + int i; + + st = malloc(sizeof(int) * heightsSize); + for(i = 0; i <= heightsSize; ++i){ + int curh = ((i == heightsSize) ? 0 : heights[i]); + while(top > -1 && curh <= heights[st[top]]){ + int h = heights[st[top--]]; + int w = ((top == -1) ? i : (i - st[top] - 1)); + + if(h * w > maxArea) + maxArea = h * w; + } + + st[++top] = i; + } + + free(st); + return maxArea; +} diff --git a/c/stack/maximal-rectangle.c b/c/stack/maximal-rectangle.c new file mode 100644 index 0000000..3e2d816 --- /dev/null +++ b/c/stack/maximal-rectangle.c @@ -0,0 +1,49 @@ +int *st; + +int maxArea(int *heights, int matrixColSize) +{ + int top = -1; + int i; + int area = 0; + + for(i = 0; i <= matrixColSize; ++i){ + while(top != -1 && heights[i] <= heights[st[top]]){ + int h = heights[st[top--]]; + int w = ((top == -1) ? i : (i - st[top] - 1)); + + if(h * w > area) + area = h * w; + } + st[++top] = i; + } + + return area; +} + +int maximalRectangle(char** matrix, int matrixRowSize, int matrixColSize) { + int *heights; + int i,j; + int max_area = 0; + int area = 0; + + heights = malloc(sizeof(int) * (matrixColSize+1)); + memset(heights, 0, sizeof(int) * (matrixColSize+1)); + st = malloc(sizeof(int) * (matrixColSize+1)); + + for(i = 0; i < matrixRowSize; ++i){ + for(j = 0; j < matrixColSize; ++j){ + if(matrix[i][j] == '0') + heights[j] = 0; + else + heights[j]++; + } + + area = maxArea(heights,matrixColSize); + max_area = area > max_area ? area : max_area; + } + + free(heights); + free(st); + + return max_area; +} diff --git a/c/stack/min-stack.c b/c/stack/min-stack.c new file mode 100644 index 0000000..e47eeca --- /dev/null +++ b/c/stack/min-stack.c @@ -0,0 +1,41 @@ +typedef struct { + int *st_data; + int *st_min; + int top_data; + int top_min; +} MinStack; + +void minStackCreate(MinStack *stack, int maxSize) { + stack->st_data = malloc(sizeof(int) * maxSize); + stack->st_min = malloc(sizeof(int) * maxSize); + stack->top_data = -1; + stack->top_min = -1; +} + +void minStackPush(MinStack *stack, int element) { + stack->st_data[++stack->top_data] = element; + + if(stack->top_min == -1 || element <= stack->st_min[stack->top_min]) + stack->st_min[++stack->top_min] = element; +} + +void minStackPop(MinStack *stack) { + if(stack->top_min != -1 && stack->st_data[stack->top_data] == + stack->st_min[stack->top_min]) + --stack->top_min; + + --stack->top_data; +} + +int minStackTop(MinStack *stack) { + return stack->st_data[stack->top_data]; +} + +int minStackGetMin(MinStack *stack) { + return stack->st_min[stack->top_min]; +} + +void minStackDestroy(MinStack *stack) { + free(stack->st_data); + free(stack->st_min); +} diff --git a/c/stack/min-stack.cpp b/c/stack/min-stack.cpp new file mode 100644 index 0000000..3b7682b --- /dev/null +++ b/c/stack/min-stack.cpp @@ -0,0 +1,41 @@ +class MinStack { +public: + /** initialize your data structure here. */ + MinStack() { + + } + + void push(int x) { + st.push(x); + if(min_st.empty() || x <= min_st.top()) + min_st.push(x); + } + + void pop() { + int x = st.top(); + if(x == min_st.top()) + min_st.pop(); + st.pop(); + } + + int top() { + return st.top(); + } + + int getMin() { + return min_st.top(); + } + +private: + stack st; + stack min_st; +}; + +/** + * Your MinStack object will be instantiated and called as such: + * MinStack obj = new MinStack(); + * obj.push(x); + * obj.pop(); + * int param_3 = obj.top(); + * int param_4 = obj.getMin(); + */ diff --git a/c/stack/remove-duplicate-letters.c b/c/stack/remove-duplicate-letters.c new file mode 100644 index 0000000..ea07d05 --- /dev/null +++ b/c/stack/remove-duplicate-letters.c @@ -0,0 +1,35 @@ +char* removeDuplicateLetters(char* s) { + char hash[256]; + char visited[256]; + int i = 0; + char *st; + int top; + + memset(hash,0,256); + memset(visited,0,256); + + while(s[i]) + ++hash[s[i++]]; + + st = malloc(i + 1); + top = -1; + + while(*s){ + char ch = *(s++); + hash[ch]--; + if(visited[ch]) + continue; + + while(top > -1 && st[top] > ch && hash[st[top]] > 0){ + visited[st[top]] = 0; + top--; + } + + st[++top] = ch; + visited[ch] = 1; + } + + st[++top] = 0; + + return st; +} diff --git a/c/stack/simplify-path.c b/c/stack/simplify-path.c new file mode 100644 index 0000000..bfc5b81 --- /dev/null +++ b/c/stack/simplify-path.c @@ -0,0 +1,80 @@ +struct path { + char *name; + struct path *parent; + struct path *child; +}; + +struct path* init_path(char *name) +{ + struct path *p = malloc(sizeof(struct path)); + p->name = strdup(name); + p->parent = NULL; + p->child = NULL; + + return p; +} + +struct path *handle_dotdot(struct path *p) +{ + if(!p->parent) + return p; + + struct path *parent = p->parent; + parent->child = NULL; + free(p->name); + free(p); + return parent; +} + +char* simplifyPath(char* path) { + struct path *root; + struct path *cur, *parent; + char *start,*name; + + root = init_path("/"); + cur = root; + + while(*path){ + while(*path == '/') + path++; + if (*path == '\0') + break; + + start = path; + while(*path && *path != '/') + path++; + + int len = path - start; + char *name = strndup(start,len); + if(!strcmp(name,".")) + continue; + if(!strcmp(name,"..")){ + cur = handle_dotdot(cur); + continue; + } + + struct path *p = init_path(name); + p->parent = cur; + cur->child = p; + cur = p; + free(name); + } + + cur = root; + char *ret = malloc(4096); + ret[0] = 0; + strcat(ret,root->name); + cur = root->child; + + while(cur){ + strcat(ret,cur->name); + parent = cur; + cur = cur->child; + free(parent->name); + free(parent); + if(cur) + strcat(ret,"/"); + } + + return ret; +} diff --git a/c/stack/trapping-rain-water.c b/c/stack/trapping-rain-water.c new file mode 100644 index 0000000..788f882 --- /dev/null +++ b/c/stack/trapping-rain-water.c @@ -0,0 +1,31 @@ +int trap(int* height, int heightSize) { + int max_height = 0; + int max_index = 0; + int i; + int ret = 0; + + for(i = 0; i < heightSize; ++i){ + if(height[i] > max_height){ + max_height = height[i]; + max_index = i; + } + } + + max_height = 0; + for(i = 0; i < max_index; ++i){ + if(max_height > height[i]) + ret += (max_height - height[i]); + else + max_height = height[i]; + } + + max_height = 0; + for(i = heightSize - 1; i > max_index; --i){ + if(max_height > height[i]) + ret += (max_height - height[i]); + else + max_height = height[i]; + } + + return ret; +} diff --git a/c/stack/valid-parentheses.c b/c/stack/valid-parentheses.c new file mode 100644 index 0000000..ef8e437 --- /dev/null +++ b/c/stack/valid-parentheses.c @@ -0,0 +1,30 @@ +bool is_match(char left, char right) +{ + return (left == '(' && right == ')') || + (left == '{' && right == '}') || + (left == '[' && right == ']'); +} + +bool isValid(char* s) { + int *st; + int top; + int len; + + len = strlen(s); + st = malloc(sizeof(int) * len); + top = -1; + + while(*s){ + if(*s == '(' || *s == '[' || *s == '{') + st[++top] = *s; + else if(top > -1 && is_match(st[top], *s)) + top--; + else + return false; + + s++; + } + + free(st); + return top == -1; +} diff --git a/c/stack/valid-parentheses[2].c b/c/stack/valid-parentheses[2].c new file mode 100644 index 0000000..83bfeba --- /dev/null +++ b/c/stack/valid-parentheses[2].c @@ -0,0 +1,26 @@ +bool isValid(char* s) { + char *st; + int len; + int top = -1; + + len = strlen(s); + st = malloc(len); + + while(*s){ + if(*s == '(' || *s == '{' || *s == '['){ + st[++top] = *s; + }else if( *s == ')' && st[top] == '('){ + --top; + }else if(*s == '}' && st[top] == '{'){ + --top; + }else if(*s == ']' && st[top] == '['){ + --top; + }else{ + return false; + } + + s++; + } + + return top == -1; +} diff --git a/c/stack/verify-preorder-serialization-of-a-binary-tree.c b/c/stack/verify-preorder-serialization-of-a-binary-tree.c new file mode 100644 index 0000000..1f8512f --- /dev/null +++ b/c/stack/verify-preorder-serialization-of-a-binary-tree.c @@ -0,0 +1,37 @@ +bool isValidSerialization(char* preorder) { + int count = 0; + char *next = preorder; + char *left,*right; + + if(*next && *next != '#') + count++; + + while (count-- > 0){ + while(*next && *next != ',') + next++; + if(*next) + next++; + left = next; + if(!*left) + return false; + + while(*next && *next != ',') + next++; + if(*next) + next++; + right = next; + if(!*right) + return false; + + if(*left != '#') + count++; + if(*right != '#') + count++; + } + while(*next && *next != ',') + next++; + if(*next) + return false; + + return true; +} diff --git a/c/string/add-binary.c b/c/string/add-binary.c new file mode 100644 index 0000000..8c6bf0e --- /dev/null +++ b/c/string/add-binary.c @@ -0,0 +1,40 @@ +char* addBinary(char* a, char* b) { + char *ret; + int la,lb,lr; + int i,j,k; + int carry = 0; + int value; + + la = strlen(a); + lb = strlen(b); + lr = (la > lb ? la : lb) + 2; + + ret = (char *)malloc(sizeof(char) * lr); + ret[lr-1] = 0; + k = lr-2; + i = la - 1; + j = lb - 1; + while(i >= 0 && j >= 0){ + value = (a[i--] - '0') + (b[j--] - '0') + carry; + carry = value / 2; + value %= 2; + ret[k--] = '0' + value; + } + + if(j >= 0){ + i = j; + a = b; + } + + while(i >= 0){ + value = (a[i--] - '0') + carry; + carry = value / 2; + value %= 2; + ret[k--] = '0' + value; + } + + if(carry) + ret[k--] = '1'; + + return ret + k + 1; +} diff --git a/c/string/compare-version-numbers.c b/c/string/compare-version-numbers.c new file mode 100644 index 0000000..fd14cfa --- /dev/null +++ b/c/string/compare-version-numbers.c @@ -0,0 +1,28 @@ +int compareVersion(char* version1, char* version2) { + int len1, len2; + int v1,v2; + int i,j; + + len1 = strlen(version1); + len2 = strlen(version2); + i = j = 0; + v1 = v2 = 0; + while(v1 == v2 && (i < len1 || j < len2)){ + while(version1[i] != '.' && i < len1){ + v1 = v1 * 10 + version1[i] - '0'; + i++; + } + while(version2[j] != '.' && j < len2){ + v2 = v2 * 10 + version2[j] - '0'; + j++; + } + + if(v1 != v2) + break; + v1 = v2 = 0; + i++; + j++; + } + + return v1 == v2 ? 0 : (v1 > v2 ? 1 : -1); +} diff --git a/c/string/count-and-say.c b/c/string/count-and-say.c new file mode 100644 index 0000000..db70294 --- /dev/null +++ b/c/string/count-and-say.c @@ -0,0 +1,34 @@ +char* countAndSay(int n) { + char *ret; + char *tmp; + int num = 10000; + int index = 1; + int i,j,count,value,len; + + ret = (char *)malloc(sizeof(char) * num); + tmp = (char *)malloc(sizeof(char) * num); + memset(ret,0,sizeof(char) * num); + ret[0] = '1'; + + while(index < n){ + i = 0; + j = 0; + len = strlen(ret); + while(i < len){ + value = ret[i++]; + count = 1; + while(i < len && ret[i] == value){ + i++; + count++; + } + tmp[j++] = count + '0'; + tmp[j++] = value; + } + tmp[j] = 0; + strcpy(ret,tmp); + index++; + } + + free(tmp); + return ret; +} diff --git a/c/string/decode-ways.c b/c/string/decode-ways.c new file mode 100644 index 0000000..9e50da4 --- /dev/null +++ b/c/string/decode-ways.c @@ -0,0 +1,28 @@ +int numDecodings(char* s) { + int len; + int *dp; + int i,value; + int ret; + + len = strlen(s); + if(len == 0) + return 0; + + dp = (int *)malloc(sizeof(int) * (len+1)); + + dp[len] = 1; + dp[len-1] = s[len-1] == '0' ? 0 : 1; + + for(i = len - 2; i >= 0; --i){ + if(s[i] == '0') + dp[i] = 0; + else if((s[i] - '0') * 10 + (s[i+1] - '0') <= 26) + dp[i] = dp[i+1] + dp[i+2]; + else + dp[i] = dp[i+1]; + } + + ret = dp[0]; + free(dp); + return ret; +} diff --git a/c/string/decode-ways[1].c b/c/string/decode-ways[1].c new file mode 100644 index 0000000..fe652fa --- /dev/null +++ b/c/string/decode-ways[1].c @@ -0,0 +1,28 @@ +int numDecodings(char* s) { + int *dp; + int len,i; + int ret,value; + + len = strlen(s); + if(len == 0) + return 0; + + dp = (int *)malloc(sizeof(int) * (len + 1)); + dp[0] = 1; + dp[1] = s[0] == '0' ? 0 : 1; + + for(i = 2; i <= len; ++i){ + dp[i] = 0; + if(s[i-1] != '0') + dp[i] = dp[i-1]; + + value = (s[i-2] - '0') * 10 + s[i-1] - '0'; + if(value >= 10 && value <= 26) + dp[i] += dp[i-2]; + } + + ret = dp[len]; + free(dp); + + return ret; +} diff --git a/c/string/distinct-subsequences.c b/c/string/distinct-subsequences.c new file mode 100644 index 0000000..295fee8 --- /dev/null +++ b/c/string/distinct-subsequences.c @@ -0,0 +1,32 @@ +int numDistinct(char* s, char* t) { + int **dp; + int i,j; + int len_s,len_t; + int ret; + len_s = strlen(s); + len_t = strlen(t); + + dp = (int **)malloc(sizeof(int *) * (len_s+1)); + for(i = 0; i <= len_s; ++i){ + dp[i] = (int *)malloc(sizeof(int) * (len_t+1)); + memset(dp[i],0,sizeof(int) * (len_t + 1)); + } + + for(i = 0; i <= len_s; ++i) + dp[i][0] = 1; + + for(i = 1; i <= len_s; ++i){ + for(j = 1; j <= len_t; ++j){ + dp[i][j] = dp[i-1][j]; + if(s[i-1] == t[j-1]) + dp[i][j] += dp[i-1][j-1]; + } + } + + ret = dp[len_s][len_t]; + for(i = 0; i <= len_s; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/c/string/edit-distance.c b/c/string/edit-distance.c new file mode 100644 index 0000000..8e142ae --- /dev/null +++ b/c/string/edit-distance.c @@ -0,0 +1,39 @@ +int minDistance(char* word1, char* word2) { + int **dp; + int len1,len2; + int i,j,ret; + + len1 = strlen(word1); + len2 = strlen(word2); + + dp = (int **)malloc(sizeof(int *) * (len1 + 1)); + for(i = 0; i <= len1; ++i){ + dp[i] = (int *)malloc(sizeof(int) * (len2 + 1)); + memset(dp[i],0,sizeof(int) * (len2+1)); + } + + for(i = 1; i <= len1; ++i) + dp[i][0] = i; + for(i = 1; i <= len2; ++i) + dp[0][i] = i; + + for(i = 1; i <= len1; ++i){ + for(j = 1; j <= len2; ++j){ + if(word1[i-1] == word2[j-1]) + dp[i][j] = dp[i-1][j-1]; + else{ + ret = dp[i-1][j] < dp[i][j-1] ? dp[i-1][j] : dp[i][j-1]; + ret = dp[i-1][j-1] < ret ? dp[i-1][j-1] : ret; + + dp[i][j] = ret + 1; + } + } + } + + ret = dp[len1][len2]; + for(i = 0; i <= len1; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/c/string/implement-strstr.c b/c/string/implement-strstr.c new file mode 100644 index 0000000..3a175e9 --- /dev/null +++ b/c/string/implement-strstr.c @@ -0,0 +1,23 @@ +int strStr(char* haystack, char* needle) { + int jump[256]; + int i,j; + int ht_len,nd_len; + + ht_len = strlen(haystack); + nd_len = strlen(needle); + + for(i = 0; i < ht_len; ++i) + jump[haystack[i]] = nd_len + 1; + for(i = 0; i < nd_len; ++i) + jump[needle[i]] = nd_len - i; + + for(i = 0; i <= ht_len - nd_len; i += jump[haystack[i+nd_len]]){ + j = 0; + while(j < nd_len && haystack[i+j] == needle[j]) + j++; + if(j == nd_len) + return i; + } + + return -1; +} diff --git a/c/string/integer-to-roman.c b/c/string/integer-to-roman.c new file mode 100644 index 0000000..18de05b --- /dev/null +++ b/c/string/integer-to-roman.c @@ -0,0 +1,32 @@ +char* intToRoman(int num) { + int values[] = { + 1000, 900, 500, 400, + 100, 90, 50, 40, + 10, 9, 5, 4, + 1 + }; + + char symbols[13][3] = { + "M", "CM", "D", "CD", + "C", "XC", "L", "XL", + "X", "IX", "V", "IV", + "I" + }; + + int i; + char *ret; + ret = (char *)malloc(sizeof(char) * 50); + memset(ret,0,sizeof(char) * 50); + + i = 0; + while(num > 0){ + if(num >= values[i]){ + strcat(ret,symbols[i]); + num -= values[i]; + continue; + } + i++; + } + + return ret; +} diff --git a/c/string/interleaving-string.c b/c/string/interleaving-string.c new file mode 100644 index 0000000..da0e994 --- /dev/null +++ b/c/string/interleaving-string.c @@ -0,0 +1,37 @@ +bool isInterleave(char* s1, char* s2, char* s3) { + bool **dp; + bool ret; + int i,j,len1,len2,len3; + + len1 = strlen(s1); + len2 = strlen(s2); + len3 = strlen(s3); + + if(len1 + len2 != len3) + return false; + + dp = (bool **)malloc(sizeof(bool *) * (len1 + 1)); + for(i = 0;i <= len1; ++i) + dp[i] = (bool *)malloc(sizeof(bool) * (len2 + 1)); + + dp[0][0] = true; + for(i = 1; i <= len1; ++i) + dp[i][0] = (dp[i-1][0] && (s1[i-1] == s3[i-1])); + + for(j = 1; j <= len2; ++j) + dp[0][j] = (dp[0][j-1] && (s2[j-1] == s3[j-1])); + + for(i = 1; i <= len1; ++i){ + for(j = 1; j <= len2; ++j){ + dp[i][j] = ((dp[i-1][j] && s1[i-1] == s3[i - 1 + j]) + || (dp[i][j-1] && s2[j-1] == s3[i + j - 1])); + } + } + + ret = dp[len1][len2]; + for(i = 0; i <= len1; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/c/string/length-of-last-word.c b/c/string/length-of-last-word.c new file mode 100644 index 0000000..1c2778c --- /dev/null +++ b/c/string/length-of-last-word.c @@ -0,0 +1,19 @@ +int lengthOfLastWord(char* s) { + int start; + int end,last; + + start = -1; + end = 0; + last = strlen(s); + + while(last > 0 && s[last-1] == ' ') + --last; + + while(end < last){ + if(s[end] == ' ') + start = end; + end++; + } + + return end - start - 1; +} diff --git a/c/string/length-of-last-word[1].c b/c/string/length-of-last-word[1].c new file mode 100644 index 0000000..162fa64 --- /dev/null +++ b/c/string/length-of-last-word[1].c @@ -0,0 +1,13 @@ +int lengthOfLastWord(char* s) { + int len = strlen(s); + int pos; + + while(len > 0 && s[len-1] == ' ') + --len; + + pos = len - 1; + while(pos >= 0 && s[pos] != ' ') + --pos; + + return len - pos - 1; +} diff --git a/c/string/longest-common-prefix.c b/c/string/longest-common-prefix.c new file mode 100644 index 0000000..5f7e391 --- /dev/null +++ b/c/string/longest-common-prefix.c @@ -0,0 +1,21 @@ +char* longestCommonPrefix(char** strs, int strsSize) { + int n = 0; + int i,loop_flag; + + if(strsSize == 0) + return ""; + loop_flag = 1; + while(loop_flag){ + char value = strs[0][n]; + for(i = 0; i < strsSize; ++i){ + if(strs[i][n] == 0 || strs[i][n] != value){ + loop_flag = 0; + break; + } + } + if(loop_flag) + n++; + } + + return strndup(strs[0],n); +} diff --git a/c/string/longest-common-prefix[1].c b/c/string/longest-common-prefix[1].c new file mode 100644 index 0000000..0f61ed5 --- /dev/null +++ b/c/string/longest-common-prefix[1].c @@ -0,0 +1,16 @@ +char* longestCommonPrefix(char** strs, int strsSize) { + int i,j; + int len; + + if(strsSize == 0) + return ""; + + len = strlen(strs[0]); + for(i = 0; i < len; ++i){ + for(j = 1; j < strsSize; ++j) + if(strs[j][i] != strs[0][i]) + return strndup(strs[0],i); + } + + return strndup(strs[0],i); +} diff --git a/c/string/longest-palindromic-substring.c b/c/string/longest-palindromic-substring.c new file mode 100644 index 0000000..a7aa8a8 --- /dev/null +++ b/c/string/longest-palindromic-substring.c @@ -0,0 +1,36 @@ +int expand(char *s, int start, int end) +{ + while(start >= 0 && s[end] && s[start] == s[end]){ + --start; + ++end; + } + return end - start - 1; +} + +char* longestPalindrome(char* s) { + int max,t1,t2,tmax,len,index; + int i; + char *ret; + + len = strlen(s); + max = 0; + for(i = 0; i < len; ++i){ + t1 = expand(s,i,i); + t2 = expand(s,i,i+1); + tmax = t1 > t2 ? t1 : t2; + if(tmax > max){ + max = tmax; + index = i - (tmax - 1) / 2; + } + } + + ret = (char *)malloc(sizeof(char) * (max + 1)); + i = 0; + while(i < max){ + ret[i] = s[index + i]; + i++; + } + ret[max] = 0; + + return ret; +} diff --git a/c/string/longest-substring-without-repeating-characters.c b/c/string/longest-substring-without-repeating-characters.c new file mode 100644 index 0000000..3445597 --- /dev/null +++ b/c/string/longest-substring-without-repeating-characters.c @@ -0,0 +1,18 @@ +int lengthOfLongestSubstring(char* s) { + int index[256]; + int last_index; + int len,i,ret; + + memset(index,0,sizeof(int) * 256); + last_index = -1; + len = strlen(s); + + ret = 0; + for(i = 0; i < len; ++i){ + last_index = index[s[i]] > last_index ? index[s[i]] : last_index; + index[s[i]] = i + 1; + ret = (i - last_index + 1 > ret) ? i - last_index + 1 : ret; + } + + return ret; +} diff --git a/c/string/roman-to-integer.c b/c/string/roman-to-integer.c new file mode 100644 index 0000000..7c3587b --- /dev/null +++ b/c/string/roman-to-integer.c @@ -0,0 +1,31 @@ +int romanToInt(char* s) { + int values[] = { + 1000, 900, 500, 400, + 100, 90, 50, 40, + 10, 9, 5, 4, + 1 + }; + + char symbols[13][3] = { + "M", "CM", "D", "CD", + "C", "XC", "L", "XL", + "X", "IX", "V", "IV", + "I" + }; + + int i = 0; + int ret = 0; + int len; + + while(*s && i < 13){ + len = strlen(symbols[i]); + if(!strncmp(s,symbols[i],len)){ + ret += values[i]; + s += len; + continue; + } + i++; + } + + return ret; +} diff --git a/c/string/string-to-integer-atoi.c b/c/string/string-to-integer-atoi.c new file mode 100644 index 0000000..ade6c90 --- /dev/null +++ b/c/string/string-to-integer-atoi.c @@ -0,0 +1,26 @@ +int myAtoi(char* str) { + int is_neg; + int ret; + + is_neg = 1; + while(*str == ' ') + str++; + + if(*str == '+'){ + str++; + }else if (*str == '-'){ + is_neg = -1; + str++; + } + + ret = 0; + while(*str && (*str >= '0' && *str <= '9')){ + int tmp = ret; + ret = (ret * 10) + *str - '0'; + if(ret / 10 != tmp) + return is_neg == -1 ? INT_MIN : INT_MAX; + str++; + } + + return is_neg * ret; +} diff --git a/c/string/valid-palindrome.c b/c/string/valid-palindrome.c new file mode 100644 index 0000000..45ef07f --- /dev/null +++ b/c/string/valid-palindrome.c @@ -0,0 +1,31 @@ +bool is_equal(int a, int b) +{ + if(a >= 'A' && a <= 'Z') + a = a - 'A' + 'a'; + if(b >= 'A' && b <= 'Z') + b = b - 'A' + 'a'; + return a == b; +} + +bool isPalindrome(char* s) { + int start, end; + + start = 0; + end = strlen(s) - 1; + while(start < end){ + if(!isalpha(s[start]) && !isdigit(s[start])){ + start++; + continue; + } + if(!isalpha(s[end]) && !isdigit(s[end])){ + --end; + continue; + } + if(!is_equal(s[start], s[end])) + return false; + ++start; + --end; + } + + return true; +} diff --git a/c/string/valid-parentheses.c b/c/string/valid-parentheses.c new file mode 100644 index 0000000..6b021b8 --- /dev/null +++ b/c/string/valid-parentheses.c @@ -0,0 +1,26 @@ +bool isValid(char* s) { + char *st; + int len,i; + int top; + char ch; + + len = strlen(s); + st = (char *)malloc(sizeof(char) * len); + top = -1; + for(i = 0; i < len; ++i){ + if(s[i] == '(' || s[i] == '[' || s[i] == '{') + st[++top] = s[i]; + else{ + if(top == -1) + return false; + + ch = st[top--]; + if((ch == '(' && s[i] != ')') || (ch == '[' && + s[i] != ']') || (ch == '{' && s[i] != '}')) + return false; + } + } + + free(st); + return top == -1; +} diff --git a/c/tree/balanced-binary-tree.c b/c/tree/balanced-binary-tree.c new file mode 100644 index 0000000..53ae77b --- /dev/null +++ b/c/tree/balanced-binary-tree.c @@ -0,0 +1,29 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +#define max_2(x,y) ({ \ + int _x = (x); \ + int _y = (y); \ + _x > _y ? _x : _y ;\ +}) +int depth(struct TreeNode *root) +{ + if(root == NULL) + return 0; + + int left = depth(root->left); + int right = depth(root->right); + + if(left == -1 || right == -1 || abs(left - right) > 1) + return -1; + + return max_2(left,right) + 1; +} +bool isBalanced(struct TreeNode* root) { + return depth(root) != -1; +} diff --git a/c/tree/binary-search-tree-iterator.c b/c/tree/binary-search-tree-iterator.c new file mode 100644 index 0000000..c41f0de --- /dev/null +++ b/c/tree/binary-search-tree-iterator.c @@ -0,0 +1,56 @@ +/** + * Definition for binary tree + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +struct BSTIterator { + struct TreeNode **st; + struct TreeNode *cur; + int count; + int top; +}; + +struct BSTIterator *bstIteratorCreate(struct TreeNode *root) { + struct BSTIterator *it = malloc(sizeof(struct BSTIterator)); + it->count = 20; + it->st = malloc(sizeof(struct TreeNode *) * it->count); + it->top = -1; + it->cur = root; + + return it; +} + +/** @return whether we have a next smallest number */ +bool bstIteratorHasNext(struct BSTIterator *it) { + return it->top > -1 || it->cur != NULL; +} + +/** @return the next smallest number */ +int bstIteratorNext(struct BSTIterator *it) { + while(it->cur){ + if(it->top == it->count){ + it->count <<= 1; + it->st = realloc(it->st, sizeof(struct TreeNode *) * it->count); + } + it->st[++(it->top)] = it->cur; + it->cur = it->cur->left; + } + struct TreeNode *tmp = it->st[(it->top)--]; + it->cur = tmp->right; + return tmp->val; +} + +/** Deallocates memory previously allocated for the iterator */ +void bstIteratorFree(struct BSTIterator *it) { + free(it->st); +} + +/** + * Your BSTIterator will be called like this: + * struct BSTIterator *i = bstIteratorCreate(root); + * while (bstIteratorHasNext(i)) printf("%d\n", bstIteratorNext(i)); + * bstIteratorFree(i); + */ diff --git a/c/tree/binary-tree-inorder-traversal.c b/c/tree/binary-tree-inorder-traversal.c new file mode 100644 index 0000000..e685e6b --- /dev/null +++ b/c/tree/binary-tree-inorder-traversal.c @@ -0,0 +1,48 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* inorderTraversal(struct TreeNode* root, int* returnSize) { + int *arr; + struct TreeNode **st; + struct TreeNode *cur; + int top = -1; + int arr_count = 32; + int st_count = 32; + int idx = 0; + + st = malloc(sizeof(struct TreeNode *) * st_count); + arr = malloc(sizeof(int) * arr_count); + + cur = root; + while(cur || top > -1){ + while(cur){ + if(top + 1 == st_count){ + st_count <<= 1; + st = realloc(st,sizeof(struct TreeNode *) * st_count); + } + st[++top] = cur; + cur = cur->left; + } + + struct TreeNode *tmp = st[top--]; + cur = tmp->right; + if(idx == arr_count){ + arr_count <<= 1; + arr = realloc(arr, sizeof(int) * arr_count); + } + arr[idx++] = tmp->val; + } + + *returnSize = idx ; + free(st); + return arr; +} diff --git a/c/tree/binary-tree-level-order-traversal-ii.c b/c/tree/binary-tree-level-order-traversal-ii.c new file mode 100644 index 0000000..8bcc8d0 --- /dev/null +++ b/c/tree/binary-tree-level-order-traversal-ii.c @@ -0,0 +1,89 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +/** + * 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** levelOrderBottom(struct TreeNode* root, int** columnSizes, int* returnSize) { + int **arr; + int *col; + struct TreeNode **q; + struct TreeNode **new_q; + struct TreeNode **cur; + int arr_count = 8; + int idx = 0; + int q_count = 512; + int tmp_count = 8; + int i,j; + + arr = malloc(sizeof(int *) * arr_count); + col = malloc(sizeof(int) * arr_count); + q = malloc(sizeof(struct TreeNode *) * q_count); + new_q = malloc(sizeof(struct TreeNode *) * q_count); + + q[0] = root; + q[1] = NULL; + while(*q){ + int *tmp; + i = 0; + j = 0; + cur = q; + memset(new_q, 0, sizeof(struct TreeNode *) * q_count); + tmp = malloc(sizeof(int) * tmp_count); + while(*cur){ + if(i == tmp_count){ + tmp_count <<= 1; + tmp = realloc(tmp, sizeof(int) * tmp_count); + } + tmp[i++] = (*cur)->val; + if((*cur)->left) + new_q[j++] = (*cur)->left; + if((*cur)->right) + new_q[j++] = (*cur)->right; + + cur++; + } + + if(idx == arr_count){ + arr_count <<= 1; + col = realloc(col, sizeof(int) * arr_count); + arr = realloc(arr,sizeof(int *) * arr_count); + } + + col[idx] = i; + arr[idx++] = tmp; + + cur = new_q; + new_q = q; + q = cur; + } + + i = 0; + j = idx - 1; + while(i < j){ + int *swap = arr[i]; + int swap_col = col[i]; + + arr[i] = arr[j]; + arr[j] = swap; + + col[i] = col[j]; + col[j] = swap_col; + i++; + j--; + } + + *columnSizes = col; + *returnSize = idx; + free(q); + free(new_q); + + return arr; +} diff --git a/c/tree/binary-tree-level-order-traversal.c b/c/tree/binary-tree-level-order-traversal.c new file mode 100644 index 0000000..aae3eaa --- /dev/null +++ b/c/tree/binary-tree-level-order-traversal.c @@ -0,0 +1,76 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +/** + * 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** levelOrder(struct TreeNode* root, int** columnSizes, int* returnSize) { + int **arr; + int *col_arr; + int i,j; + struct TreeNode **q; + struct TreeNode **new_q; + struct TreeNode **cur; + int arr_idx = 0; + int q_count = 512; + int arr_count = 8; + int tmp_count = 8; + int idx = 0; + + + arr = malloc(sizeof(int *) * arr_count); + col_arr = malloc(sizeof(int) * arr_count); + q = malloc(sizeof(struct TreeNode *) * q_count); + new_q = malloc(sizeof(struct TreeNode *) * q_count); + + q[0] = root; + q[1] = NULL; + while(*q != NULL){ + cur = q; + memset(new_q, 0, sizeof(struct TreeNode *) * q_count); + int *tmp = malloc(sizeof(int) * tmp_count); + i = 0; + j= 0; + while(*cur != NULL) { + if(i == tmp_count){ + tmp_count <<= 2; + tmp = realloc(tmp, sizeof(int) * tmp_count); + } + tmp[i++] = (*cur)->val; + + if((*cur)->left) + new_q[j++] = (*cur)->left; + if((*cur)->right) + new_q[j++] = (*cur)->right; + + cur++; + } + if(idx == arr_count){ + arr_count <<= 2; + col_arr = realloc(col_arr, sizeof(int) * arr_count); + arr = realloc(arr, sizeof(int *) * arr_count); + } + col_arr[idx] = i; + arr[idx++] = tmp; + + memset(q, 0, sizeof(struct TreeNode *) * q_count); + cur = new_q; + new_q = q; + q = cur; + + } + + *columnSizes = col_arr; + *returnSize = idx; + + free(q); + free(new_q); + return arr; +} diff --git a/c/tree/binary-tree-maximum-path-sum.c b/c/tree/binary-tree-maximum-path-sum.c new file mode 100644 index 0000000..23aaebe --- /dev/null +++ b/c/tree/binary-tree-maximum-path-sum.c @@ -0,0 +1,34 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +int get_max(struct TreeNode *root, int *node) +{ + if(root == NULL) + return 0; + + int left = get_max(root->left,node); + int right = get_max(root->right,node); + int ret; + int tmp; + + ret = root->val; + ret += left > right ? left : right; + + tmp = root->val + left + right; + *node = tmp > *node ? tmp : *node; + + return ret < 0 ? 0 : ret; +} + +int maxPathSum(struct TreeNode* root) { + int node = INT_MIN; + + get_max(root,&node); + + return node; +} diff --git a/c/tree/binary-tree-postorder-traversal.c b/c/tree/binary-tree-postorder-traversal.c new file mode 100644 index 0000000..0c648e5 --- /dev/null +++ b/c/tree/binary-tree-postorder-traversal.c @@ -0,0 +1,35 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int count = 32; +void post_order(struct TreeNode *root, int **arr, int *idx) +{ + if(root == NULL) + return ; + post_order(root->left,arr,idx); + post_order(root->right,arr,idx); + if(*idx == count){ + count <<= 1; + *arr = realloc(*arr,sizeof(int) * count); + } + (*arr)[(*idx)++] = root->val; +} + +int* postorderTraversal(struct TreeNode* root, int* returnSize) { + int *arr; + int idx = 0; + arr = malloc(sizeof(int) * count); + post_order(root,&arr,&idx); + + *returnSize = idx; + return arr; +} diff --git a/c/tree/binary-tree-postorder-traversal[1].c b/c/tree/binary-tree-postorder-traversal[1].c new file mode 100644 index 0000000..7e7c099 --- /dev/null +++ b/c/tree/binary-tree-postorder-traversal[1].c @@ -0,0 +1,53 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* postorderTraversal(struct TreeNode* root, int* returnSize) { + int *arr; + int arr_count = 32; + struct TreeNode **st; + struct TreeNode *pre = NULL; + int st_count = 32; + int idx = 0; + int top = -1; + + arr = malloc(sizeof(int) * arr_count); + st = malloc(sizeof(struct TreeNode *) * st_count); + if(root) + st[++top] = root; + + while(top > -1){ + struct TreeNode *cur = st[top]; + if((cur->left == NULL && cur->right == NULL) || + (pre && (pre == cur->left || pre == cur->right))){ + --top; + if(idx == arr_count){ + arr_count <<= 1; + arr = realloc(arr, sizeof(int) * arr_count); + } + arr[idx++] = cur->val; + pre = cur; + }else{ + if(top + 2 >= st_count){ + st_count <<= 1; + st = realloc(st,sizeof(struct TreeNode *) * st_count); + } + if(cur->right) + st[++top] = cur->right; + if(cur->left) + st[++top] = cur->left; + } + } + + *returnSize = idx; + free(st); + return arr; +} diff --git a/c/tree/binary-tree-preorder-traversal.c b/c/tree/binary-tree-preorder-traversal.c new file mode 100644 index 0000000..4defdf0 --- /dev/null +++ b/c/tree/binary-tree-preorder-traversal.c @@ -0,0 +1,48 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* preorderTraversal(struct TreeNode* root, int* returnSize) { + int *arr; + struct TreeNode **st; + int idx = 0; + int arr_size = 32; + int st_size = 32; + int top = -1; + + arr = malloc(sizeof(int) * arr_size); + st = malloc(sizeof(struct TreeNode *) * st_size); + if(root) + st[++top] = root; + + while(top > -1){ + struct TreeNode *cur = st[top--]; + if(idx == arr_size){ + arr_size <<= 1; + arr = realloc(arr,sizeof(int) * arr_size); + } + + arr[idx++] = cur->val; + if(top + 2 >= st_size){ + st_size <<= 1; + st = realloc(st, sizeof(struct TreeNode *) * st_size); + } + + if(cur->right) + st[++top] = cur->right; + if(cur->left) + st[++top] = cur->left; + } + + *returnSize = idx; + free(st); + return arr; +} diff --git a/c/tree/binary-tree-preorder-traversal[1].c b/c/tree/binary-tree-preorder-traversal[1].c new file mode 100644 index 0000000..0f0fbfb --- /dev/null +++ b/c/tree/binary-tree-preorder-traversal[1].c @@ -0,0 +1,39 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +void recursive(struct TreeNode* root, int **array, int *idx, int *arr_size) +{ + if(!root) + return ; + + + if(*idx >= *arr_size){ + *arr_size <<= 1; + *array = realloc(*array, sizeof(int) * (*arr_size)); + } + + int *arr = *array; + arr[(*idx)++] = root->val; + recursive(root->left,&arr,idx,arr_size); + recursive(root->right,&arr,idx,arr_size); +} + +int* preorderTraversal(struct TreeNode* root, int* returnSize) { + int *arr = NULL; + int arr_size = 32; + *returnSize = 0; + + arr = malloc(sizeof(int) * arr_size); + recursive(root,&arr,returnSize,&arr_size); + + return arr; +} diff --git a/c/tree/binary-tree-right-side-view.c b/c/tree/binary-tree-right-side-view.c new file mode 100644 index 0000000..287a0c5 --- /dev/null +++ b/c/tree/binary-tree-right-side-view.c @@ -0,0 +1,55 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* rightSideView(struct TreeNode* root, int* returnSize) { + struct TreeNode **st; + struct TreeNode **next_st; + int top = -1; + int next_top = -1; + int *arr; + int idx = 0; + int arr_size = 32; + + arr = malloc(arr_size * sizeof(int)); + st = malloc(100 * sizeof(struct TreeNode *)); + next_st = malloc(100 * sizeof(struct TreeNode *)); + + + if(root) + st[++top] = root; + + while( top > -1){ + if(idx >= arr_size){ + arr_size <<= 1; + arr = realloc(arr, sizeof(int) * arr_size); + } + arr[idx++] = st[top]->val; + for(int i = 0; i <= top; ++i){ + if(st[i]->left) + next_st[++next_top] = st[i]->left; + if(st[i]->right) + next_st[++next_top] = st[i]->right; + } + + struct TreeNode **swap = st; + st = next_st; + next_st = swap; + + top = next_top; + next_top = -1; + } + + *returnSize = idx; + free(st); + free(next_st); + return arr; +} diff --git a/c/tree/binary-tree-right-side-view[1].c b/c/tree/binary-tree-right-side-view[1].c new file mode 100644 index 0000000..39f12bf --- /dev/null +++ b/c/tree/binary-tree-right-side-view[1].c @@ -0,0 +1,43 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ + +int *arr; +int arr_size; +int idx; + +void dfs(struct TreeNode *root,int depth) +{ + if(!root) + return; + + if(depth >= idx) + idx = depth; + if(depth >= arr_size){ + arr_size <<= 1; + arr = realloc(arr, sizeof(int) * arr_size); + } + arr[depth] = root->val; + dfs(root->left, depth+1); + dfs(root->right, depth+1); +} + +int* rightSideView(struct TreeNode* root, int* returnSize) { + arr_size = 32; + idx = -1; + arr = malloc(sizeof(int) * arr_size); + dfs(root,0); + + *returnSize = idx+1; + + return arr; +} diff --git a/c/tree/binary-tree-zigzag-level-order-traversal.c b/c/tree/binary-tree-zigzag-level-order-traversal.c new file mode 100644 index 0000000..49a4942 --- /dev/null +++ b/c/tree/binary-tree-zigzag-level-order-traversal.c @@ -0,0 +1,73 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +/** + * 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** zigzagLevelOrder(struct TreeNode* root, int** columnSizes, int* returnSize) { + int left2right = 0; + int **arr; + int arr_size = 64; + int row = 0; + int *col_size; + struct TreeNode **queue; + int queue_count = 0; + struct TreeNode **next_queue; + int next_queue_count= 0; + int i; + + arr = malloc(sizeof(int *) * arr_size); + col_size = malloc(sizeof(int) * arr_size); + + queue = malloc(sizeof(struct TreeNode *) * 128); + next_queue = malloc(sizeof(struct TreeNode *) * 128); + + if(root) + queue[queue_count++] = root; + + while(queue_count > 0){ + int *ele = malloc(sizeof(int) * queue_count); + col_size[row] = queue_count; + for(i = 0; i < queue_count; ++i){ + ele[i] = queue[i]->val; + + } + for(i = queue_count-1; i >= 0; --i){ + if(left2right){ + if(queue[i]->left) + next_queue[next_queue_count++] = queue[i]->left; + if(queue[i]->right) + next_queue[next_queue_count++] = queue[i]->right; + }else{ + if(queue[i]->right) + next_queue[next_queue_count++] = queue[i]->right; + if(queue[i]->left) + next_queue[next_queue_count++] = queue[i]->left; + } + } + + arr[row] = ele; + struct TreeNode **swap = queue; + queue = next_queue; + next_queue = swap; + + queue_count = next_queue_count; + next_queue_count = 0; + + left2right ^= 1; + row++; + } + + free(queue); + free(next_queue); + *returnSize = row; + *columnSizes = col_size; + return arr; +} diff --git a/c/tree/construct-binary-tree-from-inorder-and-postorder-traversal.c b/c/tree/construct-binary-tree-from-inorder-and-postorder-traversal.c new file mode 100644 index 0000000..67de031 --- /dev/null +++ b/c/tree/construct-binary-tree-from-inorder-and-postorder-traversal.c @@ -0,0 +1,31 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +struct TreeNode* rescan(int* inorder, int left_in, int* postorder, int left_post, int len) +{ + if(len <= 0) + return NULL; + struct TreeNode *node = malloc(sizeof(struct TreeNode)); + + int node_pos = left_in; + while(node_pos < left_in + len){ + if(inorder[node_pos] == postorder[left_post + len - 1]) + break; + ++node_pos; + } + + node->val = postorder[left_post + len - 1]; + node->left = rescan(inorder,left_in,postorder,left_post,node_pos-left_in); + node->right = rescan(inorder,node_pos+1,postorder,left_post + node_pos - left_in, + len - 1 - (node_pos - left_in)); + return node; +} + +struct TreeNode* buildTree(int* inorder, int inorderSize, int* postorder, int postorderSize) { + return rescan(inorder, 0, postorder,0,postorderSize); +} diff --git a/c/tree/construct-binary-tree-from-preorder-and-inorder-traversal.c b/c/tree/construct-binary-tree-from-preorder-and-inorder-traversal.c new file mode 100644 index 0000000..ca0a65a --- /dev/null +++ b/c/tree/construct-binary-tree-from-preorder-and-inorder-traversal.c @@ -0,0 +1,33 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ + +struct TreeNode *rescan(int *preorder, int left_pre, int *inorder, int left_in, int len) +{ + if(len <= 0) + return NULL; + + struct TreeNode *node = malloc(sizeof(struct TreeNode)); + int node_pos = left_in; + while(node_pos < left_in + len){ + if(inorder[node_pos] == preorder[left_pre]) + break; + ++node_pos; + } + + node->val = preorder[left_pre]; + node->left = rescan(preorder, left_pre + 1, inorder, left_in, node_pos - left_in); + node->right = rescan(preorder, left_pre + 1 + node_pos - left_in, inorder, + node_pos + 1, len - 1 - (node_pos - left_in)); + + return node; +} + +struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize) { + return rescan(preorder, 0, inorder, 0, inorderSize); +} diff --git a/c/tree/convert-sorted-array-to-binary-search-tree.c b/c/tree/convert-sorted-array-to-binary-search-tree.c new file mode 100644 index 0000000..7310740 --- /dev/null +++ b/c/tree/convert-sorted-array-to-binary-search-tree.c @@ -0,0 +1,26 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +struct TreeNode *bcreate(int *nums, int start, int end) +{ + if(end < start) + return NULL; + + int mid = (start + end) / 2; + struct TreeNode *node = malloc(sizeof(struct TreeNode)); + + node->val = nums[mid]; + node->left = bcreate(nums, start, mid - 1); + node->right = bcreate(nums, mid + 1, end); + + return node; +} + +struct TreeNode* sortedArrayToBST(int* nums, int numsSize) { + return bcreate(nums,0,numsSize - 1); +} diff --git a/c/tree/count-complete-tree-nodes.c b/c/tree/count-complete-tree-nodes.c new file mode 100644 index 0000000..0072a6f --- /dev/null +++ b/c/tree/count-complete-tree-nodes.c @@ -0,0 +1,33 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +int countNodes(struct TreeNode* root) { + int lh = 0; + int rh = 0; + struct TreeNode *node; + + if(root == NULL) + return 0; + + node = root; + while(node){ + ++lh; + node = node->left; + } + + node = root; + while(node){ + ++rh; + node = node->right; + } + + if(lh == rh) + return (1 << lh) - 1; + + return 1 + countNodes(root->left) + countNodes(root->right); +} diff --git a/c/tree/flatten-binary-tree-to-linked-list.c b/c/tree/flatten-binary-tree-to-linked-list.c new file mode 100644 index 0000000..82f0c17 --- /dev/null +++ b/c/tree/flatten-binary-tree-to-linked-list.c @@ -0,0 +1,27 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ + +void flatten(struct TreeNode* root) { + if(root == NULL) + return ; + + struct TreeNode *left = root->left; + struct TreeNode *right = root->right; + + root->left = NULL; + root->right = left; + + flatten(left); + flatten(right); + + while(root->right) + root = root->right; + + root->right = right; +} diff --git a/c/tree/flatten-binary-tree-to-linked-list[2].c b/c/tree/flatten-binary-tree-to-linked-list[2].c new file mode 100644 index 0000000..99ce1ec --- /dev/null +++ b/c/tree/flatten-binary-tree-to-linked-list[2].c @@ -0,0 +1,26 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +void flatten(struct TreeNode* root) { + if(!root) + return ; + + while(root){ + if(root->left){ + struct TreeNode *node = root->left; + while(node->right) + node = node->right; + + node->right = root->right; + root->right = root->left; + root->left = NULL; + } + + root = root->right; + } +} diff --git a/c/tree/house-robber-iii.c b/c/tree/house-robber-iii.c new file mode 100644 index 0000000..cf21a4f --- /dev/null +++ b/c/tree/house-robber-iii.c @@ -0,0 +1,21 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +int rob(struct TreeNode* root) { + if(root == NULL) + return 0; + + int m1 = rob(root->left) + rob(root->right); + int m2 = root->val; + if(root->left) + m2 += rob(root->left->left) + rob(root->left->right); + if(root->right) + m2 += rob(root->right->left) + rob(root->right->right); + + return m2 > m1 ? m2 : m1; +} diff --git a/c/tree/house-robber-iii[1].c b/c/tree/house-robber-iii[1].c new file mode 100644 index 0000000..9ed8319 --- /dev/null +++ b/c/tree/house-robber-iii[1].c @@ -0,0 +1,38 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +#define max2(x,y) ({ \ + int _x = (x); \ + int _y = (y); \ + _x > _y ? _x : _y; \ +}) + +void dfs(struct TreeNode* root, int *rob, int *not_rob) +{ + if(root == NULL){ + *rob = 0; + *not_rob = 0; + return ; + } + + int left, not_left; + int right, not_right; + dfs(root->left, &left, ¬_left); + dfs(root->right, &right, ¬_right); + + *rob = root->val + not_left + not_right; + *not_rob = max2(left, not_left) + max2(right, not_right); +} + +int rob(struct TreeNode* root) { + int rob, not_rob; + + dfs(root,&rob, ¬_rob); + + return max2(rob, not_rob); +} diff --git a/c/tree/invert-binary-tree.c b/c/tree/invert-binary-tree.c new file mode 100644 index 0000000..b0b6b3a --- /dev/null +++ b/c/tree/invert-binary-tree.c @@ -0,0 +1,18 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +struct TreeNode* invertTree(struct TreeNode* root) { + if(!root) + return NULL; + + struct TreeNode *node = invertTree(root->left); + root->left = invertTree(root->right); + root->right = node; + + return root; +} diff --git a/c/tree/kth-smallest-element-in-a-bst.c b/c/tree/kth-smallest-element-in-a-bst.c new file mode 100644 index 0000000..42333a0 --- /dev/null +++ b/c/tree/kth-smallest-element-in-a-bst.c @@ -0,0 +1,30 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +int getKth(struct TreeNode *root, int k, int *val) +{ + if(root == NULL) + return 0; + + int left = getKth(root->left,k, val); + if(left + 1 > k) + return left; + else if(left + 1 == k){ + *val = root->val; + return left + 1; + } + + return left + 1 + getKth(root->right, k - left - 1, val); +} + +int kthSmallest(struct TreeNode* root, int k) { + int val; + getKth(root,k,&val); + + return val; +} diff --git a/c/tree/lowest-common-ancestor-of-a-binary-search-tree.c b/c/tree/lowest-common-ancestor-of-a-binary-search-tree.c new file mode 100644 index 0000000..d624d39 --- /dev/null +++ b/c/tree/lowest-common-ancestor-of-a-binary-search-tree.c @@ -0,0 +1,20 @@ +/** + * Definition for a binary tree node. + * 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) + return root; + + struct TreeNode *left = lowestCommonAncestor(root->left,p,q); + struct TreeNode *right = lowestCommonAncestor(root->right, p, q); + + if(left && right) + return root; + + return left ? left : right; +} diff --git a/c/tree/lowest-common-ancestor-of-a-binary-search-tree[1].c b/c/tree/lowest-common-ancestor-of-a-binary-search-tree[1].c new file mode 100644 index 0000000..634ebe9 --- /dev/null +++ b/c/tree/lowest-common-ancestor-of-a-binary-search-tree[1].c @@ -0,0 +1,28 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +#define min_2(x,y) ({ \ + int _x = (x); \ + int _y = (y); \ + _x < _y ? _x : _y;\ +}) + +#define max_2(x,y) ({ \ + int _x = (x); \ + int _y = (y); \ + _x > _y ? _x : _y; \ +}) + +struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) { + if(min_2(p->val, q->val) > root->val) + return lowestCommonAncestor(root->right, p, q); + else if(max_2(p->val, q->val) < root->val) + return lowestCommonAncestor(root->left, p, q); + else + return root; +} diff --git a/c/tree/lowest-common-ancestor-of-a-binary-search-tree[2].c b/c/tree/lowest-common-ancestor-of-a-binary-search-tree[2].c new file mode 100644 index 0000000..341ccdc --- /dev/null +++ b/c/tree/lowest-common-ancestor-of-a-binary-search-tree[2].c @@ -0,0 +1,62 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +int find; +int top; +int ptop; +int qtop; +struct TreeNode *parr[5000]; +struct TreeNode *qarr[5000]; +struct TreeNode *arr[5000]; + +void scan(struct TreeNode *root, struct TreeNode *node, int flag) +{ + if(root == NULL || find) + return ; + + arr[++top] = root; + if(root == node){ + find = 1; + if(flag){ + ptop = top; + for(int i = 0; i <= top; ++i) + parr[i] = arr[i]; + }else{ + qtop = top; + for(int i = 0; i <= top; ++i) + qarr[i] = arr[i]; + } + return; + } + + scan(root->left, node, flag); + if(find) + return; + + scan(root->right, node, flag); + if(find) + return; + + --top; +} + +struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) { + find = 0; + top = -1; + scan(root,p,0); + + find = 0; + top = -1; + scan(root,q,1); + + int m = ptop < qtop ? ptop : qtop; + while(parr[m] != qarr[m]) + m--; + + return parr[m]; +} diff --git a/c/tree/lowest-common-ancestor-of-a-binary-tree.c b/c/tree/lowest-common-ancestor-of-a-binary-tree.c new file mode 100644 index 0000000..865caec --- /dev/null +++ b/c/tree/lowest-common-ancestor-of-a-binary-tree.c @@ -0,0 +1,20 @@ +/** + * Definition for a binary tree node. + * 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) + return root; + + struct TreeNode *left = lowestCommonAncestor(root->left,p,q); + struct TreeNode *right = lowestCommonAncestor(root->right,p,q); + + if(left && right) + return root; + + return left ? left : right; +} diff --git a/c/tree/maximum-depth-of-binary-tree.c b/c/tree/maximum-depth-of-binary-tree.c new file mode 100644 index 0000000..0a1d76d --- /dev/null +++ b/c/tree/maximum-depth-of-binary-tree.c @@ -0,0 +1,28 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +void depth(struct TreeNode *root, int cur_h, int *max_h) +{ + if(root == NULL) + return ; + + cur_h++; + if(cur_h > *max_h) + *max_h = cur_h; + + depth(root->left, cur_h, max_h); + depth(root->right, cur_h, max_h); +} +int maxDepth(struct TreeNode* root) { + int max_h = 0; + int cur_h = 0; + + depth(root, cur_h, &max_h); + + return max_h; +} diff --git a/c/tree/maximum-depth-of-binary-tree[1].c b/c/tree/maximum-depth-of-binary-tree[1].c new file mode 100644 index 0000000..b434011 --- /dev/null +++ b/c/tree/maximum-depth-of-binary-tree[1].c @@ -0,0 +1,17 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +int maxDepth(struct TreeNode* root) { + if(root == NULL) + return 0; + + int left = maxDepth(root->left); + int right = maxDepth(root->right); + + return (left > right ? left : right) + 1; +} diff --git a/c/tree/minimum-depth-of-binary-tree.c b/c/tree/minimum-depth-of-binary-tree.c new file mode 100644 index 0000000..3ab6643 --- /dev/null +++ b/c/tree/minimum-depth-of-binary-tree.c @@ -0,0 +1,25 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +int minDepth(struct TreeNode* root) { + if(root == NULL) + return 0; + + if(root->left == NULL && root->right == NULL) + return 1; + + int left = minDepth(root->left); + int right = minDepth(root->right); + + if(left == 0) + left = INT_MAX; + if(right == 0) + right = INT_MAX; + + return left < right ? left + 1 : right + 1; +} diff --git a/c/tree/path-sum.c b/c/tree/path-sum.c new file mode 100644 index 0000000..51e0d2b --- /dev/null +++ b/c/tree/path-sum.c @@ -0,0 +1,23 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +bool hasPathSum(struct TreeNode* root, int sum) { + if(root == NULL) + return false; + + if(root->left == NULL && root->right == NULL) + return root->val == sum; + + bool bleft = hasPathSum(root->left,sum - root->val); + if(bleft) + return true; + + bool bright = hasPathSum(root->right, sum - root->val); + + return bright; +} diff --git a/c/tree/populating-next-right-pointers-in-each-node-ii.c b/c/tree/populating-next-right-pointers-in-each-node-ii.c new file mode 100644 index 0000000..01e7721 --- /dev/null +++ b/c/tree/populating-next-right-pointers-in-each-node-ii.c @@ -0,0 +1,50 @@ +/** + * Definition for binary tree with next pointer. + * struct TreeLinkNode { + * int val; + * struct TreeLinkNode *left, *right, *next; + * }; + * + */ + +struct TreeLinkNode *get_next_child(struct TreeLinkNode *root) +{ + while(root){ + if(root->left) + return root->left; + if(root->right) + return root->right; + root = root->next; + } + + return NULL; +} + +struct TreeLinkNode *get_next(struct TreeLinkNode *root) +{ + while(root && root->left == NULL && root->right == NULL) + root = root->next; + + return root; +} + +void connect(struct TreeLinkNode *root) { + if(root == NULL) + return; + + struct TreeLinkNode *parent = get_next(root); + struct TreeLinkNode *next = get_next_child(root); + while(parent && next){ + while(parent){ + if(parent->left) + parent->left->next = parent->right ? parent->right : get_next_child(parent->next); + + if(parent->right) + parent->right->next = get_next_child(parent->next); + + parent = get_next(parent->next); + } + parent = get_next(next); + next = get_next_child(next); + } +} diff --git a/c/tree/populating-next-right-pointers-in-each-node-ii[1].c b/c/tree/populating-next-right-pointers-in-each-node-ii[1].c new file mode 100644 index 0000000..d9de8a2 --- /dev/null +++ b/c/tree/populating-next-right-pointers-in-each-node-ii[1].c @@ -0,0 +1,42 @@ +/** + * Definition for binary tree with next pointer. + * struct TreeLinkNode { + * int val; + * struct TreeLinkNode *left, *right, *next; + * }; + * + */ +void connect(struct TreeLinkNode *root) { + struct TreeLinkNode *parent; + struct TreeLinkNode *arr[2]; + struct TreeLinkNode *first, *last; + int idx; + + parent = root; + while(parent){ + first = NULL; + last = NULL; + + while(parent){ + idx = 0; + if(parent->left) + arr[idx++] = parent->left; + if(parent->right) + arr[idx++] = parent->right; + + for(int i = 0; i < idx; ++i){ + if(first == NULL){ + first = arr[i]; + last = arr[i]; + continue; + } + last->next = arr[i]; + last = last->next; + } + + parent = parent->next; + } + + parent = first; + } +} diff --git a/c/tree/populating-next-right-pointers-in-each-node.c b/c/tree/populating-next-right-pointers-in-each-node.c new file mode 100644 index 0000000..6a0e968 --- /dev/null +++ b/c/tree/populating-next-right-pointers-in-each-node.c @@ -0,0 +1,49 @@ +/** + * Definition for binary tree with next pointer. + * struct TreeLinkNode { + * int val; + * struct TreeLinkNode *left, *right, *next; + * }; + * + */ +void connect(struct TreeLinkNode *root) { + if(root == NULL) + return ; + + int arr_size = 64; + int next_size = 64; + struct TreeLinkNode **arr = malloc(sizeof(struct TreeLinkNode *) * arr_size); + struct TreeLinkNode **next_arr = malloc(sizeof(struct TreeLinkNode *) * next_size); + int top; + int next_top; + + top = -1; + arr[++top] = root; + + while(top > -1){ + next_top = -1; + for(int i = 0; i <= top; ++i){ + arr[i]->next = (i != top) ? arr[i+1] : NULL; + if(next_top + 2 >= arr_size){ + arr_size <<= 1; + next_arr = realloc(next_arr, sizeof(struct TreeLinkNode *) * arr_size); + } + if(arr[i]->left) + next_arr[++next_top] = arr[i]->left; + if(arr[i]->right) + next_arr[++next_top] = arr[i]->right; + } + + struct TreeLinkNode **tmp = arr; + arr = next_arr; + next_arr = tmp; + top = next_top; + + int size = arr_size; + arr_size = next_size; + next_size = size; + } + + free(arr); + free(next_arr); +} diff --git a/c/tree/populating-next-right-pointers-in-each-node[1].c b/c/tree/populating-next-right-pointers-in-each-node[1].c new file mode 100644 index 0000000..b6b841b --- /dev/null +++ b/c/tree/populating-next-right-pointers-in-each-node[1].c @@ -0,0 +1,32 @@ +/** + * Definition for binary tree with next pointer. + * struct TreeLinkNode { + * int val; + * struct TreeLinkNode *left, *right, *next; + * }; + * + */ +void connect(struct TreeLinkNode *root) { + if(root == NULL) + return; + struct TreeLinkNode *parent = root; + struct TreeLinkNode *next = root->left; + + while(parent && next){ + struct TreeLinkNode *pre = NULL; + while(parent){ + if(pre == NULL){ + pre = parent->left; + }else{ + pre->next = parent->left; + pre = pre->next; + } + pre->next = parent->right; + pre = pre->next; + parent = parent->next; + } + + parent = next; + next = next->left; + } +} diff --git a/c/tree/recover-binary-search-tree.c b/c/tree/recover-binary-search-tree.c new file mode 100644 index 0000000..c5949b3 --- /dev/null +++ b/c/tree/recover-binary-search-tree.c @@ -0,0 +1,38 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +struct TreeNode *prev, *t2,*t1; + +void inorder(struct TreeNode *root){ + if(root == NULL) + return; + + inorder(root->left); + + if(prev && prev-> val > root->val){ + t2 = root; + if(t1 == NULL) + t1 = prev; + } + + prev = root; + inorder(root->right); +} + +void recoverTree(struct TreeNode* root) { + prev = NULL; + t1 = NULL; + t2 = NULL; + inorder(root); + + if(t1 && t2){ + int tmp = t1->val; + t1->val = t2->val; + t2->val = tmp; + } +} diff --git a/c/tree/same-tree.c b/c/tree/same-tree.c new file mode 100644 index 0000000..635931c --- /dev/null +++ b/c/tree/same-tree.c @@ -0,0 +1,17 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +bool isSameTree(struct TreeNode* p, struct TreeNode* q) { + if(p && q){ + if(p->val != q->val) + return false; + return isSameTree(p->left, q->left) && isSameTree(p->right, q->right); + } + + return p == NULL && q == NULL; +} diff --git a/c/tree/sum-root-to-leaf-numbers.c b/c/tree/sum-root-to-leaf-numbers.c new file mode 100644 index 0000000..c14d259 --- /dev/null +++ b/c/tree/sum-root-to-leaf-numbers.c @@ -0,0 +1,24 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ + +int sum(struct TreeNode *root, int cur_val) +{ + if(root == NULL) + return 0; + + int val = cur_val * 10 + root->val; + if(root->left == NULL && root->right == NULL) + return val; + + return sum(root->left, val) + sum(root->right, val); +} + +int sumNumbers(struct TreeNode* root) { + return sum(root,0); +} diff --git a/c/tree/symmetric-tree.c b/c/tree/symmetric-tree.c new file mode 100644 index 0000000..76f01ed --- /dev/null +++ b/c/tree/symmetric-tree.c @@ -0,0 +1,27 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ + +bool isSame(struct TreeNode *left, struct TreeNode *right) +{ + if(left && right){ + if(left->val != right->val) + return false; + + return isSame(left->left, right->right) && isSame(left->right, right->left); + } + + return left == NULL && right == NULL; +} + +bool isSymmetric(struct TreeNode* root) { + if(root) + return isSame(root->left,root->right); + + return true; +} diff --git a/c/tree/unique-binary-search-trees.c b/c/tree/unique-binary-search-trees.c new file mode 100644 index 0000000..2297e88 --- /dev/null +++ b/c/tree/unique-binary-search-trees.c @@ -0,0 +1,17 @@ +int numTrees(int n) { + int *num; + int ret; + + num = malloc(sizeof(int) * (n + 1)); + memset(num, 0, sizeof(int) * (n + 1)); + num[1] = 1; + num[0] = 1; + for(int i = 2;i <= n; ++i){ + for(int j = 0; j < i; ++j) + num[i] +=(num[j] * num[i - j - 1]); + } + + ret = num[n]; + free(num); + return ret; +} diff --git a/c/tree/validate-binary-search-tree.c b/c/tree/validate-binary-search-tree.c new file mode 100644 index 0000000..eeb78c5 --- /dev/null +++ b/c/tree/validate-binary-search-tree.c @@ -0,0 +1,28 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +bool isValidBST(struct TreeNode* root) { + if(root == NULL) + return true; + + struct TreeNode *node = root->left; + while(node && node->right) + node = node->right; + + if(node && node->val >= root->val) + return false; + + node = root->right; + while(node && node->left) + node = node->left; + + if(node && node->val <= root->val) + return false; + + return isValidBST(root->left) && isValidBST(root->right); +} diff --git a/c/tree/validate-binary-search-tree[1].c b/c/tree/validate-binary-search-tree[1].c new file mode 100644 index 0000000..61df80f --- /dev/null +++ b/c/tree/validate-binary-search-tree[1].c @@ -0,0 +1,28 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +struct TreeNode *lastnode; +bool isValid(struct TreeNode* root) +{ + if(root == NULL) + return true; + + if(!isValid(root->left)) + return false; + + if(lastnode != NULL && lastnode->val >= root->val) + return false; + + lastnode = root; + return isValid(root->right); +} + +bool isValidBST(struct TreeNode* root) { + lastnode = NULL; + return isValid(root); +} diff --git a/c/two-pointers/3sum-closest.c b/c/two-pointers/3sum-closest.c new file mode 100644 index 0000000..12da829 --- /dev/null +++ b/c/two-pointers/3sum-closest.c @@ -0,0 +1,28 @@ +int cmp(const void *a, const void *b) +{ + return *(const int *)a - *(const int *)b; +} + +int threeSumClosest(int* nums, int numsSize, int target) { + int start,end; + int sum; + int i; + int ret = nums[0] + nums[1] + nums[2]; + + qsort(nums,numsSize,sizeof(int),cmp); + for(i = 0; i < numsSize-2; ++i){ + start = i + 1; + end = numsSize - 1; + while(start < end){ + sum = nums[i] + nums[start] + nums[end]; + if(abs(sum - target) < abs(ret-target)) + ret = sum; + if(sum > target) + --end; + else + ++start; + } + } + + return ret; +} diff --git a/c/two-pointers/3sum.c b/c/two-pointers/3sum.c new file mode 100644 index 0000000..ce9874f --- /dev/null +++ b/c/two-pointers/3sum.c @@ -0,0 +1,59 @@ +/** + * Return an array of arrays of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ + +int cmp(const void *a, const void *b) +{ + return *(const int *)a - *(const int *)b; +} + +int *get_3sum(int a, int b, int c) +{ + int *arr = (int *)malloc(sizeof(int) * 3); + arr[0] = a; + arr[1] = b; + arr[2] = c; + return arr; +} + +int** threeSum(int* nums, int numsSize, int* returnSize) { + int **ret; + int count = 0; + int i,start,end; + int sum; + int alloc = numsSize; + + ret = (int **)malloc(sizeof(int *) * alloc); + + qsort(nums,numsSize,sizeof(int),cmp); + for(i = 0; i < numsSize - 2; ++i){ + if(i > 0 && nums[i] == nums[i-1]) + continue; + + start = i + 1; + end = numsSize - 1; + while(start < end){ + if(start > i + 1 && nums[start-1] == nums[start]){ + ++start; + continue; + } + + sum = nums[i] + nums[start] + nums[end]; + if(sum == 0){ + ret[count++] = get_3sum(nums[i],nums[start],nums[end]); + if(alloc == count){ + alloc <<= 1; + ret = realloc(ret,sizeof(int *) * alloc); + } + } + if(sum > 0) + --end; + else + ++start; + } + } + + *returnSize = count; + return ret; +} diff --git a/c/two-pointers/4sum.c b/c/two-pointers/4sum.c new file mode 100644 index 0000000..bcb614d --- /dev/null +++ b/c/two-pointers/4sum.c @@ -0,0 +1,66 @@ +/** + * Return an array of arrays of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int cmp(const void *a, const void *b) +{ + return *(const int *)a - *(const int *)b; +} + +int *get_4sum(int a,int b, int c, int d) +{ + int *arr = (int *)malloc(sizeof(int) * 4); + arr[0] = a; + arr[1] = b; + arr[2] = c; + arr[3] = d; + + return arr; +} + +int** fourSum(int* nums, int numsSize, int target, int* returnSize) { + int count = 0; + int i,j,start,end; + int **ret; + int alloc = numsSize; + int sum; + + ret = (int **)malloc(sizeof(int *) * alloc); + qsort(nums,numsSize,sizeof(int),cmp); + + for(i = 0; i < numsSize - 3; ++i){ + if(i > 0 && nums[i] == nums[i-1]) + continue; + + for(j = i + 1; j < numsSize - 2; ++j){ + if(j > i + 1 && nums[j] == nums[j-1]) + continue; + + start = j + 1; + end = numsSize - 1; + while(start < end){ + if(start > j + 1 && nums[start] == nums[start-1]){ + start++; + continue; + } + + sum = nums[i] + nums[j] + nums[start] + nums[end]; + if(sum == target){ + ret[count++] = get_4sum(nums[i],nums[j],nums[start],nums[end]); + if(count == alloc){ + alloc <<= 1; + ret = realloc(ret,sizeof(int *) * alloc); + } + } + + if(sum > target) + --end; + else + ++start; + } + } + } + + *returnSize = count; + return ret; +} diff --git a/c/two-pointers/container-with-most-water.c b/c/two-pointers/container-with-most-water.c new file mode 100644 index 0000000..57e1cd3 --- /dev/null +++ b/c/two-pointers/container-with-most-water.c @@ -0,0 +1,21 @@ +#define min(a,b) ((a) < (b) ? (a) : (b)) + +int maxArea(int* height, int heightSize) { + int start,end; + int ret = 0; + int mul; + + start = 0; + end = heightSize - 1; + while(start < end){ + mul = min(height[start],height[end]) * (end - start); + if(mul > ret) + ret = mul; + if(height[start] > height[end]) + --end; + else + ++start; + } + + return ret; +} diff --git a/c/two-pointers/implement-strstr.c b/c/two-pointers/implement-strstr.c new file mode 100644 index 0000000..ecc4908 --- /dev/null +++ b/c/two-pointers/implement-strstr.c @@ -0,0 +1,22 @@ +int strStr(char* haystack, char* needle) { + int step[256]; + int i,j; + int nd_len = strlen(needle); + int ht_len = strlen(haystack); + + for(i = 0; i < ht_len; ++i) + step[haystack[i]] = nd_len + 1; + + for(i = 0; i < nd_len; ++i) + step[needle[i]] = nd_len - i; + + for(i = 0; i <= ht_len - nd_len; i += step[haystack[i+nd_len]]){ + j = 0; + while(j < nd_len && haystack[j+i] == needle[j]) + ++j; + if(j == nd_len) + return i; + } + + return -1; +} diff --git a/c/two-pointers/linked-list-cycle-ii.c b/c/two-pointers/linked-list-cycle-ii.c new file mode 100644 index 0000000..786a9a0 --- /dev/null +++ b/c/two-pointers/linked-list-cycle-ii.c @@ -0,0 +1,27 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode *detectCycle(struct ListNode *head) { + struct ListNode *l1,*l2; + + l1 = head; + l2 = head; + do{ + if(!l1 || !l2 || !l2->next) + return NULL; + l2 = l2->next->next; + l1 = l1->next; + }while(l1 != l2); + + l1 = head; + while(l1 && l2 && l1 != l2){ + l1 = l1->next; + l2 = l2->next; + } + + return l1; +} diff --git a/c/two-pointers/linked-list-cycle.c b/c/two-pointers/linked-list-cycle.c new file mode 100644 index 0000000..4365b17 --- /dev/null +++ b/c/two-pointers/linked-list-cycle.c @@ -0,0 +1,20 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +bool hasCycle(struct ListNode *head) { + struct ListNode *slow = head; + struct ListNode *fast = head; + + while(fast && fast->next){ + fast = fast->next->next; + slow = slow->next; + if(fast == slow) + return true; + } + + return false; +} diff --git a/c/two-pointers/longest-substring-without-repeating-characters.c b/c/two-pointers/longest-substring-without-repeating-characters.c new file mode 100644 index 0000000..3e4f340 --- /dev/null +++ b/c/two-pointers/longest-substring-without-repeating-characters.c @@ -0,0 +1,28 @@ +int lengthOfLongestSubstring(char* s) { + int buf[256]; + int start,end; + int len; + int ret = 0; + int i; + memset(buf,0,sizeof(int) * 256); + + start = 0; + end = 0; + len = strlen(s); + + while(end < len){ + if(buf[s[end]] != 0){ + for(i = start; i < buf[s[end]]-1; ++i) + buf[s[i]] = 0; + start = buf[s[end]]; + } + + buf[s[end]] = end + 1; + if(end - start + 1 > ret) + ret = end - start + 1; + + end++; + } + + return ret; +} diff --git a/c/two-pointers/longest-substring-without-repeating-characters[1].c b/c/two-pointers/longest-substring-without-repeating-characters[1].c new file mode 100644 index 0000000..6e43f97 --- /dev/null +++ b/c/two-pointers/longest-substring-without-repeating-characters[1].c @@ -0,0 +1,17 @@ +int lengthOfLongestSubstring(char* s) { + int index[256]; + int last_pos = -1; + int i; + int ret = 0; + int len; + + memset(index,0,sizeof(int) * 256); + len = strlen(s); + for(i = 0; i < len; ++i){ + last_pos = index[s[i]] > last_pos ? index[s[i]] : last_pos; + index[s[i]] = i+1; + ret = (i - last_pos + 1) > ret ? (i - last_pos + 1) : ret; + } + + return ret; +} diff --git a/c/two-pointers/merge-sorted-array.c b/c/two-pointers/merge-sorted-array.c new file mode 100644 index 0000000..ba207d1 --- /dev/null +++ b/c/two-pointers/merge-sorted-array.c @@ -0,0 +1,16 @@ +void merge(int* nums1, int m, int* nums2, int n) { + int end = m + n - 1; + int i,j; + + i = m - 1; + j = n - 1; + while(i >= 0 && j >= 0){ + if(nums1[i] > nums2[j]) + nums1[end--] = nums1[i--]; + else + nums1[end--] = nums2[j--]; + } + + while(j >= 0) + nums1[end--] = nums2[j--]; +} diff --git a/c/two-pointers/minimum-size-subarray-sum.c b/c/two-pointers/minimum-size-subarray-sum.c new file mode 100644 index 0000000..aaaae50 --- /dev/null +++ b/c/two-pointers/minimum-size-subarray-sum.c @@ -0,0 +1,16 @@ +int minSubArrayLen(int s, int* nums, int numsSize) { + int ret = numsSize + 1; + int start = 0; + int end = 0; + int sum = 0; + + while(end < numsSize){ + sum += nums[end++]; + while(sum >= s){ + ret = (end - start) < ret ? (end - start) : ret; + sum -= nums[start++]; + } + } + + return ret == numsSize + 1 ? 0 : ret; +} diff --git a/c/two-pointers/palindrome-linked-list.c b/c/two-pointers/palindrome-linked-list.c new file mode 100644 index 0000000..56e5be8 --- /dev/null +++ b/c/two-pointers/palindrome-linked-list.c @@ -0,0 +1,58 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode* reverse(struct ListNode *head) +{ + struct ListNode root; + struct ListNode *tmp; + root.next = NULL; + while(head){ + tmp = head->next; + head->next = root.next; + root.next = head; + head = tmp; + } + + return root.next; +} + +bool isPalindrome(struct ListNode* head) { + int count = 0; + int i; + struct ListNode root; + struct ListNode *right; + struct ListNode *mid,*tmp; + + root.next = head; + while(head){ + count++; + head = head->next; + } + + head = &root; + i = 0; + while(i < ((count+1)/2)){ + head = head->next; + i++; + } + + mid = head; + right = reverse(head->next); + tmp = right; + head = root.next; + while(right){ + if(right->val != head->val){ + mid->next = reverse(tmp); + return false; + } + right = right->next; + head = head->next; + } + + mid->next = reverse(tmp); + return true; +} diff --git a/c/two-pointers/remove-duplicates-from-sorted-array-ii.c b/c/two-pointers/remove-duplicates-from-sorted-array-ii.c new file mode 100644 index 0000000..cd83f80 --- /dev/null +++ b/c/two-pointers/remove-duplicates-from-sorted-array-ii.c @@ -0,0 +1,10 @@ +int removeDuplicates(int* nums, int numsSize) { + int i,count; + + count = 1; + for(i = 2; i < numsSize; ++i) + if(nums[i] != nums[count-1]) + nums[++count] = nums[i]; + + return numsSize < 2 ? numsSize : count+1; +} diff --git a/c/two-pointers/remove-duplicates-from-sorted-array.c b/c/two-pointers/remove-duplicates-from-sorted-array.c new file mode 100644 index 0000000..36d98e7 --- /dev/null +++ b/c/two-pointers/remove-duplicates-from-sorted-array.c @@ -0,0 +1,12 @@ +int removeDuplicates(int* nums, int numsSize) { + int i,count = 0; + + if(numsSize == 0) + return 0; + + for(i = 0; i < numsSize; ++i) + if(nums[i] != nums[count]) + nums[++count] = nums[i]; + + return count+1; +} diff --git a/c/two-pointers/remove-element.c b/c/two-pointers/remove-element.c new file mode 100644 index 0000000..747598c --- /dev/null +++ b/c/two-pointers/remove-element.c @@ -0,0 +1,10 @@ +int removeElement(int* nums, int numsSize, int val) { + int count = -1; + int i; + + for(i = 0; i < numsSize; ++i) + if(nums[i] != val) + nums[++count] = nums[i]; + + return count+1; +} diff --git a/c/two-pointers/remove-nth-node-from-end-of-list.c b/c/two-pointers/remove-nth-node-from-end-of-list.c new file mode 100644 index 0000000..d3d247c --- /dev/null +++ b/c/two-pointers/remove-nth-node-from-end-of-list.c @@ -0,0 +1,28 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +struct ListNode* removeNthFromEnd(struct ListNode* head, int n) { + struct ListNode root; + struct ListNode *l1,*l2; + + root.next = head; + l1 = &root; + l2 = &root; + + while(n--){ + l2 = l2->next; + } + + while(l2->next){ + l1 = l1->next; + l2 = l2->next; + } + + l1->next = l1->next->next; + + return root.next; +} diff --git a/c/two-pointers/rotate-list.c b/c/two-pointers/rotate-list.c new file mode 100644 index 0000000..6dd6263 --- /dev/null +++ b/c/two-pointers/rotate-list.c @@ -0,0 +1,45 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +int list_count(struct ListNode *head) +{ + int count = 0; + + while(head){ + count++; + head = head->next; + } + + return count; +} + +struct ListNode* rotateRight(struct ListNode* head, int k) { + struct ListNode root; + struct ListNode *l1,*l2; + + root.next = head; + l1 = &root; + l2 = &root; + + if(head == NULL) + return NULL; + + k %= list_count(head); + while(k-- > 0) + l2 = l2->next; + + while(l2->next){ + l1 = l1->next; + l2 = l2->next; + } + + l2->next = root.next; + root.next = l1->next; + l1->next = NULL; + + return root.next; +} diff --git a/c/two-pointers/sort-colors.c b/c/two-pointers/sort-colors.c new file mode 100644 index 0000000..dbc69b1 --- /dev/null +++ b/c/two-pointers/sort-colors.c @@ -0,0 +1,18 @@ +void sortColors(int* nums, int numsSize) { + int i; + int zero,one,two; + + zero = one = two = 0; + for(i = 0; i < numsSize; ++i){ + if(nums[i] == 0){ + nums[two++] = nums[one]; + nums[one++] = nums[zero]; + nums[zero++] = 0; + }else if(nums[i] == 1){ + nums[two++] = nums[one]; + nums[one++] = 1; + }else{ + nums[two++] = 2; + } + } +} diff --git a/c/two-pointers/trapping-rain-water.c b/c/two-pointers/trapping-rain-water.c new file mode 100644 index 0000000..d4a90e7 --- /dev/null +++ b/c/two-pointers/trapping-rain-water.c @@ -0,0 +1,29 @@ +int trap(int* height, int heightSize) { + int max_height; + int max_index; + int i; + int sum = 0; + + max_height = 0; + for(i = 0; i < heightSize; ++i) + if(height[i] > max_height){ + max_index = i; + max_height = height[i]; + } + + max_height = 0; + for(i = 0; i < max_index; ++i){ + if(max_height > height[i]) + sum += (max_height - height[i]); + max_height = height[i] > max_height ? height[i] : max_height; + } + + max_height = 0; + for(i = heightSize - 1; i > max_index; --i){ + if(max_height > height[i]) + sum += (max_height - height[i]); + max_height = height[i] > max_height ? height[i] : max_height; + } + + return sum; +} diff --git a/c/two-pointers/valid-palindrome.c b/c/two-pointers/valid-palindrome.c new file mode 100644 index 0000000..6b8db57 --- /dev/null +++ b/c/two-pointers/valid-palindrome.c @@ -0,0 +1,36 @@ +int to_lower(int a) +{ + if(a >= 'A' && a <= 'Z') + return a + 32; + return a; +} + +int is_alpha(int a) +{ + return (a >= 'A' && a <= 'Z') || (a >= 'a' && a <= 'z') || + (a >= '0' && a <= '9'); +} + +bool isPalindrome(char* s) { + int i,j; + + i = 0; + j = strlen(s) - 1; + while(i < j){ + if(!is_alpha(s[i])){ + i++; + continue; + } + if(!is_alpha(s[j])){ + --j; + continue; + } + + if(to_lower(s[i]) != to_lower(s[j])) + return false; + ++i; + --j; + } + + return true; +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..a908aa9 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module leetcode + +go 1.18 diff --git a/go/alg/3sum/code.go b/go/alg/3sum/code.go new file mode 100644 index 0000000..974c195 --- /dev/null +++ b/go/alg/3sum/code.go @@ -0,0 +1,40 @@ +package sum + +import "sort" + +func threeSum(nums []int) [][]int { + sort.Ints(nums) + + arr := make([][]int, 0) + for i := 0; i < len(nums)-2; i++ { + if i > 0 && nums[i] == nums[i-1] { + continue + } + + if nums[i] > 0 || nums[i]+nums[i+1] > 0 { + break + } + + l := i + 1 + r := len(nums) - 1 + for l < r { + if l > i+1 && nums[l] == nums[l-1] { + l++ + continue + } + + sum := nums[i] + nums[l] + nums[r] + if sum > 0 { + r-- + } else if sum < 0 { + l++ + } else { + arr = append(arr, []int{nums[i], nums[l], nums[r]}) + l++ + r-- + } + } + } + + return arr +} diff --git a/go/alg/best_time_to_buy_and_sell_stock/code.go b/go/alg/best_time_to_buy_and_sell_stock/code.go new file mode 100644 index 0000000..c92fe5f --- /dev/null +++ b/go/alg/best_time_to_buy_and_sell_stock/code.go @@ -0,0 +1,17 @@ +package besttimetobuyandsellstock + +func maxProfit(prices []int) int { + minP := int(^uint(0) >> 1) + maxVal := 0 + for i := 0; i < len(prices); i++ { + if prices[i] < minP { + minP = prices[i] + } + + if prices[i]-minP > maxVal { + maxVal = prices[i] - minP + } + } + + return maxVal +} diff --git a/go/alg/binary_search/code.go b/go/alg/binary_search/code.go new file mode 100644 index 0000000..67adf29 --- /dev/null +++ b/go/alg/binary_search/code.go @@ -0,0 +1,19 @@ +package binarysearch + +func search(nums []int, target int) int { + l, r := 0, len(nums)-1 + for l <= r { + mid := l + (r-l)/2 + if nums[mid] == target { + return mid + } + + if nums[mid] > target { + r = mid - 1 + } else { + l = mid + 1 + } + } + + return -1 +} diff --git a/go/alg/bit/hamming_distance/code.go b/go/alg/bit/hamming_distance/code.go new file mode 100644 index 0000000..f055e43 --- /dev/null +++ b/go/alg/bit/hamming_distance/code.go @@ -0,0 +1,12 @@ +package hammingdistance + +func hammingDistance(x int, y int) int { + val := x ^ y + cnt := 0 + for val > 0 { + cnt += val & 0x1 + val >>= 1 + } + + return cnt +} diff --git a/go/alg/bit/hamming_distance/code_test.go b/go/alg/bit/hamming_distance/code_test.go new file mode 100644 index 0000000..1303533 --- /dev/null +++ b/go/alg/bit/hamming_distance/code_test.go @@ -0,0 +1,11 @@ +package hammingdistance + +import "testing" + +func TestHammingDistance(t *testing.T) { + cnt := hammingDistance(4, 1) + t.Logf("%d\n", cnt) //2 + + cnt = hammingDistance(3, 1) + t.Logf("%d\n", cnt) //1 +} diff --git a/go/alg/bit/integer_replacement/code.go b/go/alg/bit/integer_replacement/code.go new file mode 100644 index 0000000..4f96316 --- /dev/null +++ b/go/alg/bit/integer_replacement/code.go @@ -0,0 +1,21 @@ +package integer + +func min(a, b int) int { + if a > b { + return b + } + + return a +} + +func integerReplacement(n int) int { + if n == 1 { + return 0 + } + + if n%2 == 0 { + return 1 + integerReplacement(n/2) + } + + return 2 + min(integerReplacement((n+1)/2), integerReplacement((n-1)/2)) +} diff --git a/go/alg/bit/power_of_four/code.go b/go/alg/bit/power_of_four/code.go new file mode 100644 index 0000000..5057ce1 --- /dev/null +++ b/go/alg/bit/power_of_four/code.go @@ -0,0 +1,13 @@ +package poweroffour + +func isPowerOfFour(n int) bool { + if n <= 0 { + return false + } + + if n&(n-1) != 0 { + return false + } + + return n&0xaaaaaaaa == 0 +} diff --git a/go/alg/bit/power_of_four/code_test.go b/go/alg/bit/power_of_four/code_test.go new file mode 100644 index 0000000..678715c --- /dev/null +++ b/go/alg/bit/power_of_four/code_test.go @@ -0,0 +1,23 @@ +package poweroffour + +import ( + "testing" +) + +func TestIsPowerOfFour(t *testing.T) { + if isPowerOfFour(0) != false { + t.Fatal("test failed") + } + + if isPowerOfFour(16) != true { + t.Fatal("test failed") + } + + if isPowerOfFour(5) != false { + t.Fatal("test failed") + } + + if isPowerOfFour(1) != true { + t.Fatal("test failed") + } +} diff --git a/go/alg/climbing_stairs/code.go b/go/alg/climbing_stairs/code.go new file mode 100644 index 0000000..004940c --- /dev/null +++ b/go/alg/climbing_stairs/code.go @@ -0,0 +1,16 @@ +package climbingstairs + +func climbStairs(n int) int { + if n <= 1 { + return 1 + } + + dp := make([]int, n+1) + dp[1] = 1 + dp[2] = 2 + for i := 3; i <= n; i++ { + dp[i] = dp[i-1] + dp[i-2] + } + + return dp[n] +} diff --git a/go/alg/contains_duplicate_ii/code.go b/go/alg/contains_duplicate_ii/code.go new file mode 100644 index 0000000..d25c2b7 --- /dev/null +++ b/go/alg/contains_duplicate_ii/code.go @@ -0,0 +1,21 @@ +package containsduplicateii + +func containsNearbyDuplicate(nums []int, k int) bool { + flag := make(map[int]struct{}, k) + l := 0 + r := 0 + for r < len(nums) { + if _, ok := flag[nums[r]]; ok { + return true + } + flag[nums[r]] = struct{}{} + r++ + + if r-l > k { + delete(flag, nums[l]) + l++ + } + } + + return false +} diff --git a/go/alg/contains_duplicate_iii/code.go b/go/alg/contains_duplicate_iii/code.go new file mode 100644 index 0000000..d7224d4 --- /dev/null +++ b/go/alg/contains_duplicate_iii/code.go @@ -0,0 +1,44 @@ +package containsduplicateiii + +func abs(a, b int) int { + if a > b { + return a - b + } + return b - a +} + +func getKey(val, cnt int) int { + key := val / (cnt + 1) + if val < 0 { + key-- + } + + return key +} + +func containsNearbyAlmostDuplicate(nums []int, k int, t int) bool { + bucket := make(map[int]int, k) + + for idx, val := range nums { + key := getKey(val, t) + + if _, ok := bucket[key]; ok { + return true + } + + if _, ok := bucket[key-1]; ok && abs(bucket[key-1], val) <= t { + return true + } + + if _, ok := bucket[key+1]; ok && abs(bucket[key+1], val) <= t { + return true + } + + bucket[key] = val + if idx >= k { + delete(bucket, getKey(nums[idx-k], t)) + } + } + + return false +} diff --git a/go/alg/contains_duplicate_iii/code_test.go b/go/alg/contains_duplicate_iii/code_test.go new file mode 100644 index 0000000..6d58d1d --- /dev/null +++ b/go/alg/contains_duplicate_iii/code_test.go @@ -0,0 +1,11 @@ +package containsduplicateiii + +import "testing" + +func TestContainsNearbyAlmostDuplicate(t *testing.T) { + nums := []int{-3, 3, -6} + k := 2 + m := 3 + ok := containsNearbyAlmostDuplicate(nums, k, m) + t.Logf("%v\n", ok) +} diff --git a/go/alg/daily_temperatures/code.go b/go/alg/daily_temperatures/code.go new file mode 100644 index 0000000..070c8dd --- /dev/null +++ b/go/alg/daily_temperatures/code.go @@ -0,0 +1,24 @@ +package dailytemperatures + +func dailyTemperatures(temperatures []int) (arr []int) { + st := make([]int, len(temperatures)) + top := -1 + + arr = make([]int, len(temperatures)) + + for idx, val := range temperatures { + for top > -1 && val > temperatures[st[top]] { + arr[st[top]] = idx - st[top] + top-- + } + top++ + st[top] = idx + } + + for top > -1 { + arr[st[top]] = 0 + top-- + } + + return +} diff --git a/go/alg/edit_distance/code.go b/go/alg/edit_distance/code.go new file mode 100644 index 0000000..4d82e44 --- /dev/null +++ b/go/alg/edit_distance/code.go @@ -0,0 +1,38 @@ +package editdistance + +func min(a, b int) int { + if a < b { + return a + } + + return b +} + +func minDistance(word1 string, word2 string) int { + l1, l2 := len(word1), len(word2) + dp := make([][]int, l1+1) + for i := 0; i <= l1; i++ { + dp[i] = make([]int, l2+1) + } + + for i := 1; i <= l1; i++ { + dp[i][0] = i + } + + for j := 1; j <= l2; j++ { + dp[0][j] = j + } + + for i := 1; i <= l1; i++ { + for j := 1; j <= l2; j++ { + val := dp[i-1][j-1] + if word1[i-1] != word2[j-1] { + val += 1 + } + + dp[i][j] = min(val, min(dp[i-1][j], dp[i][j-1])+1) + } + } + + return dp[l1][l2] +} diff --git a/go/alg/generate_parentheses/code.go b/go/alg/generate_parentheses/code.go new file mode 100644 index 0000000..b7310e5 --- /dev/null +++ b/go/alg/generate_parentheses/code.go @@ -0,0 +1,27 @@ +package generateparentheses + +func generateParenthesis(n int) (arr []string) { + if n == 0 { + return + } + + set := make(map[string]struct{}) + set["()"] = struct{}{} + + for i := 2; i <= n; i++ { + newSet := make(map[string]struct{}) + for str := range set { + for i := 0; i <= len(str); i++ { + newStr := str[:i] + "()" + str[i:] + newSet[newStr] = struct{}{} + } + } + set = newSet + } + + for str := range set { + arr = append(arr, str) + } + + return arr +} diff --git a/go/alg/kth_largest_element_in_an_array/code.go b/go/alg/kth_largest_element_in_an_array/code.go new file mode 100644 index 0000000..6f3019c --- /dev/null +++ b/go/alg/kth_largest_element_in_an_array/code.go @@ -0,0 +1,42 @@ +package main + +import ( + "math/rand" + "time" +) + +func partiton(nums []int, start, end int) int { + idx := rand.Intn(end-start+1) + start + nums[idx], nums[start] = nums[start], nums[idx] + target := nums[start] + + idx = start + 1 + for i := idx; i <= end; i++ { + if nums[i] < target { + nums[i], nums[idx] = nums[idx], nums[i] + idx++ + } + } + + idx-- + nums[idx], nums[start] = nums[start], nums[idx] + return idx +} + +func quickSelect(nums []int, start, end, k int) int { + idx := partiton(nums, start, end) + if idx == k { + return nums[idx] + } + + if idx > k { + return quickSelect(nums, start, idx, k) + } + + return quickSelect(nums, idx+1, end, k) +} + +func findKthLargest(nums []int, k int) int { + rand.Seed(time.Now().UnixNano()) + return quickSelect(nums, 0, len(nums)-1, len(nums)-k) +} diff --git a/go/alg/kth_largest_element_in_an_array/code_test.go b/go/alg/kth_largest_element_in_an_array/code_test.go new file mode 100644 index 0000000..73568f4 --- /dev/null +++ b/go/alg/kth_largest_element_in_an_array/code_test.go @@ -0,0 +1,20 @@ +package main + +import "testing" + +func TestFindKthLargest(t *testing.T) { + // nums := []int{3, 2, 1, 5, 6, 4} + // k := 2 + // val := findKthLargest(nums, k) + // t.Logf("%d", val) //5 + + nums := []int{3, 1, 2, 4} + k := 2 + val := findKthLargest(nums, k) + t.Logf("%d", val) //3 + + // nums := []int{3, 2, 3, 1, 2, 4, 5, 5, 6} + // k := 4 + // val := findKthLargest(nums, k) + // t.Logf("%d", val) //4 +} diff --git a/go/alg/kth_largest_element_in_an_array/kth_largest_element_in_an_array.exe b/go/alg/kth_largest_element_in_an_array/kth_largest_element_in_an_array.exe new file mode 100644 index 0000000..6e910c5 Binary files /dev/null and b/go/alg/kth_largest_element_in_an_array/kth_largest_element_in_an_array.exe differ diff --git a/go/alg/kth_largest_element_in_an_array/main.go b/go/alg/kth_largest_element_in_an_array/main.go new file mode 100644 index 0000000..594f091 --- /dev/null +++ b/go/alg/kth_largest_element_in_an_array/main.go @@ -0,0 +1,10 @@ +package main + +import "fmt" + +func main() { + nums := []int{3, 2, 3, 1, 2, 4, 5, 5, 6} + k := 4 + val := findKthLargest(nums, k) + fmt.Printf("%d\n", val) //4 +} diff --git a/go/alg/largest_number/code.go b/go/alg/largest_number/code.go new file mode 100644 index 0000000..be6a1c6 --- /dev/null +++ b/go/alg/largest_number/code.go @@ -0,0 +1,33 @@ +package largestnumber + +import ( + "sort" + "strconv" +) + +type IntSlice []int + +func (s IntSlice) Len() int { + return len(s) +} + +func (s IntSlice) Less(i, j int) bool { + si := strconv.Itoa(s[i]) + sj := strconv.Itoa(s[j]) + + return si+sj > sj+si +} + +func (s IntSlice) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func largestNumber(nums []int) string { + sort.Sort(IntSlice(nums)) + s := "" + for _, val := range nums { + s += strconv.Itoa(val) + } + + return s +} diff --git a/go/alg/largest_number/code_test.go b/go/alg/largest_number/code_test.go new file mode 100644 index 0000000..221d985 --- /dev/null +++ b/go/alg/largest_number/code_test.go @@ -0,0 +1,11 @@ +package largestnumber + +import "testing" + +func TestLargestNumber(t *testing.T) { + // nums := []int{10, 2} + // t.Logf("%s", largestNumber(nums)) + + nums := []int{3, 30} + t.Logf("%s", largestNumber(nums)) +} diff --git a/go/alg/largest_number/next_permutation/code.go b/go/alg/largest_number/next_permutation/code.go new file mode 100644 index 0000000..b9f011d --- /dev/null +++ b/go/alg/largest_number/next_permutation/code.go @@ -0,0 +1,34 @@ +package nextpermutation + +func reverse(nums []int, i, j int) { + for i < j { + nums[i], nums[j] = nums[j], nums[i] + i++ + j-- + } +} + +func nextPermutation(nums []int) { + idx := len(nums) - 1 + + for ; idx > 0; idx-- { + if nums[idx-1] < nums[idx] { + break + } + } + + if idx <= 0 { + reverse(nums, 0, len(nums)-1) + return + } + + for i := len(nums) - 1; i >= idx; i-- { + if nums[i] > nums[idx-1] { + nums[idx-1], nums[i] = nums[i], nums[idx-1] + break + } + } + + reverse(nums, idx, len(nums)-1) + return +} diff --git a/go/alg/largest_number/next_permutation/code_test.go b/go/alg/largest_number/next_permutation/code_test.go new file mode 100644 index 0000000..081069d --- /dev/null +++ b/go/alg/largest_number/next_permutation/code_test.go @@ -0,0 +1,9 @@ +package nextpermutation + +import "testing" + +func TestNextPermutation(t *testing.T) { + nums := []int{1, 3, 2} + nextPermutation(nums) + t.Logf("%v", nums) +} diff --git a/go/alg/lfu_cache/code.go b/go/alg/lfu_cache/code.go new file mode 100644 index 0000000..4a38ffc --- /dev/null +++ b/go/alg/lfu_cache/code.go @@ -0,0 +1,131 @@ +package lfucache + +import ( + "container/list" + "math" +) + +type node struct { + key int + val int + freq int +} + +type LFUCache struct { + freqs map[int]*list.List + nodes map[int]*list.Element + cap int + minFreq int +} + +func Constructor(capacity int) LFUCache { + return LFUCache{ + freqs: make(map[int]*list.List), + nodes: make(map[int]*list.Element), + cap: capacity, + minFreq: math.MaxInt, + } +} + +func (this *LFUCache) Get(key int) int { + if this.cap == 0 { + return -1 + } + + elem := this.nodes[key] + if elem == nil { + return -1 + } + + nod := elem.Value.(*node) + this.removeElem(elem) + nod.freq++ + elem = this.addToFreqs(nod) + this.addToNodes(elem) + return nod.val +} + +func (this *LFUCache) addToFreqs(nod *node) *list.Element { + lst := this.freqs[nod.freq] + if lst == nil { + lst = list.New() + this.freqs[nod.freq] = lst + } + + return lst.PushFront(nod) +} + +func (this *LFUCache) erase() { + lst := this.freqs[this.minFreq] + if lst == nil { + return + } + + elem := lst.Back() + key := elem.Value.(*node).key + this.removeElem(elem) + this.nodes[key] = nil + delete(this.nodes, key) +} + +func (this *LFUCache) removeElem(elem *list.Element) { + nod := elem.Value.(*node) + this.freqs[nod.freq].Remove(elem) + if this.freqs[nod.freq].Len() == 0 { + this.freqs[nod.freq] = nil + delete(this.freqs, nod.freq) + if nod.freq == this.minFreq { + this.minFreq = math.MaxInt + } + } + + return +} + +func (this *LFUCache) addToNodes(elem *list.Element) { + nod := elem.Value.(*node) + this.nodes[nod.key] = elem + if nod.freq < this.minFreq { + this.minFreq = nod.freq + } + + return +} + +func (this *LFUCache) Put(key int, value int) { + if this.cap == 0 { + return + } + + elem := this.nodes[key] + if elem == nil { + if len(this.nodes) >= this.cap { + this.erase() + } + nod := &node{ + key: key, + val: value, + freq: 1, + } + elem = this.addToFreqs(nod) + this.addToNodes(elem) + return + } + + this.removeElem(elem) + + nod := elem.Value.(*node) + nod.freq++ + nod.val = value + elem = this.addToFreqs(nod) + this.addToNodes(elem) + + return +} + +/** + * Your LFUCache object will be instantiated and called as such: + * obj := Constructor(capacity); + * param_1 := obj.Get(key); + * obj.Put(key,value); + */ diff --git a/go/alg/lfu_cache/code_test.go b/go/alg/lfu_cache/code_test.go new file mode 100644 index 0000000..5405d2e --- /dev/null +++ b/go/alg/lfu_cache/code_test.go @@ -0,0 +1,50 @@ +package lfucache + +import "testing" + +func TestLFUCache(t *testing.T) { + lfu := Constructor(2) + lfu.Put(1, 1) // cache=[1,_], cnt(1)=1 + lfu.Put(2, 2) // cache=[2,1], cnt(2)=1, cnt(1)=1 + + t.Log(lfu.Get(1)) // 返回 1 + // cache=[1,2], cnt(2)=1, cnt(1)=2 + + lfu.Put(3, 3) // 去除键 2 ,因为 cnt(2)=1 ,使用计数最小 + // cache=[3,1], cnt(3)=1, cnt(1)=2 + + t.Log(lfu.Get(2)) // 返回 -1(未找到) + + t.Log(lfu.Get(3)) // 返回 3 + // cache=[3,1], cnt(3)=2, cnt(1)=2 + + lfu.Put(4, 4) // 去除键 1 ,1 和 3 的 cnt 相同,但 1 最久未使用 + // cache=[4,3], cnt(4)=1, cnt(3)=2 + + t.Log(lfu.Get(1)) // 返回 -1(未找到) + + t.Log(lfu.Get(3)) // 返回 3 + // cache=[3,4], cnt(4)=1, cnt(3)=3 + + t.Log(lfu.Get(4)) // 返回 4 + // cache=[3,4], cnt(4)=2, cnt(3)=3 + +} + +func TestLFUCache1(t *testing.T) { + lfu := Constructor(3) + lfu.Put(2, 2) + lfu.Put(1, 1) + + t.Log(lfu.Get(2)) //2 + t.Log(lfu.Get(1)) //1 + t.Log(lfu.Get(2)) //2 + + lfu.Put(3, 3) + lfu.Put(4, 4) + + t.Log(lfu.Get(3)) //-1 + t.Log(lfu.Get(2)) //2 + t.Log(lfu.Get(1)) //1 + t.Log(lfu.Get(4)) //4 +} diff --git a/go/alg/longest_increasing_subsequence/code.go b/go/alg/longest_increasing_subsequence/code.go new file mode 100644 index 0000000..5f4a631 --- /dev/null +++ b/go/alg/longest_increasing_subsequence/code.go @@ -0,0 +1,29 @@ +package longest + +func max(a, b int) int { + if a > b { + return a + } + + return b +} + +func lengthOfLIS(nums []int) int { + if len(nums) == 0 { + return 0 + } + + dp := make([]int, len(nums)) + maxLen := 0 + for i, val := range nums { + dp[i] = 1 + for j := 0; j <= i-1; j++ { + if val > nums[j] { + dp[i] = max(dp[i], dp[j]+1) + } + } + maxLen = max(maxLen, dp[i]) + } + + return maxLen +} diff --git a/go/alg/longest_substring_least_k_repeating_characters/code.go b/go/alg/longest_substring_least_k_repeating_characters/code.go new file mode 100644 index 0000000..cecb98b --- /dev/null +++ b/go/alg/longest_substring_least_k_repeating_characters/code.go @@ -0,0 +1,41 @@ +package longestsubstringleastkrepeatingcharacters + +import "strings" + +func longestSubstring(s string, k int) (cnt int) { + if s == "" { + return + } + + ch := [26]int{} + + for _, c := range s { + ch[c-'a']++ + } + + split := byte(0) + for i, v := range ch { + if 0 < v && v < k { + split = 'a' + byte(i) + break + } + } + + if split == 0 { + return len(s) + } + + for _, substr := range strings.Split(s, string(split)) { + cnt = max(cnt, longestSubstring(substr, k)) + } + + return +} + +func max(a, b int) int { + if a > b { + return a + } + + return b +} diff --git a/go/alg/longest_substring_without_repeating_characters/code.go b/go/alg/longest_substring_without_repeating_characters/code.go new file mode 100644 index 0000000..a4c1b69 --- /dev/null +++ b/go/alg/longest_substring_without_repeating_characters/code.go @@ -0,0 +1,24 @@ +package longest_substring + +func lengthOfLongestSubstring(s string) int { + flag := make(map[byte]struct{}) + start, end := 0, 0 + maxSub := 0 + for start < len(s) { + for end < len(s) { + if _, ok := flag[s[end]]; ok { + break + } + flag[s[end]] = struct{}{} + if end-start+1 > maxSub { + maxSub = end - start + 1 + } + end++ + } + + delete(flag, s[start]) + start++ + } + + return maxSub +} diff --git a/go/alg/longest_substring_without_repeating_characters/code1.go b/go/alg/longest_substring_without_repeating_characters/code1.go new file mode 100644 index 0000000..6accdd0 --- /dev/null +++ b/go/alg/longest_substring_without_repeating_characters/code1.go @@ -0,0 +1,24 @@ +package longest_substring + +func lengthOfLongestSubstring1(s string) int { + var index [256]int + for i := 0; i < len(index); i++ { + index[i] = -1 + } + + lastIndex := -1 + maxSub := 0 + for i := 0; i < len(s); i++ { + ch := int(s[i]) + if index[ch] >= lastIndex { + lastIndex = index[ch] + 1 + } + + index[ch] = i + if i-lastIndex+1 > maxSub { + maxSub = i - lastIndex + 1 + } + } + + return maxSub +} diff --git a/go/alg/longest_substring_without_repeating_characters/code1_test.go b/go/alg/longest_substring_without_repeating_characters/code1_test.go new file mode 100644 index 0000000..7ccf1ea --- /dev/null +++ b/go/alg/longest_substring_without_repeating_characters/code1_test.go @@ -0,0 +1,9 @@ +package longest_substring + +import "testing" + +func TestLengthOfLongestSubstring1(t *testing.T) { + s := "abcabcbb" + + t.Log(lengthOfLongestSubstring1(s)) +} diff --git a/go/alg/lru_cache/code.go b/go/alg/lru_cache/code.go new file mode 100644 index 0000000..da72d9e --- /dev/null +++ b/go/alg/lru_cache/code.go @@ -0,0 +1,47 @@ +package lrucache + +import "container/list" + +type node struct { + key int + val int +} + +type LRUCache struct { + *list.List + MData map[int]*list.Element + cap int +} + +func Constructor(capacity int) LRUCache { + return LRUCache{ + cap: capacity, + List: list.New(), + MData: make(map[int]*list.Element), + } +} + +func (this *LRUCache) Get(key int) int { + elem := this.MData[key] + if elem == nil { + return -1 + } + + this.MoveToFront(elem) + node := elem.Value.(node) + return node.val +} + +func (this *LRUCache) Put(key int, value int) { + elem := this.MData[key] + if elem != nil { + this.Remove(elem) + } else if len(this.MData) >= this.cap { + de := this.Back() + node := de.Value.(node) + delete(this.MData, node.key) + this.Remove(de) + } + elem = this.PushFront(node{key, value}) + this.MData[key] = elem +} diff --git a/go/alg/lru_cache/code_test.go b/go/alg/lru_cache/code_test.go new file mode 100644 index 0000000..50b57b2 --- /dev/null +++ b/go/alg/lru_cache/code_test.go @@ -0,0 +1,17 @@ +package lrucache + +import "testing" + +func TestLRUCache(t *testing.T) { + lru := Constructor(2) + lru.Put(1, 1) // 缓存是 {1=1} + lru.Put(2, 2) // 缓存是 {1=1, 2=2} + t.Log(lru.Get(1)) // 返回 1 + lru.Put(3, 3) // 该操作会使得关键字 2 作废,缓存是 {1=1, 3=3} + t.Log(lru.Get(2)) // 返回 -1 (未找到) + lru.Put(4, 4) // 该操作会使得关键字 1 作废,缓存是 {4=4, 3=3} + t.Log(lru.Get(1)) // 返回 -1 (未找到) + t.Log(lru.Get(3)) // 返回 3 + t.Log(lru.Get(4)) // 返回 4 + +} diff --git a/go/alg/maximum_length_of_repeated_subarray/code.go b/go/alg/maximum_length_of_repeated_subarray/code.go new file mode 100644 index 0000000..8e24eff --- /dev/null +++ b/go/alg/maximum_length_of_repeated_subarray/code.go @@ -0,0 +1,35 @@ +package maximum + +func max1(a, b int) int { + if a > b { + return a + } + + return b +} + +func findLength1(nums1 []int, nums2 []int) int { + ret := 0 + + m := len(nums1) + n := len(nums2) + + dp := make([][]int, m+1) + for i := 0; i <= m; i++ { + dp[i] = make([]int, n+1) + } + + for i := m - 1; i >= 0; i-- { + for j := n - 1; j >= 0; j-- { + if nums1[i] == nums2[j] { + dp[i][j] = dp[i+1][j+1] + 1 + ret = max1(ret, dp[i][j]) + } else { + dp[i][j] = 0 + } + + } + } + + return ret +} diff --git a/go/alg/maximum_length_of_repeated_subarray/code1.go b/go/alg/maximum_length_of_repeated_subarray/code1.go new file mode 100644 index 0000000..33b736a --- /dev/null +++ b/go/alg/maximum_length_of_repeated_subarray/code1.go @@ -0,0 +1,48 @@ +package maximum + +func max(a, b int) int { + if a > b { + return a + } + + return b +} + +func min(a, b int) int { + if a < b { + return a + } + + return b +} + +func maxLength(nums1, nums2 []int, add1, add2, ln int) int { + cnt := 0 + maxCnt := 0 + for i := 0; i < ln; i++ { + if nums1[add1+i] != nums2[add2+i] { + cnt = 0 + } else { + cnt++ + maxCnt = max(maxCnt, cnt) + } + } + + return maxCnt +} + +func findLength(nums1 []int, nums2 []int) int { + m, n := len(nums1), len(nums2) + maxLen := 0 + for i := 0; i < m; i++ { + ln := min(m-i, n) + maxLen = max(maxLen, maxLength(nums1, nums2, i, 0, ln)) + } + + for i := 0; i < n; i++ { + ln := min(n-i, m) + maxLen = max(maxLen, maxLength(nums1, nums2, 0, i, ln)) + } + + return maxLen +} diff --git a/go/alg/maximum_subarray/code.go b/go/alg/maximum_subarray/code.go new file mode 100644 index 0000000..b4e2964 --- /dev/null +++ b/go/alg/maximum_subarray/code.go @@ -0,0 +1,26 @@ +package maximumsubarray + +import "math" + +func max(a, b int) int { + if a > b { + return a + } + + return b +} + +func maxSubArray(nums []int) int { + maxSum := math.MinInt + + sum := 0 + for _, val := range nums { + sum += val + maxSum = max(maxSum, sum) + if sum < 0 { + sum = 0 + } + } + + return maxSum +} diff --git a/go/alg/maximum_subarray/code_test.go b/go/alg/maximum_subarray/code_test.go new file mode 100644 index 0000000..1b48bb0 --- /dev/null +++ b/go/alg/maximum_subarray/code_test.go @@ -0,0 +1,10 @@ +package maximumsubarray + +import "testing" + +func TestMaxSubArray(t *testing.T) { + nums := []int{-2, 1, -3, 4, -1, 2, 1, -5, 4} + if maxSubArray(nums) != 6 { + t.Fatalf("test failed") + } +} diff --git a/go/alg/merge_intervals/code.go b/go/alg/merge_intervals/code.go new file mode 100644 index 0000000..9974f1f --- /dev/null +++ b/go/alg/merge_intervals/code.go @@ -0,0 +1,40 @@ +package mergeintervals + +import "sort" + +type intSet [][]int + +func (s intSet) Len() int { + return len(s) +} + +func (s intSet) Less(i, j int) bool { + return s[i][0] < s[j][0] +} + +func (s intSet) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func merge(intervals [][]int) (result [][]int) { + if len(intervals) == 0 { + return + } + sort.Sort(intSet(intervals)) + result = append(result, intervals[0]) + + idx := 0 + for i := 1; i < len(intervals); i++ { + arr := intervals[i] + if result[idx][1] >= arr[0] { + if arr[1] > result[idx][1] { + result[idx][1] = arr[1] + } + } else { + idx++ + result = append(result, arr) + } + } + + return +} diff --git a/go/alg/minimum_size_subarray_sum/code.go b/go/alg/minimum_size_subarray_sum/code.go new file mode 100644 index 0000000..791323c --- /dev/null +++ b/go/alg/minimum_size_subarray_sum/code.go @@ -0,0 +1,26 @@ +package minimumsizesubarraysum + +func minSubArrayLen(target int, nums []int) int { + start, end := 0, 0 + sum := 0 + minSub := len(nums) + 1 + for end < len(nums) { + sum += nums[end] + + for start <= end && sum >= target { + if sum >= target && end-start+1 < minSub { + minSub = end - start + 1 + } + sum -= nums[start] + start++ + } + + end++ + } + + if minSub <= len(nums) { + return minSub + } + + return 0 +} diff --git a/go/alg/minimum_size_subarray_sum/code_test.go b/go/alg/minimum_size_subarray_sum/code_test.go new file mode 100644 index 0000000..f83cca2 --- /dev/null +++ b/go/alg/minimum_size_subarray_sum/code_test.go @@ -0,0 +1,10 @@ +package minimumsizesubarraysum + +import "testing" + +func TestMinSubArrayLen(t *testing.T) { + nums := []int{2, 3, 1, 2, 4, 3} + sub := minSubArrayLen(7, nums) + + t.Logf("%d", sub) +} diff --git a/go/alg/next_greater_element_i/code.go b/go/alg/next_greater_element_i/code.go new file mode 100644 index 0000000..96b18ca --- /dev/null +++ b/go/alg/next_greater_element_i/code.go @@ -0,0 +1,27 @@ +package nextgreaterelementi + +func nextGreaterElement(nums1 []int, nums2 []int) []int { + valMap := make(map[int]int) + st := make([]int, len(nums2)) + top := -1 + + for _, val := range nums2 { + for top > -1 && val > st[top] { + valMap[st[top]] = val + top-- + } + top++ + st[top] = val + } + + for i := 0; i <= top; i++ { + valMap[st[i]] = -1 + } + + arr := make([]int, len(nums1)) + for idx, val := range nums1 { + arr[idx] = valMap[val] + } + + return arr +} diff --git a/go/alg/palindrome_number/code.go b/go/alg/palindrome_number/code.go new file mode 100644 index 0000000..19024c4 --- /dev/null +++ b/go/alg/palindrome_number/code.go @@ -0,0 +1,17 @@ +package palindrome_number + +func isPalindrome(x int) bool { + if x < 0 { + return false + } + + tmp := x + val := 0 + for tmp > 0 { + remain := tmp % 10 + tmp /= 10 + val = val*10 + remain + } + + return val == x +} diff --git a/go/alg/permutation_in_string/code.go b/go/alg/permutation_in_string/code.go new file mode 100644 index 0000000..42cbcd9 --- /dev/null +++ b/go/alg/permutation_in_string/code.go @@ -0,0 +1,28 @@ +package permutationinstring + +func checkInclusion(s1 string, s2 string) bool { + if len(s2) < len(s1) { + return false + } + + cnt1 := [26]int{} + cnt2 := [26]int{} + for i, v := range s1 { + cnt1[v-'a']++ + cnt2[s2[i]-'a']++ + } + + if cnt1 == cnt2 { + return true + } + + for i := len(s1); i < len(s2); i++ { + cnt2[s2[i]-'a']++ + cnt2[s2[i-len(s1)]-'a']-- + if cnt1 == cnt2 { + return true + } + } + + return false +} diff --git a/go/alg/permutation_in_string/code_test.go b/go/alg/permutation_in_string/code_test.go new file mode 100644 index 0000000..bdb67af --- /dev/null +++ b/go/alg/permutation_in_string/code_test.go @@ -0,0 +1,10 @@ +package permutationinstring + +import "testing" + +func TestCheckInclusion(t *testing.T) { + s1 := "adc" + s2 := "dcda" + ok := checkInclusion(s1, s2) + t.Logf("%v", ok) +} diff --git a/go/alg/permutations/code.go b/go/alg/permutations/code.go new file mode 100644 index 0000000..034a3b4 --- /dev/null +++ b/go/alg/permutations/code.go @@ -0,0 +1,28 @@ +package permutations + +func permute(nums []int) [][]int { + arrList := make([][]int, 0) + process(nums, 0, &arrList) + return arrList +} + +func swap(nums []int, i, j int) { + nums[i], nums[j] = nums[j], nums[i] +} + +func process(nums []int, i int, arrList *[][]int) { + if i == len(nums)-1 { + newNums := make([]int, len(nums)) + copy(newNums, nums) + *arrList = append(*arrList, newNums) + return + } + + for j := i; j < len(nums); j++ { + swap(nums, i, j) + + process(nums, i+1, arrList) + + swap(nums, i, j) + } +} diff --git a/go/alg/permutations/code_test.go b/go/alg/permutations/code_test.go new file mode 100644 index 0000000..9eb619d --- /dev/null +++ b/go/alg/permutations/code_test.go @@ -0,0 +1,9 @@ +package permutations + +import "testing" + +func TestPermute(t *testing.T) { + nums := []int{1, 2, 3} + arrList := permute(nums) + t.Logf("%v", arrList) +} diff --git a/go/alg/permutations_ii/code.go b/go/alg/permutations_ii/code.go new file mode 100644 index 0000000..827d13c --- /dev/null +++ b/go/alg/permutations_ii/code.go @@ -0,0 +1,33 @@ +package permutationii + +func permuteUnique(nums []int) [][]int { + arrList := make([][]int, 0) + + process(nums, 0, &arrList) + return arrList +} + +func swap(nums []int, i, j int) { + nums[i], nums[j] = nums[j], nums[i] +} + +func process(nums []int, i int, arrList *[][]int) { + if i == len(nums)-1 { + newNums := make([]int, len(nums)) + copy(newNums, nums) + *arrList = append(*arrList, newNums) + return + } + + flag := make(map[int]struct{}) + for j := i; j < len(nums); j++ { + if _, ok := flag[nums[j]]; ok { + continue + } + + flag[nums[j]] = struct{}{} + swap(nums, i, j) + process(nums, i+1, arrList) + swap(nums, i, j) + } +} diff --git a/go/alg/permutations_ii/code_test.go b/go/alg/permutations_ii/code_test.go new file mode 100644 index 0000000..3330bbe --- /dev/null +++ b/go/alg/permutations_ii/code_test.go @@ -0,0 +1,15 @@ +package permutationii + +import "testing" + +func TestPermuteUnique(t *testing.T) { + nums := []int{2, 1, 1, 2} + arrList := permuteUnique(nums) + + t.Logf("%v", arrList) + + nums = []int{1, 2, 3} + arrList = permuteUnique(nums) + + t.Logf("%v", arrList) +} diff --git a/go/alg/regular_expression_matching/code.go b/go/alg/regular_expression_matching/code.go new file mode 100644 index 0000000..1883312 --- /dev/null +++ b/go/alg/regular_expression_matching/code.go @@ -0,0 +1,38 @@ +package wildcardmatregularexpressionmatchingching + +func isMatch(s string, p string) bool { + m, n := len(s), len(p) + dp := make([][]bool, m+1) + for i := 0; i < len(dp); i++ { + dp[i] = make([]bool, n+1) + } + + dp[0][0] = true + for j := 2; j <= n; j++ { + if p[j-1] == '*' { + dp[0][j] = dp[0][j-2] + } + } + + for i := 1; i <= m; i++ { + for j := 1; j <= n; j++ { + if p[j-1] == '*' { + if j >= 2 && (p[j-2] == '.' || p[j-2] == s[i-1]) { + dp[i][j] = dp[i-1][j] || dp[i][j-2] + } else { + if j >= 2 { + dp[i][j] = dp[i][j-2] + } else { + dp[i][j] = false + } + } + } else if p[j-1] == '.' || p[j-1] == s[i-1] { + dp[i][j] = dp[i-1][j-1] + } else { + dp[i][j] = false + } + } + } + + return dp[m][n] +} diff --git a/go/alg/regular_expression_matching/code_test.go b/go/alg/regular_expression_matching/code_test.go new file mode 100644 index 0000000..e20428f --- /dev/null +++ b/go/alg/regular_expression_matching/code_test.go @@ -0,0 +1,11 @@ +package wildcardmatregularexpressionmatchingching + +import "testing" + +func TestIsMatch(t *testing.T) { + s := "aa" + p := ".*" + + ok := isMatch(s, p) + t.Logf("%v\n", ok) +} diff --git a/go/alg/remove_k_digits/code.go b/go/alg/remove_k_digits/code.go new file mode 100644 index 0000000..79c97e7 --- /dev/null +++ b/go/alg/remove_k_digits/code.go @@ -0,0 +1,25 @@ +package removekdigits + +import "strings" + +func removeKdigits(num string, k int) string { + st := make([]byte, len(num)) + top := -1 + + for i := 0; i < len(num); i++ { + for k > 0 && top > -1 && num[i] < st[top] { + k-- + top-- + } + top++ + st[top] = num[i] + } + + st = st[:top-k+1] + s := strings.TrimLeft(string(st), "0") + if s == "" { + s = "0" + } + + return s +} diff --git a/go/alg/remove_k_digits/code_test.go b/go/alg/remove_k_digits/code_test.go new file mode 100644 index 0000000..7ef280c --- /dev/null +++ b/go/alg/remove_k_digits/code_test.go @@ -0,0 +1,19 @@ +package removekdigits + +import ( + "testing" +) + +func TestNum(t *testing.T) { + num := "1432219" + k := 3 + t.Logf("%s", removeKdigits(num, k)) //1219 + + num = "10200" + k = 1 + t.Logf("%s", removeKdigits(num, k)) //200 + + num = "10" + k = 2 + t.Logf("%s", removeKdigits(num, k)) //0 +} diff --git a/go/alg/search_in_rotated_sorted_array/code.go b/go/alg/search_in_rotated_sorted_array/code.go new file mode 100644 index 0000000..793ed46 --- /dev/null +++ b/go/alg/search_in_rotated_sorted_array/code.go @@ -0,0 +1,28 @@ +package searchinrotatedsortedarray + +func search(nums []int, target int) int { + l, r := 0, len(nums)-1 + for l <= r { + mid := l + (r-l)/2 + if nums[mid] == target { + return mid + } + + if nums[mid] > target { + if nums[l] <= target || nums[l] > nums[mid] { + r = mid - 1 + } else { + l = mid + 1 + } + } else { + if nums[r] >= target || nums[r] < nums[mid] { + l = mid + 1 + } else { + r = mid - 1 + } + + } + } + + return -1 +} diff --git a/go/alg/search_in_rotated_sorted_array/code_test.go b/go/alg/search_in_rotated_sorted_array/code_test.go new file mode 100644 index 0000000..1e9f2a3 --- /dev/null +++ b/go/alg/search_in_rotated_sorted_array/code_test.go @@ -0,0 +1,17 @@ +package searchinrotatedsortedarray + +import "testing" + +func TestSearch(t *testing.T) { + nums := []int{4, 5, 6, 7, 8, 1, 2, 3} + target := 8 + if search(nums, target) != 4 { + t.Fatal("test failed") + } + + nums = []int{1, 2, 3, 4} + target = 3 + if search(nums, target) != 2 { + t.Fatal("test failed") + } +} diff --git a/go/alg/shortest_unsorted_continuous_subarray/code.go b/go/alg/shortest_unsorted_continuous_subarray/code.go new file mode 100644 index 0000000..1b3c414 --- /dev/null +++ b/go/alg/shortest_unsorted_continuous_subarray/code.go @@ -0,0 +1,39 @@ +package shortestunsortedcontinuoussubarray + +func findUnsortedSubarray(nums []int) int { + st := make([]int, len(nums)) + top := -1 + + left := len(nums) + + for idx, val := range nums { + for top > -1 && val < nums[st[top]] { + if st[top] < left { + left = st[top] + } + top-- + } + top++ + st[top] = idx + } + + right := -1 + top = -1 + + for idx := len(nums) - 1; idx >= 0; idx-- { + for top > -1 && nums[idx] > nums[st[top]] { + if st[top] > right { + right = st[top] + } + top-- + } + top++ + st[top] = idx + } + + if right == -1 { + return 0 + } + + return right - left + 1 +} diff --git a/go/alg/sliding_window_maximum/code.go b/go/alg/sliding_window_maximum/code.go new file mode 100644 index 0000000..2ae8a30 --- /dev/null +++ b/go/alg/sliding_window_maximum/code.go @@ -0,0 +1,31 @@ +package sliding_window_maximum + +func maxSlidingWindow(nums []int, k int) []int { + arr := make([]int, 0) + l := 0 + r := -1 + queue := make([]int, len(nums)) + front := 0 + end := -1 + for r < len(nums)-1 { + r++ + for end-front >= 0 && nums[r] >= nums[queue[end]] { + end-- + } + end++ + queue[end] = r + + if r-l+1 > k { + if queue[front] == l { + front++ + } + l++ + } + + if r-l+1 == k { + arr = append(arr, nums[queue[front]]) + } + } + + return arr +} diff --git a/go/alg/sort_an_array/code.go b/go/alg/sort_an_array/code.go new file mode 100644 index 0000000..649df6b --- /dev/null +++ b/go/alg/sort_an_array/code.go @@ -0,0 +1,33 @@ +package sortanarray + +import "math/rand" + +func quitSort(nums []int, start, end int) { + if start >= end { + return + } + + idx := rand.Intn(end-start+1) + start + nums[idx], nums[start] = nums[start], nums[idx] + + idx = start + 1 + for i := start + 1; i <= end; i++ { + if nums[i] < nums[start] { + nums[idx], nums[i] = nums[i], nums[idx] + idx++ + } + } + idx-- + if nums[start] > nums[idx] { + nums[start], nums[idx] = nums[idx], nums[start] + } + + quitSort(nums, start, idx-1) + quitSort(nums, idx+1, end) + + return +} +func sortArray(nums []int) []int { + quitSort(nums, 0, len(nums)-1) + return nums +} diff --git a/go/alg/sort_an_array/code_test.go b/go/alg/sort_an_array/code_test.go new file mode 100644 index 0000000..5d2c713 --- /dev/null +++ b/go/alg/sort_an_array/code_test.go @@ -0,0 +1,13 @@ +package sortanarray + +import "testing" + +func TestSort(t *testing.T) { + arr := []int{23, 5, 98, 60, 23, 134} + sortArray(arr) + t.Logf("%v", arr) + + arr = []int{1, 2, 3, 4} + sortArray(arr) + t.Logf("%v", arr) +} diff --git a/go/alg/spiral_matrix/code.go b/go/alg/spiral_matrix/code.go new file mode 100644 index 0000000..737c985 --- /dev/null +++ b/go/alg/spiral_matrix/code.go @@ -0,0 +1,72 @@ +package spiralmatrix + +func spiralOrder(matrix [][]int) (result []int) { + if len(matrix) <= 0 { + return + } + + mode := 1 + rows := len(matrix) + cols := len(matrix[0]) + flag := make([][]bool, rows) + for i := 0; i < rows; i++ { + flag[i] = make([]bool, cols) + } + + isVisited := func(i, j int) bool { + if i < 0 || i >= rows || j < 0 || j >= cols { + return true + } + + if flag[i][j] { + return true + } + + return false + } + + i := 0 + j := 0 + for { + if isVisited(i, j) { + break + } + + result = append(result, matrix[i][j]) + flag[i][j] = true + + switch mode { + case 1: + j++ + if isVisited(i, j) { + mode = 2 + j-- + i++ + } + case 2: + i++ + if isVisited(i, j) { + mode = 3 + i-- + j-- + } + case 3: + j-- + if isVisited(i, j) { + mode = 4 + j++ + i-- + } + case 4: + i-- + if isVisited(i, j) { + mode = 1 + i++ + j++ + } + + } + } + + return +} diff --git a/go/alg/wildcard_matching/code.go b/go/alg/wildcard_matching/code.go new file mode 100644 index 0000000..35bdcad --- /dev/null +++ b/go/alg/wildcard_matching/code.go @@ -0,0 +1,30 @@ +package wildcardmatching + +func isMatch(s string, p string) bool { + m, n := len(s), len(p) + dp := make([][]bool, m+1) + for i := 0; i < len(dp); i++ { + dp[i] = make([]bool, n+1) + } + + dp[0][0] = true + for j := 1; j <= n; j++ { + if p[j-1] == '*' { + dp[0][j] = true + } else { + break + } + } + + for i := 1; i <= m; i++ { + for j := 1; j <= n; j++ { + if p[j-1] == '*' { + dp[i][j] = dp[i][j-1] || dp[i-1][j] + } else if p[j-1] == '?' || p[j-1] == s[i-1] { + dp[i][j] = dp[i-1][j-1] + } + } + } + + return dp[m][n] +} diff --git a/go/alg/wildcard_matching/code_test.go b/go/alg/wildcard_matching/code_test.go new file mode 100644 index 0000000..eede6fb --- /dev/null +++ b/go/alg/wildcard_matching/code_test.go @@ -0,0 +1,12 @@ +package wildcardmatching + +import "testing" + +func TestIsMatch(t *testing.T) { + s := "aab" + p := "c*a*b" + + ok := isMatch(s, p) + + t.Logf("ok: %v\n", ok) +} diff --git a/go/array/3sum-closest b/go/array/3sum-closest new file mode 100644 index 0000000..a97ef3a --- /dev/null +++ b/go/array/3sum-closest @@ -0,0 +1,26 @@ +func abs(x int) int { + if x < 0 { + return -x + } + + return x +} + +func threeSumClosest(nums []int, target int) int { + curMin := 1<<31 - 1 + ret := 0 + + for i := 0; i < len(nums); i += 1 { + for j := i + 1; j < len(nums); j += 1 { + for k := j + 1; k < len(nums); k += 1 { + tmp := nums[i] + nums[j] + nums[k] + if abs(target - tmp) < curMin { + curMin = abs(target - tmp) + ret = tmp + } + } + } + } + + return ret +} diff --git a/go/array/3sum-closest[1].go b/go/array/3sum-closest[1].go new file mode 100644 index 0000000..8694a98 --- /dev/null +++ b/go/array/3sum-closest[1].go @@ -0,0 +1,32 @@ +func abs(x int) int { + if x < 0 { + return -x + } + + return x +} + +func threeSumClosest(nums []int, target int) int { + sort.Ints(nums) + ret := nums[0] + nums[1] + nums[2] + for i := 0; i < len(nums) - 2; i += 1 { + start := i + 1 + end := len(nums) - 1 + for start < end { + sum := nums[i] + nums[start] + nums[end] + if sum == target { + return sum + }else if sum > target { + end -= 1 + }else { + start += 1 + } + + if abs(sum - target) < abs(ret - target) { + ret = sum + } + } + } + + return ret +} diff --git a/go/array/array-partition-i.go b/go/array/array-partition-i.go new file mode 100644 index 0000000..96cf442 --- /dev/null +++ b/go/array/array-partition-i.go @@ -0,0 +1,10 @@ +func arrayPairSum(nums []int) int { + sort.Ints(nums) + + ret := 0 + for i := 0; i < len(nums); i += 2 { + ret += nums[i] + } + + return ret +} diff --git a/go/array/best-time-to-buy-and-sell-stock-ii.go b/go/array/best-time-to-buy-and-sell-stock-ii.go new file mode 100644 index 0000000..61d5ab3 --- /dev/null +++ b/go/array/best-time-to-buy-and-sell-stock-ii.go @@ -0,0 +1,11 @@ +func maxProfit(prices []int) int { + var ret int + + for i := 1; i < len(prices); i++ { + if(prices[i] > prices[i-1]) { + ret += prices[i] - prices[i-1] + } + } + + return ret +} diff --git a/go/array/best-time-to-buy-and-sell-stock.go b/go/array/best-time-to-buy-and-sell-stock.go new file mode 100644 index 0000000..d70cb35 --- /dev/null +++ b/go/array/best-time-to-buy-and-sell-stock.go @@ -0,0 +1,15 @@ +func maxProfit(prices []int) int { + ret := 0; + cur := int(^uint(0) >> 1) + + for i := 0; i < len(prices); i++ { + if prices[i] - cur > ret { + ret = prices[i] - cur + } + if prices[i] < cur { + cur = prices[i] + } + } + + return ret +} diff --git a/go/array/contains-duplicate-ii.go b/go/array/contains-duplicate-ii.go new file mode 100644 index 0000000..2de6986 --- /dev/null +++ b/go/array/contains-duplicate-ii.go @@ -0,0 +1,11 @@ +func containsNearbyDuplicate(nums []int, k int) bool { + for i := 0; i < len(nums); i++ { + for j := i + 1; j < len(nums) && j <= i + k; j++{ + if(nums[i] == nums[j]){ + return true + } + } + } + + return false +} diff --git a/go/array/contains-duplicate-ii[1].go b/go/array/contains-duplicate-ii[1].go new file mode 100644 index 0000000..22db3ff --- /dev/null +++ b/go/array/contains-duplicate-ii[1].go @@ -0,0 +1,14 @@ +func containsNearbyDuplicate(nums []int, k int) bool { + var mp map[int]int + mp = make(map[int]int) + + for idx, value := range nums { + key, ok := mp[value] + if(ok && idx - key <= k){ + return true + } + mp[value] = idx + } + + return false +} diff --git a/go/array/contains-duplicate.go b/go/array/contains-duplicate.go new file mode 100644 index 0000000..1dbab93 --- /dev/null +++ b/go/array/contains-duplicate.go @@ -0,0 +1,13 @@ +func containsDuplicate(nums []int) bool { + var mp = make(map[int]int) + + for idx, value := range nums { + _, ok := mp[value] + if ok { + return true + } + mp[value] = idx + } + + return false +} diff --git a/go/array/majority-element.go b/go/array/majority-element.go new file mode 100644 index 0000000..b362f84 --- /dev/null +++ b/go/array/majority-element.go @@ -0,0 +1,16 @@ +func majorityElement(nums []int) int { + var count, value int + + for i := range nums { + if count == 0 { + value = nums[i] + } + if value == nums[i] { + count++ + }else{ + count-- + } + } + + return value +} diff --git a/go/array/maximum-subarray.go b/go/array/maximum-subarray.go new file mode 100644 index 0000000..dce8df9 --- /dev/null +++ b/go/array/maximum-subarray.go @@ -0,0 +1,16 @@ +func maxSubArray(nums []int) int { + var maxsum, cursum int + + maxsum = math.MinInt32 + for _, value := range nums { + cursum += value + if cursum > maxsum { + maxsum = cursum + } + if cursum < 0 { + cursum = 0 + } + } + + return maxsum +} diff --git a/go/array/merge-sorted-array.go b/go/array/merge-sorted-array.go new file mode 100644 index 0000000..f08a17b --- /dev/null +++ b/go/array/merge-sorted-array.go @@ -0,0 +1,21 @@ +func merge(nums1 []int, m int, nums2 []int, n int) { + i := m - 1 + j := n - 1 + k := m + n - 1 + for i >= 0 && j >= 0 { + if nums1[i] > nums2[j] { + nums1[k] = nums1[i] + i-- + } else { + nums1[k] = nums2[j] + j-- + } + k-- + } + + for j >= 0 { + nums1[k] = nums2[j] + k-- + j-- + } +} diff --git a/go/array/missing-number.go b/go/array/missing-number.go new file mode 100644 index 0000000..b28cd91 --- /dev/null +++ b/go/array/missing-number.go @@ -0,0 +1,8 @@ +func missingNumber(nums []int) int { + ret := len(nums) * (len(nums) + 1) / 2 + for _, v := range nums { + ret -= v + } + + return ret +} diff --git a/go/array/plus-one.go b/go/array/plus-one.go new file mode 100644 index 0000000..e1e5879 --- /dev/null +++ b/go/array/plus-one.go @@ -0,0 +1,15 @@ +func plusOne(digits []int) []int { + var carry = 1 + var arr = make([]int, len(digits) + 1) + + for i := len(digits); i > 0; i-- { + arr[i] = (digits[i-1] + carry) % 10 + carry = (digits[i-1] + carry) / 10 + } + + if carry == 1 { + arr[0] = carry + return arr + } + return arr[1:] +} diff --git a/go/array/remove-duplicates-from-sorted-array.go b/go/array/remove-duplicates-from-sorted-array.go new file mode 100644 index 0000000..5f3a2a8 --- /dev/null +++ b/go/array/remove-duplicates-from-sorted-array.go @@ -0,0 +1,16 @@ +func removeDuplicates(nums []int) int { + c := 0 + + if len(nums) == 0 { + return 0 + } + + for i := 0; i < len(nums); i++ { + if(nums[i] != nums[c]){ + c++ + nums[c], nums[i] = nums[i], nums[c] + } + } + + return c + 1 +} diff --git a/go/array/remove-element.go b/go/array/remove-element.go new file mode 100644 index 0000000..6ad30e9 --- /dev/null +++ b/go/array/remove-element.go @@ -0,0 +1,19 @@ +func removeElement(nums []int, val int) int { + i := 0 + j := len(nums) - 1 + for i <= j { + for i <= j && nums[i] != val { + i++ + } + + for j >= i && nums[j] == val { + j-- + } + + if(i < j) { + nums[i], nums[j] = nums[j], nums[i] + } + } + + return i +} diff --git a/go/array/remove-element[1].go b/go/array/remove-element[1].go new file mode 100644 index 0000000..38f1e5e --- /dev/null +++ b/go/array/remove-element[1].go @@ -0,0 +1,10 @@ +func removeElement(nums []int, val int) int { + idx := 0 + for i := 0; i < len(nums); i++ { + if nums[i] != val { + nums[idx] = nums[i] + idx++ + } + } + return idx +} diff --git a/go/array/rotate-array.go b/go/array/rotate-array.go new file mode 100644 index 0000000..f849a63 --- /dev/null +++ b/go/array/rotate-array.go @@ -0,0 +1,12 @@ +func rotate(nums []int, k int) { + k = k % len(nums) + + for k > 0 { + var tmp = nums[len(nums) - 1] + for i := len(nums) - 1; i > 0; i-- { + nums[i] = nums[i - 1] + } + nums[0] = tmp + k-- + } +} diff --git a/go/array/rotate-array[1].go b/go/array/rotate-array[1].go new file mode 100644 index 0000000..70e27a9 --- /dev/null +++ b/go/array/rotate-array[1].go @@ -0,0 +1,7 @@ +func rotate(nums []int, k int) { + k %= len(nums) + r := make([]int, len(nums)) + copy(r, nums[len(nums) - k:]) + copy(r[k:], nums[:len(nums) - k]) + copy(nums, r) +} diff --git a/go/array/rotate-array[2].go b/go/array/rotate-array[2].go new file mode 100644 index 0000000..c6021f1 --- /dev/null +++ b/go/array/rotate-array[2].go @@ -0,0 +1,15 @@ +func rotate(nums []int, k int) { + k %= len(nums) + + reverse(nums, 0, len(nums) - k - 1) + reverse(nums, len(nums) - k, len(nums) - 1) + reverse(nums, 0, len(nums) - 1) +} + +func reverse(nums []int, start, end int){ + for(start < end){ + nums[start], nums[end] = nums[end], nums[start] + start++ + end-- + } +} diff --git a/go/array/search-insert-position.go b/go/array/search-insert-position.go new file mode 100644 index 0000000..c8927c1 --- /dev/null +++ b/go/array/search-insert-position.go @@ -0,0 +1,15 @@ +func searchInsert(nums []int, target int) int { + i, j := 0, len(nums) - 1 + for i <= j { + mid := (i + j) >> 1 + if nums[mid] == target { + return mid + }else if nums[mid] > target { + j = mid - 1 + }else { + i = mid + 1 + } + } + + return i +} diff --git a/go/array/two-sum-ii-input-array-is-sorted.go b/go/array/two-sum-ii-input-array-is-sorted.go new file mode 100644 index 0000000..5bb28d6 --- /dev/null +++ b/go/array/two-sum-ii-input-array-is-sorted.go @@ -0,0 +1,26 @@ +func twoSum(numbers []int, target int) []int { + var i, j int + for i = 0; i < len(numbers); i++ { + j = search(numbers, target - numbers[i], i + 1, len(numbers) - 1) + if(j != -1){ + break + } + } + + return []int{i+1, j+1} +} + +func search(numbers []int, target, start, end int) int { + for start <= end { + mid := (start + end) / 2 + if(numbers[mid] == target){ + return mid + }else if(numbers[mid] > target){ + end = mid - 1 + }else{ + start = mid + 1 + } + } + + return -1 +} diff --git a/go/array/two-sum-ii-input-array-is-sorted[1].go b/go/array/two-sum-ii-input-array-is-sorted[1].go new file mode 100644 index 0000000..6dd935a --- /dev/null +++ b/go/array/two-sum-ii-input-array-is-sorted[1].go @@ -0,0 +1,14 @@ +func twoSum(numbers []int, target int) []int { + var mp = make(map[int] int) + + for key, value := range numbers { + idx, ok := mp[target - value] + if ok { + return []int{idx + 1, key + 1} + } + + mp[value] = key + } + + return []int{-1,-1} +} diff --git a/go/array/two-sum.go b/go/array/two-sum.go new file mode 100644 index 0000000..6713cd6 --- /dev/null +++ b/go/array/two-sum.go @@ -0,0 +1,13 @@ +func twoSum(nums []int, target int) []int { + var ret []int + for i := 0; i < len(nums); i++ { + for j := i + 1; j < len(nums); j++ { + if ((nums[i] + nums[j]) == target) { + ret = append(ret,i,j) + return ret + } + } + } + + return ret +} diff --git a/go/array/two-sum[1].go b/go/array/two-sum[1].go new file mode 100644 index 0000000..cc451d3 --- /dev/null +++ b/go/array/two-sum[1].go @@ -0,0 +1,16 @@ +two-sum +func twoSum(nums []int, target int) []int { + var mp = make(map[int] int) + for i := 0; i < len(nums); i++ { + mp[nums[i]] = i + } + + for j := 0; j < len(nums); j++{ + index, ok := mp[target - nums[j]] + if(ok && index != j){ + return []int{index,j} + } + } + + return nil +} diff --git a/go/dp/longest-palindromic-substring/code.go b/go/dp/longest-palindromic-substring/code.go new file mode 100644 index 0000000..6de29c9 --- /dev/null +++ b/go/dp/longest-palindromic-substring/code.go @@ -0,0 +1,73 @@ +package dp + +func format(s string) (dstBytes []byte) { + srcBytes := []byte(s) + if len(srcBytes) == 0 { + return + } + + dstBytes = make([]byte, 0, len(srcBytes)*2+1) + + for i := 0; i < len(srcBytes); i++ { + dstBytes = append(dstBytes, 0) + dstBytes = append(dstBytes, srcBytes[i]) + } + + dstBytes = append(dstBytes, 0) + return +} + +func longestPalindrome(s string) string { + buf := format(s) + if len(buf) == 0 { + return "" + } + + maxC := -1 + maxR := 0 + + C := -1 //最大回文中心点 + R := -1 //最大回文右边界 + p := make([]int, len(buf)) //p[i] 表示buf数组中,以i下标为中心,最大回文半径 + + for i := range buf { + p[i] = 1 + if R > i { + p[i] = p[2*C-i] + if R-i < p[i] { + p[i] = R - i + } + } + + left := i - p[i] + right := i + p[i] + for left >= 0 && right < len(buf) { + if buf[left] != buf[right] { + break + } + p[i]++ + left-- + right++ + } + + if p[i] > maxR { + maxC = i + maxR = p[i] + } + + if i+p[i] >= R { + C = i + R = i + p[i] - 1 + } + } + + retBuf := make([]byte, 0, maxR) + for i := maxC - maxR + 1; i < maxC+maxR; i++ { + if buf[i] == 0 { + continue + } + retBuf = append(retBuf, buf[i]) + } + + return string(retBuf) +} diff --git a/go/dp/longest-palindromic-substring/code_test.go b/go/dp/longest-palindromic-substring/code_test.go new file mode 100644 index 0000000..c74580a --- /dev/null +++ b/go/dp/longest-palindromic-substring/code_test.go @@ -0,0 +1,17 @@ +package dp + +import "testing" + +func TestLongestPalindrome(t *testing.T) { + s := "aba" + rs := longestPalindrome(s) + if rs != "aba" { + t.Fatalf("test failed: %s", rs) + } + + s = "cbbd" + rs = longestPalindrome(s) + if rs != "bb" { + t.Fatalf("test failed: %s", rs) + } +} diff --git a/go/dp/unique_binary_search_trees/code.go b/go/dp/unique_binary_search_trees/code.go new file mode 100644 index 0000000..4c83dab --- /dev/null +++ b/go/dp/unique_binary_search_trees/code.go @@ -0,0 +1,14 @@ +package unique_binary_search_trees + +func numTrees(n int) int { + dp := make([]int, n+1) + dp[0] = 1 + dp[1] = 1 + for i := 2; i <= n; i++ { + for j := 1; j <= i; j++ { + dp[i] += dp[j-1] * dp[i-j] + } + } + + return dp[n] +} diff --git a/go/dp/unique_binary_search_trees/code_test.go b/go/dp/unique_binary_search_trees/code_test.go new file mode 100644 index 0000000..270a389 --- /dev/null +++ b/go/dp/unique_binary_search_trees/code_test.go @@ -0,0 +1,10 @@ +package unique_binary_search_trees + +import "testing" + +func TestNumTrees(t *testing.T) { + val := numTrees(3) + if val != 5 { + t.Fatalf("test failed: %d", val) + } +} diff --git a/go/kmp/code.go b/go/kmp/code.go new file mode 100644 index 0000000..f093cac --- /dev/null +++ b/go/kmp/code.go @@ -0,0 +1,33 @@ +package kmp + +//返回s1中,首次出现s2的下标,如果s1中不包含s2, 返回-1 +func KMP(s1, s2 string) int{ + + return -1 +} + +func getNext(s string) (arr []int) { + if len(s) <= 1 { + return []int{-1} + } + + arr = make([]int, len(s)) + arr[0] = -1 + arr[1] = 1 + idx := 2 + prev := 0 + ch := []byte(s) + for idx < len(s){ + if ch[idx] == ch[arr[prev]+1] { + arr[idx] = arr[prev] + 1 + idx++ + prev = idx -1 + }else if arr[prev] == -1 { + arr[idx] = 1 + idx++ + }else { + idx = arr[prev] + } + } + return +} \ No newline at end of file diff --git a/go/kmp/code1.go b/go/kmp/code1.go new file mode 100644 index 0000000..d3b0013 --- /dev/null +++ b/go/kmp/code1.go @@ -0,0 +1,71 @@ +package kmp + +import "fmt" + +func buildNext(s string) (next []int) { + if len(s) <= 1 { + return []int{-1} + } + + next = make([]int, len(s)) + next[0] = -1 + next[1] = 0 + + idx := 2 + cn := 0 + for idx < len(s) { + if s[idx-1] == s[cn] { + next[idx] = cn + 1 + cn++ + idx++ + } else if cn > 0 { + cn = next[cn] + } else { + next[idx] = 0 + idx++ + } + } + + // for i := 2; i < len(s); i++ { + // j := i - 1 + // for j >= 0 { + // if j > 0 && s[i-1] == s[next[j]] { + // next[i] = next[j] + 1 + // break + // } else if j > 0 { + // j = next[j] + // } else if j == 0 { + // next[i] = 0 + // break + // } + // } + // } + return +} + +func Kmp(s string, pattern string) int { + if len(pattern) == 0 || len(s) < len(pattern) { + return -1 + } + + next := buildNext(pattern) + fmt.Println(pattern) + fmt.Println(next) + i, j := 0, 0 + for i < len(s) && j < len(pattern) { + if s[i] == pattern[j] { + i++ + j++ + } else if j == 0 { + i++ + } else { + j = next[j] + } + } + + if j == len(pattern) { + return i - j + } + + return -1 +} diff --git a/go/kmp/code1_test.go b/go/kmp/code1_test.go new file mode 100644 index 0000000..9364513 --- /dev/null +++ b/go/kmp/code1_test.go @@ -0,0 +1,11 @@ +package kmp + +import "testing" + +func TestKmp(t *testing.T) { + s := "rabaieet" + p := "abai" + + idx := Kmp(s, p) + t.Logf("idx: %d", idx) +} diff --git a/go/list/add_two_numbers/code.go b/go/list/add_two_numbers/code.go new file mode 100644 index 0000000..5523bc2 --- /dev/null +++ b/go/list/add_two_numbers/code.go @@ -0,0 +1,55 @@ +package addtwonumbers + +type ListNode struct { + Val int + Next *ListNode +} + +func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode { + carry := 0 + root := &ListNode{} + + p := root + for l1 != nil && l2 != nil { + val := l1.Val + l2.Val + carry + carry = val / 10 + val = val % 10 + + node := &ListNode{ + Val: val, + } + p.Next = node + p = node + + l1 = l1.Next + l2 = l2.Next + } + + if l2 != nil { + l1 = l2 + } + + for l1 != nil { + val := l1.Val + carry + carry = val / 10 + val = val % 10 + + node := &ListNode{ + Val: val, + } + p.Next = node + p = node + + l1 = l1.Next + } + + if carry > 0 { + node := &ListNode{ + Val: carry, + } + p.Next = node + p = node + } + + return root.Next +} diff --git a/go/list/add_two_numbers/code_test.go b/go/list/add_two_numbers/code_test.go new file mode 100644 index 0000000..230ff34 --- /dev/null +++ b/go/list/add_two_numbers/code_test.go @@ -0,0 +1 @@ +package addtwonumbers diff --git a/go/list/add_two_numbers_ii/code.go b/go/list/add_two_numbers_ii/code.go new file mode 100644 index 0000000..0d7b4c7 --- /dev/null +++ b/go/list/add_two_numbers_ii/code.go @@ -0,0 +1,66 @@ +package addtwonumbersii + +type ListNode struct { + Val int + Next *ListNode +} + +func reverse(head *ListNode) *ListNode { + root := &ListNode{} + for head != nil { + next := head.Next + head.Next = root.Next + root.Next = head + head = next + } + + return root.Next +} + +func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode { + r1 := reverse(l1) + r2 := reverse(l2) + + root := &ListNode{} + cur := root + + token := 0 + for r1 != nil && r2 != nil { + sum := r1.Val + r2.Val + token + node := &ListNode{ + Val: sum % 10, + } + token = sum / 10 + cur.Next = node + cur = cur.Next + + r1 = r1.Next + r2 = r2.Next + } + + tail := r1 + if r2 != nil { + tail = r2 + } + + for tail != nil { + sum := tail.Val + token + node := &ListNode{ + Val: sum % 10, + } + token = sum / 10 + cur.Next = node + cur = cur.Next + tail = tail.Next + } + + if token > 0 { + node := &ListNode{ + Val: token, + } + cur.Next = node + cur = cur.Next + } + + return reverse(root.Next) +} diff --git a/go/list/add_two_numbers_ii/code_test.go b/go/list/add_two_numbers_ii/code_test.go new file mode 100644 index 0000000..de792bf --- /dev/null +++ b/go/list/add_two_numbers_ii/code_test.go @@ -0,0 +1 @@ +package addtwonumbersii diff --git a/go/list/all_oone_data_structure/code.go b/go/list/all_oone_data_structure/code.go new file mode 100644 index 0000000..331ecc1 --- /dev/null +++ b/go/list/all_oone_data_structure/code.go @@ -0,0 +1,100 @@ +package alloone + +import "container/list" + +type node struct { + keys map[string]struct{} + count int +} + +type AllOne struct { + *list.List + nodes map[string]*list.Element +} + +func Constructor() AllOne { + return AllOne{ + List: list.New(), + nodes: map[string]*list.Element{}, + } +} + +func (a *AllOne) Inc(key string) { + curElem := a.nodes[key] + if curElem == nil { + if a.Front() == nil || a.Front().Value.(*node).count > 1 { + a.nodes[key] = a.PushFront(&node{keys: map[string]struct{}{key: {}}, count: 1}) + } else { + a.Front().Value.(*node).keys[key] = struct{}{} + a.nodes[key] = a.Front() + } + + return + } + + curNode := curElem.Value.(*node) + nextElem := curElem.Next() + if nextElem == nil || nextElem.Value.(*node).count > curNode.count+1 { + a.nodes[key] = a.InsertAfter(&node{keys: map[string]struct{}{key: {}}, count: curNode.count + 1}, curElem) + } else { + nextElem.Value.(*node).keys[key] = struct{}{} + a.nodes[key] = nextElem + } + + delete(curNode.keys, key) + if len(curNode.keys) == 0 { + a.Remove(curElem) + } +} + +func (a *AllOne) Dec(key string) { + curElem, ok := a.nodes[key] + if !ok { + return + } + + elem := curElem.Value.(*node) + if elem.count > 1 { + prevElem := curElem.Prev() + if prevElem == nil || prevElem.Value.(*node).count < elem.count-1 { + a.nodes[key] = a.InsertBefore(&node{ + keys: map[string]struct{}{ + key: {}, + }, + count: elem.count - 1, + }, curElem) + } else { + prevElem.Value.(*node).keys[key] = struct{}{} + a.nodes[key] = prevElem + } + } else { + delete(a.nodes, key) + } + + delete(elem.keys, key) + if len(elem.keys) == 0 { + a.Remove(curElem) + } +} + +func (a *AllOne) GetMaxKey() string { + elem := a.Back() + if elem != nil { + for key := range elem.Value.(*node).keys { + return key + } + } + + return "" +} + +func (a *AllOne) GetMinKey() string { + elem := a.Front() + if elem != nil { + for key := range elem.Value.(*node).keys { + return key + } + } + + return "" +} diff --git a/go/list/all_oone_data_structure/code1.go b/go/list/all_oone_data_structure/code1.go new file mode 100644 index 0000000..453fa9e --- /dev/null +++ b/go/list/all_oone_data_structure/code1.go @@ -0,0 +1,126 @@ +package alloone + +type listNode struct { + Val int + Key string + Prev *listNode + Next *listNode +} + +func (root *listNode) pushFront(node *listNode) { + node.Next = root.Next + root.Next.Prev = node + + node.Prev = root + root.Next = node +} + +func (root *listNode) delete(node *listNode) { + next := node.Next + prev := node.Prev + + prev.Next = next + next.Prev = prev + + node.Next = nil + node.Prev = nil +} + +//链表向前后移动一个位置 +func (root *listNode) moveBack(node *listNode) { + back := node.Next //node2为需要 + + node.Next = back.Next + back.Next.Prev = node + + prev := node.Prev + + node.Prev = back + back.Next = node + + back.Prev = prev + prev.Next = back +} + +func (root *listNode) moveFront(node *listNode) { + prev := node.Prev + root.moveBack(prev) +} + +type AllOne1 struct { + Root *listNode + MData map[string]*listNode +} + +func Constructor1() AllOne1 { + a := AllOne1{ + MData: make(map[string]*listNode), + Root: new(listNode), + } + + a.Root.Next = a.Root + a.Root.Prev = a.Root + + return a +} + +func (a *AllOne1) Inc(key string) { + node, ok := a.MData[key] + if !ok { + node = &listNode{ + Key: key, + Val: 1, + } + + a.MData[key] = node + a.Root.pushFront(node) + return + } + + node.Val++ + for node.Next != a.Root { + if node.Next.Val >= node.Val { + break + } + + a.Root.moveBack(node) + } +} + +func (a *AllOne1) Dec(key string) { + node, ok := a.MData[key] + if !ok { + return + } + node.Val-- + if node.Val == 0 { + delete(a.MData, key) + a.Root.delete(node) + return + } + + for node.Prev != a.Root { + if node.Prev.Val <= node.Val { + break + } + a.Root.moveFront(node) + } +} + +func (a *AllOne1) GetMaxKey() string { + node := a.Root.Prev + if node == a.Root { + return "" + } + + return node.Key +} + +func (a *AllOne1) GetMinKey() string { + node := a.Root.Next + if node == a.Root { + return "" + } + + return node.Key +} diff --git a/go/list/all_oone_data_structure/code_test.go b/go/list/all_oone_data_structure/code_test.go new file mode 100644 index 0000000..6726d49 --- /dev/null +++ b/go/list/all_oone_data_structure/code_test.go @@ -0,0 +1,43 @@ +package alloone + +import "testing" + +func TestAllOne1(t *testing.T) { + hello := "hello" + // goodBye := "goodbye" + leet := "leet" + // code := "code" + obj := Constructor1() + obj.Inc(hello) + // obj.Inc(goodBye) + obj.Inc(hello) + obj.Inc(hello) + t.Logf("max key :%s\n", obj.GetMaxKey()) + obj.Inc(leet) + + // obj.Inc(code) + obj.Inc(leet) + obj.Dec(hello) + + obj.Inc(leet) + // obj.Inc(code) + // obj.Inc(code) + t.Logf("max key :%s\n", obj.GetMaxKey()) +} + +func TestAllOne(t *testing.T) { + hello := "hello" + leet := "leet" + obj := Constructor() + + obj.Inc(leet) + obj.Inc(hello) + obj.Inc(hello) + obj.Inc(hello) + obj.Inc(hello) + obj.Dec(hello) + obj.Dec(hello) + t.Logf("max key :%s\n", obj.GetMaxKey()) + + t.Logf("max key :%s\n", obj.GetMaxKey()) +} diff --git a/go/list/copy_random/code.go b/go/list/copy_random/code.go new file mode 100644 index 0000000..712e4a7 --- /dev/null +++ b/go/list/copy_random/code.go @@ -0,0 +1,46 @@ +package copyrandom + +type Node struct { + Val int + Next *Node + Random *Node +} + +func copyRandomList(head *Node) *Node { + if head == nil { + return nil + } + + cur := head + for cur != nil { + next := cur.Next + node := &Node{ + Val: cur.Val, + Next: next, + } + cur.Next = node + cur = next + } + + cur = head + for cur != nil { + if cur.Random != nil { + cur.Next.Random = cur.Random.Next + } + cur = cur.Next.Next + } + + cur = head + root := &Node{} + p := root + for cur != nil { + p.Next = cur.Next + p = p.Next + + cur.Next = p.Next + cur = cur.Next + } + p.Next = nil + + return root.Next +} diff --git a/go/list/detect_cycle/code.go b/go/list/detect_cycle/code.go new file mode 100644 index 0000000..9e0e261 --- /dev/null +++ b/go/list/detect_cycle/code.go @@ -0,0 +1,34 @@ +package detectcycle + +type ListNode struct { + Val int + Next *ListNode +} + +func detectCycle(head *ListNode) *ListNode { + if head == nil { + return nil + } + + slow, fast := head, head + for slow != nil && fast != nil { + slow = slow.Next + fast = fast.Next + if fast == nil || fast.Next == nil { //说明链表没有环 + return nil + } + + fast = fast.Next + + if slow == fast { + break + } + } + + for head != slow { + head = head.Next + slow = slow.Next + } + + return head +} diff --git a/go/list/detect_cycle/code_test.go b/go/list/detect_cycle/code_test.go new file mode 100644 index 0000000..3a1b3d6 --- /dev/null +++ b/go/list/detect_cycle/code_test.go @@ -0,0 +1,27 @@ +package detectcycle + +import "testing" + +func TestDetectCycle(t *testing.T) { + n1 := &ListNode{ + Val: 3, + } + n2 := &ListNode{ + Val: 2, + } + n3 := &ListNode{ + Val: 0, + } + n4 := &ListNode{ + Val: -4, + } + + n1.Next = n2 + n2.Next = n3 + n3.Next = n4 + n4.Next = n2 + + node := detectCycle(n1) + + t.Logf("val: %d", node.Val) +} diff --git a/go/list/get_kth_from_end/code.go b/go/list/get_kth_from_end/code.go new file mode 100644 index 0000000..23188f9 --- /dev/null +++ b/go/list/get_kth_from_end/code.go @@ -0,0 +1,23 @@ +package getkthfromend + +type ListNode struct { + Val int + Next *ListNode +} + +func getKthFromEnd(head *ListNode, k int) *ListNode { + cnt := 0 + p := head + for p != nil { + cnt++ + p = p.Next + } + + k = cnt - k + for k > 0 { + head = head.Next + k-- + } + + return head +} diff --git a/go/list/linked_list_cycle/code.go b/go/list/linked_list_cycle/code.go new file mode 100644 index 0000000..ea4f3e7 --- /dev/null +++ b/go/list/linked_list_cycle/code.go @@ -0,0 +1,25 @@ +package linkedlistcycle + +type ListNode struct { + Val int + Next *ListNode +} + +func hasCycle(head *ListNode) bool { + if head == nil { + return false + } + slow, fast := head, head.Next + for slow != nil && fast != nil { + if slow == fast { + return true + } + slow = slow.Next + fast = fast.Next + if fast != nil { + fast = fast.Next + } + } + + return false +} diff --git a/go/list/merge/code.go b/go/list/merge/code.go new file mode 100644 index 0000000..b3dfcc1 --- /dev/null +++ b/go/list/merge/code.go @@ -0,0 +1,52 @@ +package merge + +type ListNode struct { + Val int + Next *ListNode +} + +func merge(n1, n2 *ListNode) *ListNode { + root := &ListNode{} + cur := root + var tmp *ListNode + + for n1 != nil && n2 != nil { + if n1.Val <= n2.Val { + tmp = n1 + n1 = n1.Next + } else { + tmp = n2 + n2 = n2.Next + } + + cur.Next = tmp + cur = tmp + } + + if n1 != nil { + cur.Next = n1 + } else { + cur.Next = n2 + } + + return root.Next +} + +func mergeKLists(lists []*ListNode) *ListNode { + if len(lists) == 0 { + return nil + } + if len(lists) == 1 { + return lists[0] + } + + if len(lists) == 2 { + return merge(lists[0], lists[1]) + } + + ln := len(lists) + n1 := mergeKLists(lists[:ln/2]) + n2 := mergeKLists(lists[ln/2:]) + + return merge(n1, n2) +} diff --git a/go/list/odd_even_linked_list/code.go b/go/list/odd_even_linked_list/code.go new file mode 100644 index 0000000..4e4f2dc --- /dev/null +++ b/go/list/odd_even_linked_list/code.go @@ -0,0 +1,31 @@ +package oddevenlinkedlist + +type ListNode struct { + Val int + Next *ListNode +} + +func oddEvenList(head *ListNode) *ListNode { + oddRoot := &ListNode{} + evenRoot := &ListNode{} + odd := oddRoot + even := evenRoot + + isOdd := true + for head != nil { + next := head.Next + if isOdd { + odd.Next = head + odd = head + } else { + even.Next = head + even = head + } + head.Next = nil + head = next + isOdd = !isOdd + } + + odd.Next = evenRoot.Next + return oddRoot.Next +} diff --git a/go/list/palindrome/code.go b/go/list/palindrome/code.go new file mode 100644 index 0000000..0e3c346 --- /dev/null +++ b/go/list/palindrome/code.go @@ -0,0 +1,48 @@ +package palindrome + +type ListNode struct { + Val int + Next *ListNode +} + +func invert(head *ListNode) *ListNode { + root := &ListNode{ + Next: nil, + } + + for head != nil { + tmp := head.Next + head.Next = root.Next + root.Next = head + head = tmp + } + + return root.Next +} + +func isPalindrome(head *ListNode) bool { + if head == nil { + return true + } + slow := head + fast := head + for slow != nil && fast != nil { + slow = slow.Next + fast = fast.Next + if fast != nil { + fast = fast.Next + } + } + + slow = invert(slow) + + for slow != nil { + if slow.Val != head.Val { + return false + } + slow = slow.Next + head = head.Next + } + + return true +} diff --git a/go/list/remove_duplicates_from_sorted_list_ii/code.go b/go/list/remove_duplicates_from_sorted_list_ii/code.go new file mode 100644 index 0000000..97bad27 --- /dev/null +++ b/go/list/remove_duplicates_from_sorted_list_ii/code.go @@ -0,0 +1,35 @@ +package removeduplicatesfromsortedlistii + +type ListNode struct { + Val int + Next *ListNode +} + +func deleteDuplicates(head *ListNode) *ListNode { + root := &ListNode{} + cur := root + + for head != nil { + val := head.Val + cnt := 1 + for head.Next != nil && head.Next.Val == val { + cnt++ + head = head.Next + } + + next := head.Next + + if cnt > 1 { + head = next + continue + } + + cur.Next = head + cur = head + head = next + } + + cur.Next = nil + + return root.Next +} diff --git a/go/list/remove_nth_node_from_end_list/code.go b/go/list/remove_nth_node_from_end_list/code.go new file mode 100644 index 0000000..b6c1f3c --- /dev/null +++ b/go/list/remove_nth_node_from_end_list/code.go @@ -0,0 +1,34 @@ +package removenthnodefromendlist + +type ListNode struct { + Val int + Next *ListNode +} + +func removeNthFromEnd(head *ListNode, n int) *ListNode { + root := &ListNode{ + Next: head, + } + + cnt := 0 + for head != nil { + cnt++ + head = head.Next + } + + n = cnt - n + + p := root + for n > 0 && p != nil { + p = p.Next + n-- + } + + if p == nil || p.Next == nil { + return root.Next + } + + p.Next = p.Next.Next + + return root.Next +} diff --git a/go/list/reorder/code.go b/go/list/reorder/code.go new file mode 100644 index 0000000..3eb3716 --- /dev/null +++ b/go/list/reorder/code.go @@ -0,0 +1,52 @@ +package reorder + +type ListNode struct { + Val int + Next *ListNode +} + +func reverse(head *ListNode) *ListNode { + root := &ListNode{} + + for head != nil { + tmp := head.Next + head.Next = root.Next + root.Next = head + head = tmp + } + + return root.Next +} + +func reorderList(head *ListNode) { + if head == nil { + return + } + + slow, fast := head, head + prev := slow + for slow != nil && fast != nil { + prev = slow + slow = slow.Next + fast = fast.Next + if fast != nil { + fast = fast.Next + } + } + + prev.Next = nil + + n1 := head + n2 := reverse(slow) + + for n2 != nil { + next1 := n1.Next + next2 := n2.Next + + n1.Next = n2 + n2.Next = next1 + + n1 = next1 + n2 = next2 + } +} diff --git a/go/list/reorder_list/code.go b/go/list/reorder_list/code.go new file mode 100644 index 0000000..2851b7c --- /dev/null +++ b/go/list/reorder_list/code.go @@ -0,0 +1,61 @@ +package reorderlist + +type ListNode struct { + Val int + Next *ListNode +} + +func reverse(head *ListNode) *ListNode { + root := &ListNode{} + + for head != nil { + next := head.Next + head.Next = root.Next + root.Next = head + head = next + } + + return root.Next +} + +func reorderList(head *ListNode) { + if head == nil { + return + } + + slow, fast := head, head + + for fast != nil { + fast = fast.Next + if fast == nil { + break + } + fast = fast.Next + if fast == nil { + break + } + slow = slow.Next + } + + h1 := head + h2 := reverse(slow.Next) + slow.Next = nil + + root := &ListNode{} + p := root + for h1 != nil && h2 != nil { + p.Next = h1 + h1 = h1.Next + p = p.Next + p.Next = h2 + h2 = h2.Next + p = p.Next + } + + if h1 != nil { + p.Next = h1 + } + + head = root.Next + return +} diff --git a/go/list/reorder_list/code_test.go b/go/list/reorder_list/code_test.go new file mode 100644 index 0000000..9a7a484 --- /dev/null +++ b/go/list/reorder_list/code_test.go @@ -0,0 +1,20 @@ +package reorderlist + +import "testing" + +func TestOrderList(t *testing.T) { + head := &ListNode{ + Val: 1, + Next: &ListNode{ + Val: 2, + Next: &ListNode{ + Val: 3, + Next: &ListNode{ + Val: 4, + }, + }, + }, + } + + reorderList(head) +} diff --git a/go/list/reverse/code.go b/go/list/reverse/code.go new file mode 100644 index 0000000..4f69571 --- /dev/null +++ b/go/list/reverse/code.go @@ -0,0 +1,18 @@ +package reverse + +type ListNode struct { + Val int + Next *ListNode +} + +func reverseList(head *ListNode) *ListNode { + root := &ListNode{} + for head != nil { + tmp := head.Next + head.Next = root.Next + root.Next = head + head = tmp + } + + return root.Next +} diff --git a/go/list/reverse_nodes_in_k_group/code.go b/go/list/reverse_nodes_in_k_group/code.go new file mode 100644 index 0000000..72ea4fb --- /dev/null +++ b/go/list/reverse_nodes_in_k_group/code.go @@ -0,0 +1,48 @@ +package reversenodesinkgroup + +type ListNode struct { + Val int + Next *ListNode +} + +func reverse(head *ListNode) *ListNode { + root := &ListNode{} + + for head != nil { + next := head.Next + head.Next = root.Next + root.Next = head + head = next + } + + return root.Next +} + +func reverseKGroup(head *ListNode, k int) *ListNode { + root := &ListNode{} + + cur := root + for head != nil { + cnt := k + start := head + for cnt > 1 && head != nil { + cnt-- + head = head.Next + } + + if head == nil { + cur.Next = start + return root.Next + } + + next := head.Next + head.Next = nil + + cur.Next = reverse(start) + cur = start + + head = next + } + + return root.Next +} diff --git a/go/list/reverse_nodes_in_k_group/code_test.go b/go/list/reverse_nodes_in_k_group/code_test.go new file mode 100644 index 0000000..8d3e816 --- /dev/null +++ b/go/list/reverse_nodes_in_k_group/code_test.go @@ -0,0 +1,28 @@ +package reversenodesinkgroup + +import "testing" + +func TestReverseKGroup(t *testing.T) { + head := &ListNode{ + Val: 1, + Next: &ListNode{ + Val: 2, + Next: &ListNode{ + Val: 3, + Next: &ListNode{ + Val: 4, + Next: &ListNode{ + Val: 5, + }, + }, + }, + }, + } + + head = reverseKGroup(head, 2) + + for head != nil { + t.Logf("%d\n", head.Val) + head = head.Next + } +} diff --git a/go/list/rotate_list/code.go b/go/list/rotate_list/code.go new file mode 100644 index 0000000..0d33271 --- /dev/null +++ b/go/list/rotate_list/code.go @@ -0,0 +1,39 @@ +package rotatelist + +type ListNode struct { + Val int + Next *ListNode +} + +func rotateRight(head *ListNode, k int) *ListNode { + if head == nil { + return nil + } + + cur := head + cnt := 0 + tail := cur + for cur != nil { + cnt++ + tail = cur + cur = cur.Next + } + + k = k % cnt + k = cnt - k + cur = &ListNode{ + Next: head, + } + + cnt = 0 + for cur != nil && cnt != k { + cur = cur.Next + cnt++ + } + + tail.Next = head + head = cur.Next + cur.Next = nil + + return head +} diff --git a/go/list/shan_chu_lian_biao/code.go b/go/list/shan_chu_lian_biao/code.go new file mode 100644 index 0000000..5a99e49 --- /dev/null +++ b/go/list/shan_chu_lian_biao/code.go @@ -0,0 +1,26 @@ +package shanchulianbiao + +type ListNode struct { + Val int + Next *ListNode +} + +func deleteNode(head *ListNode, val int) *ListNode { + root := &ListNode{ + Next: head, + } + cur := root + for head != nil && head.Val != val { + cur = head + head = head.Next + } + + if head == nil { + return nil + } + + cur.Next = head.Next + head.Next = nil + head = nil + return root.Next +} diff --git a/go/list/sort/code.go b/go/list/sort/code.go new file mode 100644 index 0000000..5fbd093 --- /dev/null +++ b/go/list/sort/code.go @@ -0,0 +1,55 @@ +package sort + +type ListNode struct { + Val int + Next *ListNode +} + +func merge(n1, n2 *ListNode) *ListNode { + root := &ListNode{} + cur := root + var tmp *ListNode + for n1 != nil && n2 != nil { + + if n1.Val <= n2.Val { + tmp = n1 + n1 = n1.Next + } else { + tmp = n2 + n2 = n2.Next + } + cur.Next = tmp + cur = tmp + } + + if n1 != nil { + cur.Next = n1 + } else if n2 != nil { + cur.Next = n2 + } + + return root.Next +} + +func sortList(head *ListNode) *ListNode { + if head == nil || head.Next == nil { + return head + } + + slow, fast := head, head + prev := slow + for slow != nil && fast != nil { + prev = slow + slow = slow.Next + fast = fast.Next + if fast != nil { + fast = fast.Next + } + } + + prev.Next = nil + head = sortList(head) + slow = sortList(slow) + + return merge(head, slow) +} diff --git a/go/list/sort_list/code.go b/go/list/sort_list/code.go new file mode 100644 index 0000000..8ba0a05 --- /dev/null +++ b/go/list/sort_list/code.go @@ -0,0 +1,49 @@ +package sortlist + +type ListNode struct { + Val int + Next *ListNode +} + +func sortList(head *ListNode) *ListNode { + if head == nil || head.Next == nil { + return head + } + + slow, fast := head, head + for fast != nil { + fast = fast.Next + if fast == nil || fast.Next == nil { + break + } + slow = slow.Next + fast = fast.Next + } + + next := slow.Next + slow.Next = nil + + h1 := sortList(head) + h2 := sortList(next) + + root := &ListNode{} + p := root + for h1 != nil && h2 != nil { + if h1.Val <= h2.Val { + p.Next = h1 + h1 = h1.Next + } else { + p.Next = h2 + h2 = h2.Next + } + p = p.Next + p.Next = nil + } + if h2 != nil { + h1 = h2 + } + + p.Next = h1 + + return root.Next +} diff --git a/go/misc/joseph/code.go b/go/misc/joseph/code.go new file mode 100644 index 0000000..05c8758 --- /dev/null +++ b/go/misc/joseph/code.go @@ -0,0 +1,18 @@ +package joseph + +//约瑟夫环问题 + +//给定n个人,从1 到 n 编号,每隔m个人,删掉一个人,最后剩余一人为止, +// 求最后剩下的那个人的编号 + +//f(n,m) = (f(n-1, m) + m) % n +//参考: https://blog.csdn.net/u011500062/article/details/72855826 +func Joseph(n, m int) int { + idx := 0 + for i := 2; i <= n; i++ { + idx = (idx + m) % i + } + + //注意,由于编号从1开始的,所以这里加1 + return idx + 1 +} diff --git a/go/misc/joseph/code_test.go b/go/misc/joseph/code_test.go new file mode 100644 index 0000000..956a870 --- /dev/null +++ b/go/misc/joseph/code_test.go @@ -0,0 +1,13 @@ +package joseph + +import "testing" + +func TestJoseph(t *testing.T) { + n := 11 + m := 3 + + idx := Joseph(n, m) + if idx != 7 { + t.Fatalf("test failed: %d", idx) + } +} diff --git a/go/misc/longest-palindromic-substring/code.go b/go/misc/longest-palindromic-substring/code.go new file mode 100644 index 0000000..8ad2e6c --- /dev/null +++ b/go/misc/longest-palindromic-substring/code.go @@ -0,0 +1,67 @@ +package longest_palindromic_substring + +//manacher算法 +func toManacher(src string) []byte { + srcBuf := []byte(src) + dstBuf := make([]byte, 0) + for _, val := range srcBuf { + dstBuf = append(dstBuf, 0) + dstBuf = append(dstBuf, val) + } + if len(dstBuf) > 0 { + dstBuf = append(dstBuf, 0) + } + + return dstBuf +} + +func longestPalindrome(s string) (ret string) { + buf := toManacher(s) + + pArr := make([]int, len(buf)) + R := -1 //回文右边界 + C := -1 //中心 + + maxIdx := 0 //最大回文子串 中心下标 + maxLen := 0 //最大回文子串长度 + + for idx := range buf { + pArr[idx] = 1 + if R >= idx { + pLen := R - idx + 1 + if pArr[2*C-R] < pLen { + pLen = pArr[2*C-R] + } + } + + left := idx - pArr[idx] + right := idx + pArr[idx] + for left >= 0 && right < len(buf) { + if buf[left] != buf[right] { + break + } + pArr[idx]++ + left-- + right++ + } + + if idx + pArr[idx] >= R { + R = pArr[idx] - 1 + C = idx + } + + if pArr[idx] > maxLen { + maxLen = pArr[idx] + maxIdx = idx + } + } + + dstBuf := make([]byte, 0) + for i := maxIdx - maxLen + 1; i <= maxIdx + maxLen -1; i++ { + if buf[i] != 0 { + dstBuf = append(dstBuf, buf[i]) + } + } + + return string(dstBuf) +} diff --git a/go/misc/longest-palindromic-substring/code_test.go b/go/misc/longest-palindromic-substring/code_test.go new file mode 100644 index 0000000..ed42be4 --- /dev/null +++ b/go/misc/longest-palindromic-substring/code_test.go @@ -0,0 +1,23 @@ +package longest_palindromic_substring + +import "testing" + +func TestLongestPalindrome(t *testing.T) { + s := "babad" + result := longestPalindrome(s) + if result != "bab" && result != "aba" { + t.Fatalf("test failed:%s", result) + } + + s = "" + result = longestPalindrome(s) + if result != "" { + t.Fatalf("test failed:%s", result) + } + + s = "a" + result = longestPalindrome(s) + if result != "a" { + t.Fatalf("test failed:%s", result) + } +} diff --git a/go/misc/sliding-window-maximum/code.go b/go/misc/sliding-window-maximum/code.go new file mode 100644 index 0000000..e8aa9a4 --- /dev/null +++ b/go/misc/sliding-window-maximum/code.go @@ -0,0 +1,31 @@ +package sliding_window_maximum + +func maxSlidingWindow(nums []int, k int) []int { + if k > len(nums) { + k = len(nums) + } + + qArr := make([]int, len(nums)) + l := 0 + r := -1 + + arr := make([]int, 0, len(nums) - k + 1) + for idx, val := range nums { + for l <= r && idx - qArr[l] >= k { + l++ + } + + for r >= l && nums[qArr[r]] <= val { + r-- + } + + r++ + qArr[r] = idx + + if idx >= k-1 { + arr = append(arr, nums[qArr[l]]) + } + } + + return arr +} diff --git a/go/misc/sliding-window-maximum/code_test.go b/go/misc/sliding-window-maximum/code_test.go new file mode 100644 index 0000000..3ff1996 --- /dev/null +++ b/go/misc/sliding-window-maximum/code_test.go @@ -0,0 +1,32 @@ +package sliding_window_maximum + +import ( + "reflect" + "testing" +) + +func TestMaxSlidingWindow(t *testing.T) { + nums := []int{1,3,-1,-3,5,3,6,7} + k := 3 + expect := []int{3,3,5,5,6,7} + result := maxSlidingWindow(nums, k) + if !reflect.DeepEqual(expect, result) { + t.Fatalf("test failed: %v", result) + } + + nums = []int{1} + k = 1 + expect = []int{1} + result = maxSlidingWindow(nums, k) + if !reflect.DeepEqual(expect, result) { + t.Fatalf("test failed: %v", result) + } + + nums = []int{1, -1} + k = 1 + expect = []int{1, -1} + result = maxSlidingWindow(nums, k) + if !reflect.DeepEqual(expect, result) { + t.Fatalf("test failed: %v", result) + } +} diff --git a/go/misc/sum-of-subarray-minimums/code.go b/go/misc/sum-of-subarray-minimums/code.go new file mode 100644 index 0000000..cb41a9c --- /dev/null +++ b/go/misc/sum-of-subarray-minimums/code.go @@ -0,0 +1,46 @@ +package sum_of_subarray_minimums + +func sumSubarrayMins(arr []int) int { + st := make([]int, len(arr)) //单调递增栈 + left := make([]int, len(arr)) + right := make([]int, len(arr)) + + top := -1 + for idx, val := range arr { + for top > -1 && arr[st[top]] > val { + top-- + } + if top == -1 { + left[idx] = -1 + }else { + left[idx] = st[top] + } + top++ + st[top] = idx + } + + top = -1 + for idx := len(arr)-1; idx >= 0; idx-- { + for top > -1 && arr[st[top]] >= arr[idx] { + top-- + } + if top == -1 { + right[idx] = len(arr) + }else { + right[idx] = st[top] + } + top++ + st[top] = idx + } + + sum := 0 + const Mod = 1e9+7 + + for idx := 0; idx < len(arr); idx++ { + sum += (idx-left[idx]) * (right[idx] - idx) * arr[idx] + sum %= Mod + } + + + return sum +} diff --git a/go/misc/sum-of-subarray-minimums/code_test.go b/go/misc/sum-of-subarray-minimums/code_test.go new file mode 100644 index 0000000..930962e --- /dev/null +++ b/go/misc/sum-of-subarray-minimums/code_test.go @@ -0,0 +1,26 @@ +package sum_of_subarray_minimums + +import "testing" + +func TestSumSubarrayMins(t *testing.T) { + arr := []int{3,1,2,4} + result := sumSubarrayMins(arr) + expect := 17 + if result !=expect { + t.Fatalf("test failed: %d", result) + } + + arr = []int{71,55,82,55} + result = sumSubarrayMins(arr) + expect = 593 + if result !=expect { + t.Fatalf("test failed: %d", result) + } + + arr = []int{1,2,1} + result = sumSubarrayMins(arr) + expect = 4 + if result !=expect { + t.Fatalf("test failed: %d", result) + } +} diff --git a/go/misc/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/code.go b/go/misc/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/code.go new file mode 100644 index 0000000..4d7720b --- /dev/null +++ b/go/misc/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/code.go @@ -0,0 +1,10 @@ +package yuan_quan_zhong_zui_hou_sheng_xia_de_shu_zi_lcof + +//see https://blog.csdn.net/u011500062/article/details/72855826 +func lastRemaining(n int, m int) int { + p := 0 + for i := 2; i <= n; i++ { + p = (p + m) % i + } + return p +} diff --git a/go/misc/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/code_test.go b/go/misc/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/code_test.go new file mode 100644 index 0000000..d0c0d71 --- /dev/null +++ b/go/misc/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/code_test.go @@ -0,0 +1,16 @@ +package yuan_quan_zhong_zui_hou_sheng_xia_de_shu_zi_lcof + +import "testing" + +func TestLastRemaining(t *testing.T) { + var result int + result = lastRemaining(5, 3) + if result != 3 { + t.Fatalf("test failed: %d", result) + } + + result = lastRemaining(10, 17) + if result != 2 { + t.Fatalf("test failed: %d", result) + } +} diff --git a/go/sort/heap/code.go b/go/sort/heap/code.go new file mode 100644 index 0000000..fe9d5ca --- /dev/null +++ b/go/sort/heap/code.go @@ -0,0 +1,47 @@ +package heap + +func swap(arr []int, idx1, idx2 int) { + arr[idx1], arr[idx2] = arr[idx2], arr[idx1] +} +func heapInsert(arr []int, idx int) { //从idx开始向上调整为打根堆 + for arr[idx] >arr[(idx-1)/2] { + swap(arr, idx, (idx-1)/2) + idx = (idx-1)/2 + } +} + +func heapify(arr []int, idx int) { + left := 2 *idx +1 + for left < len(arr){ + right := 2*idx+2 + si := idx + if right < len(arr) && arr[right] > arr[left]{ + si = right + }else if arr[left] > arr[idx] { + si = left + } + + if si == idx { + break + } + + swap(arr, idx, si) + left = si + } +} + +func heapSort(arr []int){ + for i := 0; i 0 { + heapify(arr, 0) + swap(arr, 0, heapSize) + heapSize-- + } +} diff --git a/go/sort/heap/code_test.go b/go/sort/heap/code_test.go new file mode 100644 index 0000000..55c0af6 --- /dev/null +++ b/go/sort/heap/code_test.go @@ -0,0 +1,25 @@ +package heap + +import ( + "reflect" + "testing" +) + +func TestHeapSort(t *testing.T) { + arr := []int{1, 7, 3, 5, 3, 6,9} + heapSort(arr) + expect := []int{1, 3, 3, 5, 6, 7, 9} + + if !reflect.DeepEqual(arr, expect) { + t.Fatalf("test failed:%v", arr) + } + + + arr = []int{1,1} + heapSort(arr) + expect = []int{1,1} + + if !reflect.DeepEqual(arr, expect) { + t.Fatalf("test failed:%v", arr) + } +} diff --git a/go/sort/heap/heap.go b/go/sort/heap/heap.go new file mode 100644 index 0000000..fae9204 --- /dev/null +++ b/go/sort/heap/heap.go @@ -0,0 +1,45 @@ +package heap + +func handleHeap(arr []int, idx int) { + for arr[idx] > arr[(idx-1)/2] { + parent := (idx - 1) / 2 + arr[idx], arr[parent] = arr[parent], arr[idx] + idx = parent + } +} + +func buildHeap(arr []int) { + for i := 0; i < len(arr); i++ { + handleHeap(arr, i) + } +} + +func sortHead(arr []int, heapSize int) { + parent := 0 + for { + idx := 2*parent + 1 + if idx >= heapSize { + return + } + right := 2*parent + 2 + if right < heapSize && arr[right] > arr[idx] { + idx = right + } + + if arr[parent] > arr[idx] { + return + } + + arr[parent], arr[idx] = arr[idx], arr[parent] + parent = idx + } +} + +func sort(arr []int) { + buildHeap(arr) + + for i := len(arr) - 1; i > 0; i-- { + arr[0], arr[i] = arr[i], arr[0] + sortHead(arr, i) + } +} diff --git a/go/sort/heap/heap_test.go b/go/sort/heap/heap_test.go new file mode 100644 index 0000000..7c88027 --- /dev/null +++ b/go/sort/heap/heap_test.go @@ -0,0 +1,9 @@ +package heap + +import "testing" + +func TestSort(t *testing.T) { + arr := []int{3, -1, 45, 3, 5, 98, 12, 2, 10} + sort(arr) + t.Logf("%v", arr) +} diff --git a/go/sort/merge/code.go b/go/sort/merge/code.go new file mode 100644 index 0000000..c4aac5e --- /dev/null +++ b/go/sort/merge/code.go @@ -0,0 +1,47 @@ +package merge + +func mergeSort(arr []int) { + merge(arr, 0, len(arr)-1) +} + +func merge(arr []int, start, end int) { + if end - start < 1 { + return + } + + mid := start + (end-start)>>1 + + merge(arr, start, mid) + merge(arr, mid+1, end) + + tmpArr := make([]int, end-start+1) + l := start + r := mid+1 + idx := 0 + for l <= mid && r <= end { + if arr[l] < arr[r] { + tmpArr[idx] = arr[l] + l++ + }else { + tmpArr[idx] = arr[r] + r++ + } + idx++ + } + + for l <= mid { + tmpArr[idx] = arr[l] + l++ + idx++ + } + + for r <= end { + tmpArr[idx] = arr[r] + r++ + idx++ + } + + for i := start; i <= end; i++ { + arr[i] = tmpArr[i-start] + } +} \ No newline at end of file diff --git a/go/sort/merge/code_test.go b/go/sort/merge/code_test.go new file mode 100644 index 0000000..ed06bde --- /dev/null +++ b/go/sort/merge/code_test.go @@ -0,0 +1,31 @@ +package merge + +import ( + "reflect" + "testing" +) + +func TestMergeSort(t *testing.T) { + arr := []int{1, 6, 5, 4} + mergeSort(arr) + expect := []int{1, 4, 5, 6} + if !reflect.DeepEqual(arr, expect) { + t.Fatalf("test failed:%v", arr) + } + + arr = []int{1, 7, 3, 5, 3, 6, 9} + mergeSort(arr) + expect = []int{1, 3, 3, 5, 6,7, 9} + if !reflect.DeepEqual(arr, expect) { + t.Fatalf("test failed:%v", arr) + } + + + arr = []int{1,1} + mergeSort(arr) + expect = []int{1,1} + if !reflect.DeepEqual(arr, expect) { + t.Fatalf("test failed:%v", arr) + } +} + diff --git a/go/sort/quick/code.go b/go/sort/quick/code.go new file mode 100644 index 0000000..e33d56f --- /dev/null +++ b/go/sort/quick/code.go @@ -0,0 +1,40 @@ +package quick + +import "math/rand" + +func swap(arr []int, i, j int) { + arr[i], arr[j] = arr[j], arr[i] +} + +func quickSort(arr []int) { + quick(arr, 0, len(arr)-1) +} + +func partiton(nums []int, start, end int) int { + idx := rand.Intn(end-start+1) + start + + nums[idx], nums[start] = nums[start], nums[idx] + target := nums[start] + + idx = start + 1 + for i := start + 1; i <= end; i++ { + if nums[i] < target { + nums[i], nums[idx] = nums[idx], nums[i] + idx++ + } + } + idx-- + + nums[start], nums[idx] = nums[idx], nums[start] + return idx +} + +func quick(arr []int, start, end int) { + if end-start < 1 { + return + } + + idx := partiton(arr, start, end) + quick(arr, start, idx-1) + quick(arr, idx+1, end) +} diff --git a/go/sort/quick/code_test.go b/go/sort/quick/code_test.go new file mode 100644 index 0000000..39d9242 --- /dev/null +++ b/go/sort/quick/code_test.go @@ -0,0 +1,47 @@ +package quick + +import ( + "math/rand" + "reflect" + "testing" +) + +func TestQickSort(t *testing.T) { + arr := []int{1, 6, 5, 4} + quickSort(arr) + expect := []int{1, 4, 5, 6} + if !reflect.DeepEqual(arr, expect) { + t.Fatalf("test failed:%v", arr) + } + + arr = []int{1, 7, 3, 5, 3, 6, 9} + quickSort(arr) + expect = []int{1, 3, 3, 5, 6, 7, 9} + if !reflect.DeepEqual(arr, expect) { + t.Fatalf("test failed:%v", arr) + } + + arr = []int{1, 1} + quickSort(arr) + expect = []int{1, 1} + if !reflect.DeepEqual(arr, expect) { + t.Fatalf("test failed:%v", arr) + } + + for i := 0; i < 1000; i++ { + cnt := 50 + rand.Intn(300) + nums := make([]int, cnt) + for j := 0; j < len(nums); j++ { + nums[j] = rand.Intn(cnt + 100) + } + + quickSort(nums) + + for j := 1; j < len(nums); j++ { + if nums[j] < nums[j-1] { + t.Fatalf("test failed:%v", nums) + } + } + } + +} diff --git a/go/stack/132-pattern.go b/go/stack/132-pattern.go new file mode 100644 index 0000000..99b958b --- /dev/null +++ b/go/stack/132-pattern.go @@ -0,0 +1,38 @@ +package stack + +func find132pattern(nums []int) bool { + if len(nums) < 3 { + return false + } + + min := make([]int, len(nums)) + min[0] = nums[0] + for i := 1; i < len(nums); i++ { + min[i] = min[i-1] + if nums[i] < min[i] { + min[i] = nums[i] + } + } + + st := make([]int, len(nums)) + top := -1 + + for j := len(nums) -1; j >= 0; j-- { + if nums[j] <= min[j] { + continue + } + + for top > -1 && min[j] >= st[top] { + top-- + } + + if top > -1 && nums[j] > st[top] { + return true + } + + top++ + st[top] = nums[j] + } + + return false +} diff --git a/go/stack/132-pattern_test.go b/go/stack/132-pattern_test.go new file mode 100644 index 0000000..5abb314 --- /dev/null +++ b/go/stack/132-pattern_test.go @@ -0,0 +1,25 @@ +package stack + +import "testing" + +func TestFind132pattern(t *testing.T) { + nums := []int{1, 2, 3, 4} + if find132pattern(nums) == true { + t.Fatalf("test failed") + } + + nums = []int{1,0,1,-4,-3} + if find132pattern(nums) == true { + t.Fatalf("test failed") + } + + nums = []int{3, 1, 4, 2} + if find132pattern(nums) == false { + t.Fatalf("test failed") + } + + nums = []int{-1, 3, 2, 0} + if find132pattern(nums) == false { + t.Fatalf("test failed") + } +} diff --git a/go/stack/backspace-string-compare.go b/go/stack/backspace-string-compare.go new file mode 100644 index 0000000..30ec6a5 --- /dev/null +++ b/go/stack/backspace-string-compare.go @@ -0,0 +1,32 @@ +package stack + +func toStack(s string) (st []int32, top int) { + top = -1 + st = make([]int32, len(s)) + for _, val := range s { + if val != '#' { + top++ + st[top] = val + }else if top > -1{ + top-- + } + } + + return +} + +func backspaceCompare(S string, T string) bool { + st1, top1 := toStack(S) + st2, top2 := toStack(T) + + if top1 != top2 { + return false + } + + for idx := 0; idx <= top1; idx++ { + if st1[idx] != st2[idx] { + return false + } + } + return true +} diff --git a/go/stack/backspace-string-compare_test.go b/go/stack/backspace-string-compare_test.go new file mode 100644 index 0000000..c51abde --- /dev/null +++ b/go/stack/backspace-string-compare_test.go @@ -0,0 +1,31 @@ +package stack + +import "testing" + +func TestBackspaceCompare(t *testing.T) { + S := "ab#c" + T := "ad#c" + if !backspaceCompare(S, T) { + t.Fatalf("test failed ") + } + + S = "ab##" + T = "c#d#" + if !backspaceCompare(S, T) { + t.Fatalf("test failed ") + } + + + S = "a##c" + T = "#a#c" + if !backspaceCompare(S, T) { + t.Fatalf("test failed ") + } + + + S = "a#c" + T = "b" + if backspaceCompare(S, T) { + t.Fatalf("test failed ") + } +} diff --git a/go/stack/baseball-game.go b/go/stack/baseball-game.go new file mode 100644 index 0000000..faaeb36 --- /dev/null +++ b/go/stack/baseball-game.go @@ -0,0 +1,34 @@ +package stack + +import "strconv" + +func calPoints(ops []string) int { + st := make([]int, len(ops)) + top := -1 + + for _, s := range ops { + switch s { + case "C": + top-- + case "D": + val := st[top] * 2 + top++ + st[top] = val + case "+": + val := st[top-1] + st[top] + top++ + st[top] = val + default: + val,_ := strconv.ParseInt(s, 10, 64) + top++ + st[top] = int(val) + } + } + + var sum int + for idx := 0; idx <= top; idx++ { + sum += st[idx] + } + + return sum +} diff --git a/go/stack/baseball-game_test.go b/go/stack/baseball-game_test.go new file mode 100644 index 0000000..aa9caf6 --- /dev/null +++ b/go/stack/baseball-game_test.go @@ -0,0 +1,18 @@ +package stack + +import "testing" + +func TestCalPoints(t *testing.T) { + ops := []string{"5","2","C","D","+"} + + sum := calPoints(ops) + if sum != 30 { + t.Fatalf("test failed: %d",sum) + } + + ops = []string{"5","-2","4","C","D","9","+","+"} + sum = calPoints(ops) + if sum != 27 { + t.Fatalf("test failed: %d",sum) + } +} diff --git a/go/stack/basic-calculator-ii/basic-calculator-ii.go b/go/stack/basic-calculator-ii/basic-calculator-ii.go new file mode 100644 index 0000000..d78b69c --- /dev/null +++ b/go/stack/basic-calculator-ii/basic-calculator-ii.go @@ -0,0 +1,122 @@ +package basic_calculator_ii + +import ( + "strconv" +) + +func calculate(s string) int { + isOp := true + isNeg := false + numbers := make([]int, len(s)) + ntop := -1 + + ops := make([]int32, len(s)) + otop := -1 + + for i := 0; i < len(s); i++ { + c := int32(s[i]) + if c == ' ' { + continue + } + + if isNumber(c) { + j := i + 1 + for j < len(s){ + if !isNumber(int32(s[j])) { + break + } + j++ + } + + tmp := s[i:j] + val, _ := strconv.Atoi(tmp) + if isNeg { + val = -val + } + ntop++ + numbers[ntop] = val + i = j-1 + isNeg = false + isOp = false + continue + } + + if isOp { + if c == '-' { + isNeg = true + } + continue + } + + if c == '(' { + otop++ + ops[otop] = c + continue + } + + if c == ')' { + for ops[otop] != '(' { + ntop,otop = calc(numbers, ntop, ops, otop) + } + otop-- + continue + } + + for otop > -1 && isHigh(ops[otop], c) { + ntop,otop = calc(numbers, ntop, ops, otop) + } + + otop++ + ops[otop] = c + isOp = true + } + + for otop > -1 { + ntop,otop = calc(numbers, ntop, ops, otop) + } + + return numbers[0] +} + +func isNumber (c int32) bool { + if c >= '0' && c <= '9' { + return true + } + + return false +} + +func calc(nums []int, ntop int, ops []int32, otop int)(int, int) { + op := ops[otop] + otop-- + right := nums[ntop] + ntop-- + left := nums[ntop] + ntop-- + var val int + switch op { + case '*': + val = left * right + case '/': + val = left / right + case '-': + val = left - right + case '+': + val = left + right + } + + ntop++ + nums[ntop] = val + return ntop, otop +} + +func isHigh(left, right int32) bool { + if left == '*' || left == '/' { + return true + } + + if right == '+' || right == '-' { + return true + } + return false +} \ No newline at end of file diff --git a/go/stack/basic-calculator-ii/basic-calculator-ii_test.go b/go/stack/basic-calculator-ii/basic-calculator-ii_test.go new file mode 100644 index 0000000..8a3b484 --- /dev/null +++ b/go/stack/basic-calculator-ii/basic-calculator-ii_test.go @@ -0,0 +1,37 @@ +package basic_calculator_ii + +import ( + "testing" +) + +func TestCalculate(t *testing.T) { + s := "12-3*4" + val := calculate(s) + if val != 0 { + t.Fatalf("test failed: %d", val) + } + + s = " -3 +2*2 " + val = calculate(s) + if val != 1 { + t.Fatalf("test failed: %d", val) + } + + s = " 3/2 " + val = calculate(s) + if val != 1 { + t.Fatalf("test failed: %d", val) + } + + s = "3+5 / 2" + val = calculate(s) + if val != 5 { + t.Fatalf("test failed: %d", val) + } + + s = "35" + val = calculate(s) + if val != 35 { + t.Fatalf("test failed: %d", val) + } +} diff --git a/go/stack/basic-calculator.go b/go/stack/basic-calculator.go new file mode 100644 index 0000000..47624cf --- /dev/null +++ b/go/stack/basic-calculator.go @@ -0,0 +1,139 @@ +package stack + +import ( + "strconv" +) + +func isDigit(val int32) bool { + if val >= '0' && val <= '9' { + return true + } + + return false +} +var opW = map[int32]int { + '(': 0, + '-': 1, + '+': 1, + '*': 2, + '/':2, +} + +func getResult(op1, op2 int, op int32)(val int) { + switch op { + case '-': + val = op1 - op2 + case '+': + val = op1 + op2 + case '*': + val = op1 * op2 + case '/': + val = op1/op2 + } + + return val +} + +func calculate(s string) int { + st := make([]int, len(s)) + top := -1 + + opSt := make([]int32, len(s)/2) + opTop := -1 + + for i := 0; i < len(s); i++ { + c := int32(s[i]) + if c == ' ' { + continue + } + + if isDigit(c) { + j := i+1 + for j -1 && opW[opSt[opTop]] >= opW[c]) { + for opTop > -1 { + topC := opSt[opTop] + if topC == '(' || opW[topC] < opW[c] { + break + } + + opTop-- + + var result int + if top >= 1 { + op2 := st[top] + top-- + op1 := st[top] + top-- + + result = getResult(op1, op2, topC) + }else { + result = st[top] + top-- + if topC == '-' { + result = -result + } + } + + + top++ + st[top] = result + } + } + + if c == ')' { + opTop-- + continue + } + + + + opTop++ + opSt[opTop] = c + } + + for opTop > -1 { + topC := opSt[opTop] + opTop-- + + var result int + if top >= 1 { + op2 := st[top] + top-- + op1 := st[top] + top-- + + result = getResult(op1, op2, topC) + }else { + result = st[top] + top-- + if topC == '-' { + result = -result + } + } + + top++ + st[top] = result + } + + return st[0] +} diff --git a/go/stack/basic-calculator_test.go b/go/stack/basic-calculator_test.go new file mode 100644 index 0000000..ea00614 --- /dev/null +++ b/go/stack/basic-calculator_test.go @@ -0,0 +1,41 @@ +package stack + +import "testing" + +func TestCalculate(t *testing.T) { + s := "1 + 1" + val := calculate(s) + if val != 2 { + t.Fatalf("test failed: %d", val) + } + + s = "- (3 + (4 + 5))" + val = calculate(s) + if val != -12 { + t.Fatalf("test failed: %d", val) + } + + s = "-2 +1 " + val = calculate(s) + if val != -1 { + t.Fatalf("test failed: %d", val) + } + + s = "1 * 5" + val = calculate(s) + if val != 5 { + t.Fatalf("test failed: %d", val) + } + + s = "2-1 + 2 " + val = calculate(s) + if val != 3 { + t.Fatalf("test failed: %d", val) + } + + s = "(1+(4+5+2)-3)+(6+8)" + val = calculate(s) + if val != 23 { + t.Fatalf("test failed: %d", val) + } +} diff --git a/go/stack/binary-tree-postorder-traversal.go b/go/stack/binary-tree-postorder-traversal.go new file mode 100644 index 0000000..74a61db --- /dev/null +++ b/go/stack/binary-tree-postorder-traversal.go @@ -0,0 +1,41 @@ +package stack + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func postorderTraversal(root *TreeNode) []int { + var result []int + + if root == nil { + return result + } + + st := New() + st.Push(root) + for !st.IsEmpty() { + tmp := st.Pop().(*TreeNode) + result = append(result, tmp.Val) + + cur := tmp.Left + if cur != nil { + st.Push(cur) + cur = cur.Left + } + + cur = tmp.Right + if cur != nil { + st.Push(cur) + cur = cur.Right + } + } + i, j := 0, len(result)-1 + for i < j { + result[i], result[j] = result[j], result[i] + i++ + j-- + } + return result +} diff --git a/go/stack/binary-tree-postorder-traversal[2].go b/go/stack/binary-tree-postorder-traversal[2].go new file mode 100644 index 0000000..1ecf327 --- /dev/null +++ b/go/stack/binary-tree-postorder-traversal[2].go @@ -0,0 +1,33 @@ +package stack + +func postorderTraversal2(root *TreeNode) []int { + var result []int + + if root == nil { + return result + } + + st := New() + st.Push(root) + var pre *TreeNode + for !st.IsEmpty() { + cur := st.Top().(*TreeNode) + if (cur.Left == nil && cur.Right == nil) || + (pre != nil && (cur.Left == pre || cur.Right == pre)){ + result = append(result, cur.Val) + st.Pop() + pre = cur + }else { + if cur.Right != nil { + st.Push(cur.Right) + } + + if cur.Left != nil { + st.Push(cur.Left) + } + } + } + + return result +} + diff --git a/go/stack/binary-tree-postorder-traversal_test.go b/go/stack/binary-tree-postorder-traversal_test.go new file mode 100644 index 0000000..852ad29 --- /dev/null +++ b/go/stack/binary-tree-postorder-traversal_test.go @@ -0,0 +1,51 @@ +package stack + +import "testing" + +func TestPostorderTraversal(t *testing.T) { + root := &TreeNode{ + Val: 3, + } + + right := &TreeNode{ + Val: 2, + } + + root.Right = right + l2 := &TreeNode{ + Val: 1, + } + + right.Left = l2 + + result := postorderTraversal(root) + for idx, val := range result { + if val != idx +1 { + t.Fatalf("test failed, idx: %d, result: %v", idx, result) + } + } +} + +func TestPostorderTraversal2(t *testing.T) { + root := &TreeNode{ + Val: 3, + } + + right := &TreeNode{ + Val: 2, + } + + root.Right = right + l2 := &TreeNode{ + Val: 1, + } + + right.Left = l2 + + result := postorderTraversal2(root) + for idx, val := range result { + if val != idx +1 { + t.Fatalf("test failed, idx: %d, result: %v", idx, result) + } + } +} diff --git a/go/stack/check-if-word-is-valid-after-substitutions.go b/go/stack/check-if-word-is-valid-after-substitutions.go new file mode 100644 index 0000000..f6941c1 --- /dev/null +++ b/go/stack/check-if-word-is-valid-after-substitutions.go @@ -0,0 +1,27 @@ +package stack + +func isValid1(s string) bool { + st := New() + for _, c := range s { + if c < 'c' { + st.Push(c) + continue + } + + if st.Len() < 2 { + return false + } + + b := st.Pop() + if b.(int32) != 'b' { + return false + } + + a := st.Pop() + if a.(int32) != 'a' { + return false + } + } + + return st.Len() == 0 +} diff --git a/go/stack/check-if-word-is-valid-after-substitutions_test.go b/go/stack/check-if-word-is-valid-after-substitutions_test.go new file mode 100644 index 0000000..4d5c2fc --- /dev/null +++ b/go/stack/check-if-word-is-valid-after-substitutions_test.go @@ -0,0 +1,28 @@ +package stack + +import "testing" + +func TestIsValid1(t *testing.T) { + var s string + s = "aabcbc" + if !isValid1(s) { + t.Fatalf("test failed") + } + + s = "abcabcababcc" + if !isValid1(s) { + t.Fatalf("test failed") + } + + + s = "abccba" + if isValid1(s) { + t.Fatalf("test failed") + } + + + s = "cababc" + if isValid1(s) { + t.Fatalf("test failed") + } +} diff --git a/go/stack/exclusive-time-of-functions.go b/go/stack/exclusive-time-of-functions.go new file mode 100644 index 0000000..185739f --- /dev/null +++ b/go/stack/exclusive-time-of-functions.go @@ -0,0 +1,41 @@ +package stack + +import ( + "strconv" + "strings" +) + +func parseLog(str string)(id int, op string, t int) { + arr := strings.Split(str, ":") + id, _ = strconv.Atoi(arr[0]) + op = arr[1] + t, _ = strconv.Atoi(arr[2]) + + return +} + +func exclusiveTime(n int, logs []string) []int { + arr := make([]int, n) + st := make([]int, len(logs)) + top := -1 + prev := 0 + + for _, s := range logs { + id, op, t := parseLog(s) + if op == "start" { + if top > -1 { + arr[st[top]] += t - prev + } + top++ + st[top] = id + prev = t + continue + } + + arr[st[top]] += t - prev + 1 + top-- + prev = t + 1 + } + + return arr +} diff --git a/go/stack/exclusive-time-of-functions_test.go b/go/stack/exclusive-time-of-functions_test.go new file mode 100644 index 0000000..a9dfd26 --- /dev/null +++ b/go/stack/exclusive-time-of-functions_test.go @@ -0,0 +1,18 @@ +package stack + +import "testing" + +func TestExclusiveTime(t *testing.T) { + n := 2 + logs := []string { + "0:start:0", + "1:start:2", + "1:end:5", + "0:end:6", + } + + arr := exclusiveTime(n, logs) + if arr[0] != 3 || arr[1] != 4 { + t.Fatalf("test failed: %+v", arr) + } +} diff --git a/go/stack/find-the-most-competitive-subsequence.go b/go/stack/find-the-most-competitive-subsequence.go new file mode 100644 index 0000000..0afb8bf --- /dev/null +++ b/go/stack/find-the-most-competitive-subsequence.go @@ -0,0 +1,18 @@ +package stack + +func mostCompetitive(nums []int, k int) []int { + st := make([]int, len(nums)) + top := -1 + + for i := 0; i < len(nums); i++ { + val := nums[i] + for top > -1 && val < st[top] &&(top + len(nums) - i) >= k { + top-- + } + + top++ + st[top] = val + } + + return st[:k] +} \ No newline at end of file diff --git a/go/stack/find-the-most-competitive-subsequence_test.go b/go/stack/find-the-most-competitive-subsequence_test.go new file mode 100644 index 0000000..805a01a --- /dev/null +++ b/go/stack/find-the-most-competitive-subsequence_test.go @@ -0,0 +1,35 @@ +package stack + +import "testing" + +func TestMostCompetitive(t *testing.T) { + nums := []int{3,5,2,6} + k := 2 + target := []int{2, 6} + result := mostCompetitive(nums, k) + + if len(target) != len(result) { + t.Fatalf("tesst failed, %+v : %+v", target, result) + } + + for idx, val := range target { + if result[idx] != val { + t.Fatalf("test failed, %d:%d", idx, result[idx]) + } + } + + + nums = []int{2,4,3,3,5,4,9,6} + k = 4 + target = []int{2,3,3,4} + result = mostCompetitive(nums, k) + if len(target) != len(result) { + t.Fatalf("tesst failed, %+v : %+v", target, result) + } + + for idx, val := range target { + if result[idx] != val { + t.Fatalf("test failed, %d:%d", idx, result[idx]) + } + } +} diff --git a/go/stack/implement-queue-using-stacks-lcci.go b/go/stack/implement-queue-using-stacks-lcci.go new file mode 100644 index 0000000..8f91ea5 --- /dev/null +++ b/go/stack/implement-queue-using-stacks-lcci.go @@ -0,0 +1,79 @@ +package stack + +type MyQueue struct { + st []int + top int + dSt []int + dTop int +} + + +/** Initialize your data structure here. */ +func Constructor() MyQueue { + return MyQueue{ + st : make([]int, 16), + top: -1, + + dSt : make([]int, 16), + dTop: -1, + } +} + + +func (this *MyQueue) MallocStack(st []int, top int)([]int) { + if top >= len(st)-1 { + newSt := make([]int, 2 * len(st)) + copy(newSt,st) + return newSt + } + + return st +} + +/** Push element x to the back of queue. */ +func (this *MyQueue) Push(x int) { + this.st = this.MallocStack(this.st, this.top) + + this.top++ + this.st[this.top] = x +} + + +/** Removes the element from in front of queue and returns that element. */ +func (this *MyQueue) Pop() int { + val := this.Peek() + this.dTop-- + return val +} + + +/** Get the front element. */ +func (this *MyQueue) Peek() int { + if this.dTop == -1 { + for this.top > -1 { + this.dSt = this.MallocStack(this.dSt, this.dTop) + this.dTop++ + this.dSt[this.dTop] = this.st[this.top] + this.top-- + } + } + + val := this.dSt[this.dTop] + return val +} + + +/** Returns whether the queue is empty. */ +func (this *MyQueue) Empty() bool { + return this.top <= -1 && this.dTop <= -1 +} + + +/** + * Your MyQueue object will be instantiated and called as such: + * obj := Constructor(); + * obj.Push(x); + * param_2 := obj.Pop(); + * param_3 := obj.Peek(); + * param_4 := obj.Empty(); + */ \ No newline at end of file diff --git a/go/stack/implement-queue-using-stacks-lcci_test.go b/go/stack/implement-queue-using-stacks-lcci_test.go new file mode 100644 index 0000000..ae9d886 --- /dev/null +++ b/go/stack/implement-queue-using-stacks-lcci_test.go @@ -0,0 +1,20 @@ +package stack + +import "testing" + +func TestQueue(t *testing.T) { + queue := Constructor() + + queue.Push(1) + queue.Push(2) + queue.Push(3) + val := queue.Peek() + if val != 1 { + t.Fatalf("test failed, val: %d", val) + } + + queue.Pop() + if queue.Empty() { + t.Fatalf("test failed") + } +} diff --git a/go/stack/longest-well-performing-interval.go b/go/stack/longest-well-performing-interval.go new file mode 100644 index 0000000..96b15e0 --- /dev/null +++ b/go/stack/longest-well-performing-interval.go @@ -0,0 +1,39 @@ +package stack + +func longestWPI(hours []int) int { + preSum :=[]int{0} + sum := 0 + + + for _, h := range hours { + if h > 8 { + sum++ + }else { + sum-- + } + + preSum = append(preSum, sum) + + + } + + st := make([]int, 0) + for idx, val := range preSum { + if len(st) == 0 || preSum[st[len(st)-1]] > val { + st = append(st, idx) + } + } + + maxWPI := 0 + for i := 0; i idx; j-- { + if preSum[j] >preSum[idx] && j - idx >maxWPI { + maxWPI = j - idx + break + } + } + } + + return maxWPI +} \ No newline at end of file diff --git a/go/stack/longest-well-performing-interval_test.go b/go/stack/longest-well-performing-interval_test.go new file mode 100644 index 0000000..dbe2221 --- /dev/null +++ b/go/stack/longest-well-performing-interval_test.go @@ -0,0 +1,25 @@ +package stack + +import "testing" + +func TestLongestWPI(t *testing.T) { + arr := []int{9,9,6,0,6,6,9} + + wpi := longestWPI(arr) + if wpi != 3 { + t.Fatalf("test failed:%d", wpi) + } + + arr = []int{6,9,9} + wpi = longestWPI(arr) + if wpi != 3 { + t.Fatalf("test failed:%d", wpi) + } + + arr = []int{9,6, 9} + + wpi = longestWPI(arr) + if wpi != 3 { + t.Fatalf("test failed:%d", wpi) + } +} diff --git a/go/stack/minimum-remove-to-make-valid-parentheses.go b/go/stack/minimum-remove-to-make-valid-parentheses.go new file mode 100644 index 0000000..8ace7fc --- /dev/null +++ b/go/stack/minimum-remove-to-make-valid-parentheses.go @@ -0,0 +1,32 @@ +package stack + +func minRemoveToMakeValid(s string) string { + st := make([]int32, len(s)) + top := -1 + + idSt := make([]int, len(s)) + idTop := -1 + + for idx, v := range s { + if v == '(' || (v == ')' && (top == -1 || st[top] != '(') ){ + top++ + st[top] = v + + idTop++ + idSt[idTop] = idx + continue + }else if v == ')' { + top-- + idTop-- + } + } + + for idTop > -1 { + idx := idSt[idTop] + idTop-- + + s = s[:idx] + s[idx+1:] + } + + return s +} diff --git a/go/stack/minimum-remove-to-make-valid-parentheses_test.go b/go/stack/minimum-remove-to-make-valid-parentheses_test.go new file mode 100644 index 0000000..7c209d7 --- /dev/null +++ b/go/stack/minimum-remove-to-make-valid-parentheses_test.go @@ -0,0 +1,35 @@ +package stack + +import "testing" + +func TestMinRemoveToMakeValid(t *testing.T) { + var s, result, expect string + + s = "lee(t(c)o)de)" + expect = "lee(t(c)o)de" + result = minRemoveToMakeValid(s) + if result != expect { + t.Fatalf("test failed: %s", result) + } + + s = "a)b(c)d" + expect = "ab(c)d" + result = minRemoveToMakeValid(s) + if result != expect { + t.Fatalf("test failed: %s", result) + } + + s = "))((" + expect = "" + result = minRemoveToMakeValid(s) + if result != expect { + t.Fatalf("test failed: %s", result) + } + + s = "(a(b(c)d)" + expect = "a(b(c)d)" + result = minRemoveToMakeValid(s) + if result != expect { + t.Fatalf("test failed: %s", result) + } +} diff --git a/go/stack/next-greater-node-in-linked-list.go b/go/stack/next-greater-node-in-linked-list.go new file mode 100644 index 0000000..df40a88 --- /dev/null +++ b/go/stack/next-greater-node-in-linked-list.go @@ -0,0 +1,31 @@ +package stack + +type ListNode struct { + Val int + Next *ListNode +} + +func nextLargerNodes(head *ListNode) []int { + arr := make([]int, 0) + for head != nil { + arr = append(arr, head.Val) + head = head.Next + } + + ret := make([]int, len(arr)) + st := make([]int, len(arr)) + top := -1 + for i := len(arr)-1; i >= 0; i-- { + for top > -1 && arr[i] >= st[top] { + top-- + } + + if top > -1 { + ret[i] = st[top] + } + top++ + st[top] = arr[i] + } + + return ret +} diff --git a/go/stack/next-greater-node-in-linked-list_test.go b/go/stack/next-greater-node-in-linked-list_test.go new file mode 100644 index 0000000..52c0906 --- /dev/null +++ b/go/stack/next-greater-node-in-linked-list_test.go @@ -0,0 +1,57 @@ +package stack + +import ( + "testing" +) + +func createLargerNodes(arr []int) (head *ListNode) { + var node *ListNode + for i := len(arr) - 1; i >= 0; i-- { + tmp := &ListNode{ + Val: arr[i], + Next: node, + } + + node = tmp + } + + head = node + return +} +func TestNextLargerNodes(t *testing.T) { + head := createLargerNodes([]int{2,1,5}) + target := []int{5,5,0} + arr := nextLargerNodes(head) + for i := 0; i < len(arr); i++ { + if arr[i] != target[i] { + t.Fatalf("test failed, [%d]:%d - %d", i,arr[i], target[i]) + } + } + + head = createLargerNodes([]int{2,2,5}) + target = []int{5,5,0} + arr = nextLargerNodes(head) + for i := 0; i < len(arr); i++ { + if arr[i] != target[i] { + t.Fatalf("test failed, [%d]:%d - %d", i,arr[i], target[i]) + } + } + + head = createLargerNodes([]int{2,7,4,3,5}) + target = []int{7,0,5,5,0} + arr = nextLargerNodes(head) + for i := 0; i < len(arr); i++ { + if arr[i] != target[i] { + t.Fatalf("test failed, [%d]:%d - %d", i,arr[i], target[i]) + } + } + + head = createLargerNodes([]int{1,7,5,1,9,2,5,1}) + target = []int{7,9,9,9,0,5,0,0} + arr = nextLargerNodes(head) + for i := 0; i < len(arr); i++ { + if arr[i] != target[i] { + t.Fatalf("test failed, [%d]:%d - %d", i,arr[i], target[i]) + } + } +} diff --git a/go/stack/reverse-substrings-between-each-pair-of-parentheses.go b/go/stack/reverse-substrings-between-each-pair-of-parentheses.go new file mode 100644 index 0000000..fec1c37 --- /dev/null +++ b/go/stack/reverse-substrings-between-each-pair-of-parentheses.go @@ -0,0 +1,37 @@ +package stack + + +func reverseParentheses(s string) string { + var ret string + + st := make([]int32, len(s)) + top := -1 + + for _, v := range s { + if v != ')' { + top++ + st[top] = v + continue + } + + var tmp string + for top > -1 { + tc := st[top] + top-- + if tc == '(' { + break + } + tmp += string(tc) + } + + for _, c := range tmp { + top++ + st[top] = c + } + } + + for i := 0; i <= top; i++ { + ret += string(st[i]) + } + return ret +} \ No newline at end of file diff --git a/go/stack/reverse-substrings-between-each-pair-of-parentheses_test.go b/go/stack/reverse-substrings-between-each-pair-of-parentheses_test.go new file mode 100644 index 0000000..04ecd06 --- /dev/null +++ b/go/stack/reverse-substrings-between-each-pair-of-parentheses_test.go @@ -0,0 +1,29 @@ +package stack + +import "testing" + +func TestReverseParentheses(t *testing.T) { + s := "(abcd)" + rs := reverseParentheses(s) + if rs != "dcba" { + t.Fatalf("test failed: %s", rs) + } + + s = "(u(love)i)" + rs = reverseParentheses(s) + if rs != "iloveu" { + t.Fatalf("test failed: %s", rs) + } + + s = "(ed(et(oc))el)" + rs = reverseParentheses(s) + if rs != "leetcode" { + t.Fatalf("test failed: %s", rs) + } + + s = "a(bcdefghijkl(mno)p)q" + rs = reverseParentheses(s) + if rs != "apmnolkjihgfedcbq" { + t.Fatalf("test failed: %s", rs) + } +} diff --git a/go/stack/score-of-parentheses.go b/go/stack/score-of-parentheses.go new file mode 100644 index 0000000..fc17ed7 --- /dev/null +++ b/go/stack/score-of-parentheses.go @@ -0,0 +1,49 @@ +package stack + +func max(v1, v2 int) int { + if v1 > v2 { + return v1 + } + + return v2 +} + +func scoreOfParentheses(S string) int { + st := make([]int, len(S)) + top := 0 + st[top] = 0 + + for _, s := range S { + if s == '(' { + top++ + st[top] = 0 + continue + } + + cur := st[top] + top-- + st[top] += max(cur*2, 1) + + } + + return st[top] +} + +func scoreOfParentheses1(S string) int { + dep := 0 + score := 0 + + for i := 0; i < len(S); i++ { + if S[i] == '(' { + dep++ + continue + } + + dep-- + if S[i-1] == '(' { + score += (1 << dep) + } + } + + return score +} diff --git a/go/stack/score-of-parentheses_test.go b/go/stack/score-of-parentheses_test.go new file mode 100644 index 0000000..f9502b8 --- /dev/null +++ b/go/stack/score-of-parentheses_test.go @@ -0,0 +1,56 @@ +package stack + +import "testing" + +func TestScoreOfParentheses(t *testing.T) { + S := "()" + val := scoreOfParentheses(S) + if val != 1 { + t.Fatalf("test failed: %d", val) + } + + S = "(())" + val = scoreOfParentheses(S) + if val != 2 { + t.Fatalf("test failed: %d", val) + } + + S = "()()" + val = scoreOfParentheses(S) + if val != 2 { + t.Fatalf("test failed: %d", val) + } + + S = "(()(()))" + val = scoreOfParentheses(S) + if val != 6 { + t.Fatalf("test failed: %d", val) + } + +} + +func TestScoreOfParentheses1(t *testing.T) { + S := "()" + val := scoreOfParentheses1(S) + if val != 1 { + t.Fatalf("test failed: %d", val) + } + + S = "(())" + val = scoreOfParentheses1(S) + if val != 2 { + t.Fatalf("test failed: %d", val) + } + + S = "()()" + val = scoreOfParentheses1(S) + if val != 2 { + t.Fatalf("test failed: %d", val) + } + + S = "(()(()))" + val = scoreOfParentheses1(S) + if val != 6 { + t.Fatalf("test failed: %d", val) + } +} \ No newline at end of file diff --git a/go/stack/stack.go b/go/stack/stack.go new file mode 100644 index 0000000..0d91d4c --- /dev/null +++ b/go/stack/stack.go @@ -0,0 +1,41 @@ +package stack + +import "container/list" + +type Stack struct { + data *list.List +} + +func New() *Stack { + return &Stack{ + data:list.New(), + } +} + +func (s *Stack)Push(v interface{}) { + s.data.PushBack(v) +} + +func (s *Stack)Pop()interface{} { + e := s.data.Back() + s.data.Remove(e) + + return e.Value +} + +func (s *Stack)Top() interface{} { + e := s.data.Back() + return e.Value +} + +func (s *Stack)IsEmpty() bool { + if s.data.Len() == 0 { + return true + } + + return false +} + +func (s *Stack)Len() int { + return s.data.Len() +} diff --git a/go/stack/valid-parentheses.go b/go/stack/valid-parentheses.go new file mode 100644 index 0000000..f8340e2 --- /dev/null +++ b/go/stack/valid-parentheses.go @@ -0,0 +1,63 @@ +package stack + +func isLeft(c int32) bool { + if c == '[' || c == '(' || c == '{' { + return true + } + + return false +} + +//isMatch +func isMatch(c1, c2 int32) bool { + if getMatch(c1) == c2 || getMatch(c2) == c1 { + return true + } + + return false +} + + +func getMatch(left int32) int32 { + if left == '[' { + return']' + } + + if left == '(' { + return ')' + } + + if left == '{'{ + return '}' + } + + return 0 +} + +func isValid(s string) bool { + st := New() + + for _, c1 := range s { + if isLeft(c1) { + st.Push(c1) + continue + } + + if st.IsEmpty() { + return false + } + + c2 := st.Top().(int32) + if !isMatch(c1, c2) { + return false + } + + st.Pop() + } + + if !st.IsEmpty() { + return false + } + + return true +} diff --git a/go/stack/valid-parentheses_test.go b/go/stack/valid-parentheses_test.go new file mode 100644 index 0000000..6b9805b --- /dev/null +++ b/go/stack/valid-parentheses_test.go @@ -0,0 +1,20 @@ +package stack + +import "testing" + +func TestIsValid(t *testing.T) { + s := "" + if ok := isValid(s); !ok { + t.Fatalf("test failed: %s", s) + } + + s = "{{(){}[]}}" + if ok := isValid(s); !ok { + t.Fatalf("test failed: %s", s) + } + + s = "{{(){}[]}}}" + if ok := isValid(s); ok { + t.Fatalf("test failed: %s", s) + } +} diff --git a/go/stack/verify-preorder-serialization-of-a-binary-tree.go b/go/stack/verify-preorder-serialization-of-a-binary-tree.go new file mode 100644 index 0000000..cc13fe7 --- /dev/null +++ b/go/stack/verify-preorder-serialization-of-a-binary-tree.go @@ -0,0 +1,22 @@ +package stack + +import "strings" + +func isValidSerialization(preorder string) bool { + arrs := strings.Split(preorder, ",") + slots := 1 + + for _, val := range arrs { + slots-- + if slots < 0 { + return false + } + + if val != "#" { + slots += 2 + } + } + + return slots == 0 +} + diff --git a/go/stack/verify-preorder-serialization-of-a-binary-tree_test.go b/go/stack/verify-preorder-serialization-of-a-binary-tree_test.go new file mode 100644 index 0000000..4e2a33e --- /dev/null +++ b/go/stack/verify-preorder-serialization-of-a-binary-tree_test.go @@ -0,0 +1,25 @@ +package stack + +import "testing" + +func TestIsValidSerialization(t *testing.T) { + preorder := "9,3,4,#,#,1,#,#,2,#,6,#,#" + if !isValidSerialization(preorder) { + t.Fatalf("test failed") + } + + preorder = "1,#" + if isValidSerialization(preorder) { + t.Fatalf("test failed") + } + + preorder = "9,#,#,1" + if isValidSerialization(preorder) { + t.Fatalf("test failed") + } + + preorder = "9,3,4,#,#,1,#,#,#,2,#,6,#,#" + if isValidSerialization(preorder) { + t.Fatalf("test failed") + } +} diff --git a/go/tree/balanced_binary_tree/code.go b/go/tree/balanced_binary_tree/code.go new file mode 100644 index 0000000..a955fb1 --- /dev/null +++ b/go/tree/balanced_binary_tree/code.go @@ -0,0 +1,44 @@ +package balancedbinarytree + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func isBalanced(root *TreeNode) bool { + _, ok := balanceHeight(root) + return ok +} + +func balanceHeight(root *TreeNode) (height int, isBalance bool) { + if root == nil { + isBalance = true + return + } + + lh, lb := balanceHeight(root.Left) + if !lb { + return + } + rh, rb := balanceHeight(root.Right) + if !rb { + return + } + + subH := lh - rh + if lh > rh { + height = lh + } else { + height = rh + subH = rh - lh + } + + if subH <= 1 { + isBalance = true + } + + height++ + + return +} diff --git a/go/tree/binary_tree_level_order_traversal/code.go b/go/tree/binary_tree_level_order_traversal/code.go new file mode 100644 index 0000000..7bf129d --- /dev/null +++ b/go/tree/binary_tree_level_order_traversal/code.go @@ -0,0 +1,38 @@ +package binarytree + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func bfs(node *TreeNode, level int, result [][]int) [][]int { + if node == nil { + return result + } + + var arr []int + if level > len(result)-1 { + arr = make([]int, 0) + result = append(result, arr) + } else { + arr = result[level] + } + + arr = append(arr, node.Val) + result[level] = arr + if node.Left != nil { + result = bfs(node.Left, level+1, result) + } + + if node.Right != nil { + result = bfs(node.Right, level+1, result) + } + + return result +} + +func levelOrder1(root *TreeNode) (result [][]int) { + result = bfs(root, 0, result) + return +} diff --git a/go/tree/binary_tree_level_order_traversal/code1.go b/go/tree/binary_tree_level_order_traversal/code1.go new file mode 100644 index 0000000..fe66c64 --- /dev/null +++ b/go/tree/binary_tree_level_order_traversal/code1.go @@ -0,0 +1,27 @@ +package binarytree + +func levelOrder(root *TreeNode) (result [][]int) { + if root == nil { + return + } + + q := []*TreeNode{root} + + for len(q) > 0 { + var p []*TreeNode + arr := make([]int, 0) + for _, node := range q { + arr = append(arr, node.Val) + if node.Left != nil { + p = append(p, node.Left) + } + if node.Right != nil { + p = append(p, node.Right) + } + } + result = append(result, arr) + q = p + } + + return +} diff --git a/go/tree/binary_tree_level_order_traversal/code_test.go b/go/tree/binary_tree_level_order_traversal/code_test.go new file mode 100644 index 0000000..28647fe --- /dev/null +++ b/go/tree/binary_tree_level_order_traversal/code_test.go @@ -0,0 +1,24 @@ +package binarytree + +import "testing" + +func TestLevelOrder(t *testing.T) { + root := &TreeNode{ + Val: 1, + } + left := &TreeNode{ + Val: 2, + Left: &TreeNode{ + Val: 4, + }, + } + right := &TreeNode{ + Val: 3, + } + + root.Left = left + root.Right = right + + result := levelOrder(root) + t.Logf("%v", result) +} diff --git a/go/tree/binary_tree_pruning/code.go b/go/tree/binary_tree_pruning/code.go new file mode 100644 index 0000000..a5badab --- /dev/null +++ b/go/tree/binary_tree_pruning/code.go @@ -0,0 +1,21 @@ +package binarytreepruning + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func pruneTree(root *TreeNode) *TreeNode { + if root == nil { + return nil + } + + root.Left = pruneTree(root.Left) + root.Right = pruneTree(root.Right) + if root.Left == nil && root.Right == nil && root.Val == 0 { + return nil + } + + return root +} diff --git a/go/tree/binary_tree_right_side_view/code.go b/go/tree/binary_tree_right_side_view/code.go new file mode 100644 index 0000000..f24afe7 --- /dev/null +++ b/go/tree/binary_tree_right_side_view/code.go @@ -0,0 +1,40 @@ +package binarytreerightsideview + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} +package binarytreerightsideview + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func rightSideView(root *TreeNode) (arr []int) { + if root == nil { + return + } + + p := []*TreeNode{root} + + for len(p) != 0 { + arr = append(arr, p[len(p)-1].Val) + + var q []*TreeNode + for _, node := range p { + if node.Left != nil { + q = append(q, node.Left) + } + if node.Right != nil { + q = append(q, node.Right) + } + } + + p = q + } + + return +} diff --git a/go/tree/binary_tree_zigzag_level_order_traversal/code.go b/go/tree/binary_tree_zigzag_level_order_traversal/code.go new file mode 100644 index 0000000..694b91a --- /dev/null +++ b/go/tree/binary_tree_zigzag_level_order_traversal/code.go @@ -0,0 +1,46 @@ +package zigzaglevelorder + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func reverse(arr []int) { + i, j := 0, len(arr)-1 + for i < j { + arr[i], arr[j] = arr[j], arr[i] + i++ + j-- + } +} + +func zigzagLevelOrder(root *TreeNode) (result [][]int) { + if root == nil { + return + } + + q := []*TreeNode{root} + leftFirst := true + for len(q) > 0 { + var p []*TreeNode + var arr []int + for _, node := range q { + arr = append(arr, node.Val) + if node.Left != nil { + p = append(p, node.Left) + } + if node.Right != nil { + p = append(p, node.Right) + } + } + if !leftFirst { + reverse(arr) + } + leftFirst = !leftFirst + result = append(result, arr) + q = p + } + + return +} diff --git a/go/tree/construct-binary-search-tree-from-preorder-traversal/code.go b/go/tree/construct-binary-search-tree-from-preorder-traversal/code.go new file mode 100644 index 0000000..913cbe6 --- /dev/null +++ b/go/tree/construct-binary-search-tree-from-preorder-traversal/code.go @@ -0,0 +1,36 @@ +package tree_from_preorder_traversal + +//https://leetcode-cn.com/problems/construct-binary-search-tree-from-preorder-traversal/ + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func bstFromPreorder(preorder []int) *TreeNode { + return bstOrder(preorder, 0, len(preorder)-1) +} + +func bstOrder(preorder []int, start, end int) (head *TreeNode) { + if start > end { + return + } + head = &TreeNode{ + Val: preorder[start], + } + if start == end { + return + } + + idx := start + 1 + for ; idx <= end; idx++ { + if preorder[idx] > head.Val { + break + } + } + + head.Left = bstOrder(preorder, start+1, idx-1) + head.Right = bstOrder(preorder, idx, end) + return +} diff --git a/go/tree/inorder/code.go b/go/tree/inorder/code.go new file mode 100644 index 0000000..80e4248 --- /dev/null +++ b/go/tree/inorder/code.go @@ -0,0 +1,66 @@ +package inorder + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +type Stack struct { + data []interface{} + top int +} + +func NewStack() *Stack { + return &Stack{ + data: make([]interface{}, 0), + top: -1, + } +} + +func (st *Stack) Empty() bool { + return st.top == -1 +} + +func (st *Stack) Pop() interface{} { + if st.Empty() { + panic("pop from emtpy stack") + } + + val := st.data[st.top] + st.top-- + return val +} + +func (st *Stack) Push(val interface{}) { + st.top++ + if len(st.data)-1 >= st.top { + st.data[st.top] = val + } else { + st.data = append(st.data, val) + } +} + +//中序遍历,非递归 +func inorderTraversal(root *TreeNode) (arr []int) { + if root == nil { + return + } + + st := NewStack() + last := root + for !st.Empty() || last != nil { + for last != nil { + st.Push(last) + last = last.Left + } + + node := st.Pop().(*TreeNode) + arr = append(arr, node.Val) + if node.Right != nil { + last = node.Right + } + } + + return +} diff --git a/go/tree/invert_binary_tree/code.go b/go/tree/invert_binary_tree/code.go new file mode 100644 index 0000000..efbffbd --- /dev/null +++ b/go/tree/invert_binary_tree/code.go @@ -0,0 +1,20 @@ +package invertbinarytree + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func invertTree(root *TreeNode) *TreeNode { + if root == nil { + return nil + } + left := invertTree(root.Left) + right := invertTree(root.Right) + + root.Left = right + root.Right = left + + return root +} diff --git a/go/tree/lowest_common_ancestor/code.go b/go/tree/lowest_common_ancestor/code.go new file mode 100644 index 0000000..177fe80 --- /dev/null +++ b/go/tree/lowest_common_ancestor/code.go @@ -0,0 +1,25 @@ +package lowestcommonancestor + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { + if root == nil || root == p || root == q { + return root + } + + left := lowestCommonAncestor(root.Left, p, q) + right := lowestCommonAncestor(root.Right, p, q) + if left != nil && right != nil { + return root + } + + if left != nil { + return left + } + + return right +} diff --git a/go/tree/postorder/code.go b/go/tree/postorder/code.go new file mode 100644 index 0000000..bf109a1 --- /dev/null +++ b/go/tree/postorder/code.go @@ -0,0 +1,83 @@ +package postorder + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +type Stack struct { + data []interface{} + top int +} + +func NewStack() *Stack { + return &Stack{ + data: make([]interface{}, 0), + top: -1, + } +} + +func (st *Stack) Empty() bool { + return st.top == -1 +} + +func (st *Stack) Pop() interface{} { + if st.Empty() { + panic("pop from emtpy stack") + } + + val := st.data[st.top] + st.top-- + return val +} + +func (st *Stack) Top() interface{} { + if st.Empty() { + return nil + } + + val := st.data[st.top] + return val +} + +func (st *Stack) Push(val interface{}) { + st.top++ + if len(st.data)-1 >= st.top { + st.data[st.top] = val + } else { + st.data = append(st.data, val) + } +} + +func postorderTraversal(root *TreeNode) (arr []int) { + if root == nil { + return + } + + st := NewStack() + cur := root + + var prev *TreeNode + for !st.Empty() || cur != nil { + for cur != nil { + st.Push(cur) + cur = cur.Left + } + if st.Empty() { + continue + } + + node := st.Top().(*TreeNode) + if node.Right != nil && prev != node.Right { + cur = node.Right + } else if (node.Left == nil && node.Right == nil) || + (prev != nil && (node.Left == prev || node.Right == prev)) { + arr = append(arr, node.Val) + prev = node + st.Pop() + } + } + + return +} diff --git a/go/tree/preorder/code.go b/go/tree/preorder/code.go new file mode 100644 index 0000000..87f4f30 --- /dev/null +++ b/go/tree/preorder/code.go @@ -0,0 +1,66 @@ +package tree + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +type Stack struct { + data []interface{} + top int +} + +func NewStack() *Stack { + return &Stack{ + data: make([]interface{}, 0), + top: -1, + } +} + +func (st *Stack) Empty() bool { + return st.top == -1 +} + +func (st *Stack) Pop() interface{} { + if st.Empty() { + panic("pop from emtpy stack") + } + + val := st.data[st.top] + st.top-- + return val +} + +func (st *Stack) Push(val interface{}) { + st.top++ + if len(st.data)-1 >= st.top { + st.data[st.top] = val + } else { + st.data = append(st.data, val) + } +} + +//二叉树前序遍历,非递归 +func preorderTraversal(root *TreeNode) (arr []int) { + if root == nil { + return + } + + st := NewStack() + st.Push(root) + + for !st.Empty() { + node := st.Pop().(*TreeNode) + arr = append(arr, node.Val) + + if node.Right != nil { + st.Push(node.Right) + } + + if node.Left != nil { + st.Push(node.Left) + } + } + return +} diff --git a/go/tree/symmetric_tree/code.go b/go/tree/symmetric_tree/code.go new file mode 100644 index 0000000..aa61862 --- /dev/null +++ b/go/tree/symmetric_tree/code.go @@ -0,0 +1,41 @@ +package symmetrictree + +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func isSymmetric(root *TreeNode) bool { + if root == nil { + return true + } + + ok := isSame(root.Left, root.Right) + + return ok +} + +func isSame(left, right *TreeNode) bool { + if left == nil && right == nil { + return true + } + + if left == nil || right == nil { + return false + } + + if left.Val != right.Val { + return false + } + + if !isSame(left.Left, right.Right) { + return false + } + + if !isSame(left.Right, right.Left) { + return false + } + + return true +} diff --git a/3sum-closest.c b/misc/3sum-closest.c similarity index 100% rename from 3sum-closest.c rename to misc/3sum-closest.c diff --git a/3sum-closest[2].c b/misc/3sum-closest[2].c similarity index 100% rename from 3sum-closest[2].c rename to misc/3sum-closest[2].c diff --git a/3sum.c b/misc/3sum.c similarity index 100% rename from 3sum.c rename to misc/3sum.c diff --git a/3sum.cpp b/misc/3sum.cpp similarity index 100% rename from 3sum.cpp rename to misc/3sum.cpp diff --git a/4sum.cpp b/misc/4sum.cpp similarity index 100% rename from 4sum.cpp rename to misc/4sum.cpp diff --git a/misc/README.md b/misc/README.md new file mode 100644 index 0000000..0db179e --- /dev/null +++ b/misc/README.md @@ -0,0 +1,5 @@ +# leetcode +the algorithm codes of LeetCode OJ(https://leetcode.com/problemset/algorithms/) + +those codes are mostly implemented by C languages + diff --git a/misc/add-and-search-word-data-structure-design.c b/misc/add-and-search-word-data-structure-design.c new file mode 100644 index 0000000..7d79bb9 --- /dev/null +++ b/misc/add-and-search-word-data-structure-design.c @@ -0,0 +1,74 @@ +struct WordDictionary { + struct WordDictionary *child[26]; + int is_word; +}; + +/** Initialize your data structure here. */ +struct WordDictionary* wordDictionaryCreate() { + struct WordDictionary *root; + root = (struct WordDictionary *)malloc(sizeof(struct WordDictionary)); + memset(root,0,sizeof(struct WordDictionary)); + + return root; +} + +/** Inserts a word into the data structure. */ +void addWord(struct WordDictionary* root, char* word) { + int key; + while(*word){ + key = *word - 'a'; + if(root->child[key] == NULL){ + root->child[key] = wordDictionaryCreate(); + } + root = root->child[key]; + word++; + } + + root->is_word = 1; +} + +/** Returns if the word is in the data structure. A word could + contain the dot character '.' to represent any one letter. */ +bool search(struct WordDictionary* root, char* word) { + int key,i; + bool ret = false; + while(*word){ + key = -1; + if(*word != '.') + key = *word - 'a'; + + if(key == -1){ + for(i = 0; i < 26; ++i){ + if(root->child[i]) + ret = search(root->child[i],word+1); + if(ret) + break; + } + return ret; + } + + if(root->child[key] == NULL) + return false; + + word++; + root = root->child[key]; + } + + return root->is_word; +} + +/** Deallocates memory previously allocated for the data structure. */ +void wordDictionaryFree(struct WordDictionary* root) { + int i; + for(i = 0; i < 26; ++i) + if(root->child[i]) + wordDictionaryFree(root->child[i]); + + free(root); +} + +// Your WordDictionary object will be instantiated and called as such: +// struct WordDictionary* wordDictionary = wordDictionaryCreate(); +// addWord(wordDictionary, "word"); +// search(wordDictionary, "pattern"); +// wordDictionaryFree(wordDictionary); diff --git a/add-binary.c b/misc/add-binary.c similarity index 100% rename from add-binary.c rename to misc/add-binary.c diff --git a/add-two-numbers.cpp b/misc/add-two-numbers.cpp similarity index 100% rename from add-two-numbers.cpp rename to misc/add-two-numbers.cpp diff --git a/misc/anagrams.cpp b/misc/anagrams.cpp new file mode 100644 index 0000000..f1c9083 --- /dev/null +++ b/misc/anagrams.cpp @@ -0,0 +1,28 @@ +class Solution { +public: + vector anagrams(vector& strs) { + vector ret; + map mp; + int len; + + len = strs.size(); + for(int i = 0; i < len; ++i){ + string key = strs[i]; + sort(key.begin(),key.end()); + + if( mp.find(key) == mp.end()){ + mp.insert(pair(key,i)); + continue; + } + + if(mp[key] >= 0){ + ret.push_back(strs[mp[key]]); + mp[key] = -1; + } + + ret.push_back(strs[i]); + } + + return ret; + } +}; diff --git a/balanced-binary-tree.c b/misc/balanced-binary-tree.c similarity index 100% rename from balanced-binary-tree.c rename to misc/balanced-binary-tree.c diff --git a/misc/basic-calculator-ii.c b/misc/basic-calculator-ii.c new file mode 100644 index 0000000..1a19868 --- /dev/null +++ b/misc/basic-calculator-ii.c @@ -0,0 +1,41 @@ +int calculate(char* s) { + int ret = 0; + int cur = 0; + int tmp; + char op = 0; + int type = 1; + + while(*s){ + if(isdigit(*s)){ + tmp = 0; + while(isdigit(*s)){ + tmp = tmp * 10 + (*s - '0'); + s++; + } + + if(op == '+' || op == '-'){ + ret += (type * cur); + cur = tmp; + type = ((op == '+') ? 1 : -1); + }else if(op == '*'){ + cur *= tmp; + }else if(op == '/'){ + cur /= tmp; + }else{ + cur = tmp; + } + + continue; + } + + if(*s == ' ') + goto out; + + op = *s; +out: + s++; + } + + ret += (type * cur); + return ret; +} diff --git a/misc/basic-calculator.c b/misc/basic-calculator.c new file mode 100644 index 0000000..355d4ec --- /dev/null +++ b/misc/basic-calculator.c @@ -0,0 +1,36 @@ +int calculate(char* s) { + int ret = 0; + int top = 0; + int stack[1000]; + int tmp; + int type = 1; + + while(*s){ + if(isdigit(*s)){ + tmp = 0; + while(*s && isdigit(*s)){ + tmp = tmp * 10 + (*s - '0'); + s++; + } + ret += (type * tmp); + continue; + } + + if(*s == '-'){ + type = -1; + }else if(*s == '+'){ + type = 1; + }else if(*s == '('){ + stack[top++] = ret; + ret = 0; + stack[top++] = type; + type = 1; + }else if(*s == ')'){ + type = stack[--top]; + ret = stack[--top] + type * ret; + } + s++; + } + + return ret; +} diff --git a/misc/best-time-to-buy-and-sell-stock-ii.c b/misc/best-time-to-buy-and-sell-stock-ii.c new file mode 100644 index 0000000..1c6c315 --- /dev/null +++ b/misc/best-time-to-buy-and-sell-stock-ii.c @@ -0,0 +1,11 @@ +int maxProfit(int* prices, int pricesSize) { + int i; + int ret = 0; + + for(i = 1; i < pricesSize; ++i){ + if(prices[i] > prices[i-1]) + ret += prices[i] - prices[i-1]; + } + + return ret; +} diff --git a/misc/best-time-to-buy-and-sell-stock-iii.c b/misc/best-time-to-buy-and-sell-stock-iii.c new file mode 100644 index 0000000..c99b05e --- /dev/null +++ b/misc/best-time-to-buy-and-sell-stock-iii.c @@ -0,0 +1,35 @@ +int maxProfit(int* prices, int pricesSize) { + int *left,*right; + int min,max; + int i,ret; + + left = (int *)malloc(sizeof(int) * pricesSize); + right = (int *)malloc(sizeof(int) * pricesSize); + + left[0] = 0; + min = prices[0]; + for(i = 1; i < pricesSize; ++i){ + min = prices[i] < min ? prices[i] : min; + left[i] = prices[i] - min > left[i-1] ? + prices[i] - min : left[i-1]; + } + + max = prices[pricesSize-1]; + right[pricesSize-1] = 0; + for(i = pricesSize-2; i >= 0; --i){ + max = prices[i] > max ? prices[i] : max; + right[i] = max - prices[i] > right[i+1] ? + max - prices[i] : right[i+1]; + } + + ret = 0; + for(i = 0; i < pricesSize; ++i){ + if(left[i] + right[i] > ret) + ret = left[i] + right[i]; + } + + free(left); + free(right); + + return ret; +} diff --git a/misc/best-time-to-buy-and-sell-stock-iv.c b/misc/best-time-to-buy-and-sell-stock-iv.c new file mode 100644 index 0000000..4c0d2aa --- /dev/null +++ b/misc/best-time-to-buy-and-sell-stock-iv.c @@ -0,0 +1,40 @@ +static int max(int a, int b) +{ + return a > b ? a : b; +} + +int maxProfit(int k, int* prices, int pricesSize) { + int ret = 0; + int i,j; + int *local,*global; + int tmp; + + if(k >= pricesSize){ + for(i = 1; i < pricesSize; ++i){ + if(prices[i] - prices[i-1] > 0) + ret += prices[i] - prices[i-1]; + } + return ret; + } + + local = (int *)malloc(sizeof(int) * (k + 1)); + global = (int *)malloc(sizeof(int) * (k + 1)); + + memset(local,0,sizeof(int) * (k + 1)); + memset(global,0,sizeof(int) * (k + 1)); + + for(i = 0; i < pricesSize - 1; ++i){ + tmp = prices[i+1] - prices[i]; + + for(j = k; j >= 1; --j){ + local[j] = max(global[j-1] + max(tmp,0),local[j] + tmp); + global[j] = max(local[j],global[j]); + } + } + + ret = global[k]; + free(local); + free(global); + + return ret; +} diff --git a/best-time-to-buy-and-sell-stock.c b/misc/best-time-to-buy-and-sell-stock.c similarity index 100% rename from best-time-to-buy-and-sell-stock.c rename to misc/best-time-to-buy-and-sell-stock.c diff --git a/misc/binary-search-tree-iterator.c b/misc/binary-search-tree-iterator.c new file mode 100644 index 0000000..5f899e9 --- /dev/null +++ b/misc/binary-search-tree-iterator.c @@ -0,0 +1,56 @@ +/** + * Definition for binary tree + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +struct BSTIterator { + struct TreeNode *stack[1000]; + int top; + struct TreeNode *cur; +}; + +struct BSTIterator *bstIteratorCreate(struct TreeNode *root) { + struct BSTIterator *bit = (struct BSTIterator *)malloc(sizeof(struct BSTIterator)); + + bit->top = 0; + bit->cur = root; + + return bit; +} + +/** @return whether we have a next smallest number */ +bool bstIteratorHasNext(struct BSTIterator *iter) { + if(iter->cur != NULL || iter->top > 0) + return true; + + return false; +} + +/** @return the next smallest number */ +int bstIteratorNext(struct BSTIterator *iter) { + int ret; + while(iter->cur){ + iter->stack[iter->top++] = iter->cur; + iter->cur = iter->cur->left; + } + + iter->cur = iter->stack[--iter->top]; + ret = iter->cur->val; + iter->cur = iter->cur->right; + return ret; +} + +/** Deallocates memory previously allocated for the iterator */ +void bstIteratorFree(struct BSTIterator *iter) { + +} + +/** + * Your BSTIterator will be called like this: + * struct BSTIterator *i = bstIteratorCreate(root); + * while (bstIteratorHasNext(i)) printf("%d\n", bstIteratorNext(i)); + * bstIteratorFree(i); + */ diff --git a/binary-tree-inorder-traversal.c b/misc/binary-tree-inorder-traversal.c similarity index 100% rename from binary-tree-inorder-traversal.c rename to misc/binary-tree-inorder-traversal.c diff --git a/binary-tree-level-order-traversal-ii.cpp b/misc/binary-tree-level-order-traversal-ii.cpp similarity index 100% rename from binary-tree-level-order-traversal-ii.cpp rename to misc/binary-tree-level-order-traversal-ii.cpp diff --git a/binary-tree-level-order-traversal.cpp b/misc/binary-tree-level-order-traversal.cpp similarity index 100% rename from binary-tree-level-order-traversal.cpp rename to misc/binary-tree-level-order-traversal.cpp diff --git a/binary-tree-maximum-path-sum.c b/misc/binary-tree-maximum-path-sum.c similarity index 100% rename from binary-tree-maximum-path-sum.c rename to misc/binary-tree-maximum-path-sum.c diff --git a/binary-tree-postorder-traversal.c b/misc/binary-tree-postorder-traversal.c similarity index 100% rename from binary-tree-postorder-traversal.c rename to misc/binary-tree-postorder-traversal.c diff --git a/binary-tree-preorder-traversal.cpp b/misc/binary-tree-preorder-traversal.cpp similarity index 100% rename from binary-tree-preorder-traversal.cpp rename to misc/binary-tree-preorder-traversal.cpp diff --git a/binary-tree-right-side-view.c b/misc/binary-tree-right-side-view.c similarity index 100% rename from binary-tree-right-side-view.c rename to misc/binary-tree-right-side-view.c diff --git a/binary-tree-zigzag-level-order-traversal.cpp b/misc/binary-tree-zigzag-level-order-traversal.cpp similarity index 100% rename from binary-tree-zigzag-level-order-traversal.cpp rename to misc/binary-tree-zigzag-level-order-traversal.cpp diff --git a/bitwise-and-of-numbers-range.c b/misc/bitwise-and-of-numbers-range.c similarity index 100% rename from bitwise-and-of-numbers-range.c rename to misc/bitwise-and-of-numbers-range.c diff --git a/bitwise-and-of-numbers-range[2].c b/misc/bitwise-and-of-numbers-range[2].c similarity index 100% rename from bitwise-and-of-numbers-range[2].c rename to misc/bitwise-and-of-numbers-range[2].c diff --git a/candy.c b/misc/candy.c similarity index 100% rename from candy.c rename to misc/candy.c diff --git a/climbing-stairs.c b/misc/climbing-stairs.c similarity index 100% rename from climbing-stairs.c rename to misc/climbing-stairs.c diff --git a/misc/combination-sum-ii.cpp b/misc/combination-sum-ii.cpp new file mode 100644 index 0000000..dcb7022 --- /dev/null +++ b/misc/combination-sum-ii.cpp @@ -0,0 +1,37 @@ +class Solution { +public: + int size; + int tar; + vector > vret; + + void rec(vector &vt, vector &cand,int sum, int index) + { + if(sum > tar) + return ; + if(sum == tar){ + vret.push_back(vt); + return ; + } + + int prev = -1; + for(int i = index; i < size; ++i){ + if(cand[i] == prev) + continue; + prev = cand[i]; + vt.push_back(cand[i]); + rec(vt,cand,sum+cand[i],i+1); + vt.pop_back(); + } + } + + vector> combinationSum2(vector& candidates, int target) { + vector vt; + sort(candidates.begin(),candidates.end()); + size = candidates.size(); + tar = target; + + rec(vt,candidates,0,0); + + return vret; + } +}; diff --git a/misc/combination-sum-ii[1].cpp b/misc/combination-sum-ii[1].cpp new file mode 100644 index 0000000..dd7b302 --- /dev/null +++ b/misc/combination-sum-ii[1].cpp @@ -0,0 +1,39 @@ +class Solution { +public: + int size; + vector > vret; + + void rec(vector &vt, vector &cand,int target, int index) + { + if(target == 0){ + vret.push_back(vt); + return ; + } + + if(index >= size || target < 0) + return ; + + int prev = -1; + for(int i = index; i < size; ++i){ + if(cand[i] > target) + break; + if(cand[i] == prev) + continue; + + prev = cand[i]; + vt.push_back(cand[i]); + rec(vt,cand,target-cand[i],i+1); + vt.pop_back(); + } + } + + vector> combinationSum2(vector& candidates, int target) { + vector vt; + sort(candidates.begin(),candidates.end()); + size = candidates.size(); + + rec(vt,candidates,target,0); + + return vret; + } +}; diff --git a/misc/combination-sum-iii.c b/misc/combination-sum-iii.c new file mode 100644 index 0000000..3512021 --- /dev/null +++ b/misc/combination-sum-iii.c @@ -0,0 +1,48 @@ +/** + * 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 count; +int gk; + +void helper(int **ret,int *arr, int k, int n, int index) +{ + int i; + if(k == 0 && n == 0){ + int *tmp = (int *)malloc(sizeof(int) * gk); + memcpy(tmp,arr,sizeof(int) * gk); + ret[count] = tmp; + count++; + return ; + } + + if(index > 9 || k <= 0 || n <= 0) + return ; + + for(i = index; i <= 9; ++i){ + arr[gk-k] = i; + helper(ret, arr,k-1,n-i,i+1); + } +} +int** combinationSum3(int k, int n, int** columnSizes, int* returnSize) { + int **ret; + int *arr; + int i,len; + len = 200; + + *columnSizes = (int *)malloc(sizeof(int) * len); + ret = (int **)malloc(sizeof(int*) * len); + arr = (int *)malloc(sizeof(int) * k); + count = 0; + gk = k; + + helper(ret,arr,k,n,1); + *returnSize = count; + for(i = 0; i < count; ++i) + (*columnSizes)[i] = k; + free(arr); + + return ret; +} diff --git a/misc/combination-sum-iii.cpp b/misc/combination-sum-iii.cpp new file mode 100644 index 0000000..5bf052c --- /dev/null +++ b/misc/combination-sum-iii.cpp @@ -0,0 +1,30 @@ +class Solution { +public: + void helper(vector > &vret, vector &vt, int k, int n, int index) + { + if(n == 0 && k == 0){ + vret.push_back(vt); + return ; + } + + if(index > 9 || n <= 0 || k <= 0) + return ; + + for(int i = index; i <= 9; ++i){ + if(i > n) + break; + vt.push_back(i); + helper(vret,vt,k-1,n-i,i+1); + vt.pop_back(); + } + } + + vector> combinationSum3(int k, int n) { + vector > vret; + vector vt; + + helper(vret,vt,k,n,1); + + return vret; + } +}; diff --git a/misc/combination-sum.cpp b/misc/combination-sum.cpp new file mode 100644 index 0000000..1057ba2 --- /dev/null +++ b/misc/combination-sum.cpp @@ -0,0 +1,50 @@ +class Solution { +public: + bool is_equal(vector &va, vector &vb) + { + int size = va.size(); + if(size != vb.size()) + return false; + for(int i = 0; i < size; ++i) + if(va[i] != vb[i]) + return false; + return true; + } + + void rec(vector > &vret, vector &cand, vector &vt, int target) + { + int size = cand.size(); + for(int i = 0; i < size; ++i){ + if(target < cand[i]) + continue; + if(target == cand[i]){ + vt.push_back(target); + vector tmp(vt.begin(),vt.end()); + vt.pop_back(); + int vsize = vret.size(); + int i; + sort(tmp.begin(),tmp.end()); + for(i = 0; i < vsize; ++i) + if(is_equal(vret[i],tmp)) + break; + if(i == vsize) + vret.push_back(tmp); + + break; + } + + vt.push_back(cand[i]); + rec(vret,cand,vt,target-cand[i]); + vt.pop_back(); + } + } + vector> combinationSum(vector& candidates, int target) { + vector > vret; + vector vt; + + sort(candidates.begin(),candidates.end()); + rec(vret,candidates,vt,target); + + return vret; + } +}; diff --git a/misc/combination-sum[1].cpp b/misc/combination-sum[1].cpp new file mode 100644 index 0000000..daba2b0 --- /dev/null +++ b/misc/combination-sum[1].cpp @@ -0,0 +1,27 @@ +class Solution { +public: + void rec(vector > &vret, vector &vt, vector &cand, + int index, int sum, int target) + { + if(sum > target) + return ; + if(sum == target){ + vret.push_back(vt); + return ; + } + int size = cand.size(); + for(int i = index; i < size; ++i){ + vt.push_back(cand[i]); + rec(vret,vt,cand,i,sum+cand[i],target); + vt.pop_back(); + } + } + vector> combinationSum(vector& candidates, int target) { + vector > vret; + vector vt; + + sort(candidates.begin(),candidates.end()); + rec(vret,vt,candidates,0,0,target); + return vret; + } +}; diff --git a/misc/combinations.c b/misc/combinations.c new file mode 100644 index 0000000..b49f60c --- /dev/null +++ b/misc/combinations.c @@ -0,0 +1,50 @@ +/** + * 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 idx; + +void rec(int **ret, int *rcd, int n, int k, int l, int p) +{ + int i; + if(l == k){ + memcpy(ret[idx],rcd,sizeof(int)*k); + idx++; + return ; + } + + for(i = p; i <= n; ++i){ + rcd[l] = i; + rec(ret,rcd,n,k,l+1,i+1); + } +} + +int** combine(int n, int k, int** columnSizes, int* returnSize) { + long len = 1; //len must be long, or it will overflow if n is 13 + int **ret; + int *rcd; + int i; + + for(i = n; i > n - k; --i) + len *= i; + for(i = k; i >= 2; --i) + len /= i; + + rcd = (int *)malloc(sizeof(int) * k); + ret = (int **)malloc(sizeof(int *) * len); + *columnSizes = (int *)malloc(sizeof(int) * len); + for(i = 0; i < len; ++i){ + ret[i] = (int *)malloc(sizeof(int) * k); + (*columnSizes)[i] = k; + } + + idx = 0; + rec(ret,rcd,n,k,0,1); + + *returnSize = len; + + free(rcd); + return ret; +} diff --git a/misc/combinations.cpp b/misc/combinations.cpp new file mode 100644 index 0000000..d76e124 --- /dev/null +++ b/misc/combinations.cpp @@ -0,0 +1,23 @@ +class Solution { +public: + void rec(vector > &vret, vector &vt, + int l,int p, int n, int k) + { + if(l == k){ + vret.push_back(vt); + }else{ + for(int i = p; i <= n; ++i){ + vt.push_back(i); + rec(vret,vt,l+1,i+1,n,k); + vt.pop_back(); + } + } + } + vector> combine(int n, int k) { + vector > vret; + vector vt; + rec(vret,vt,0,1,n,k); + + return vret; + } +}; diff --git a/compare-version-numbers.c b/misc/compare-version-numbers.c similarity index 100% rename from compare-version-numbers.c rename to misc/compare-version-numbers.c diff --git a/construct-binary-tree-from-inorder-and-postorder-traversal.c b/misc/construct-binary-tree-from-inorder-and-postorder-traversal.c similarity index 100% rename from construct-binary-tree-from-inorder-and-postorder-traversal.c rename to misc/construct-binary-tree-from-inorder-and-postorder-traversal.c diff --git a/construct-binary-tree-from-preorder-and-inorder-traversal.c b/misc/construct-binary-tree-from-preorder-and-inorder-traversal.c similarity index 100% rename from construct-binary-tree-from-preorder-and-inorder-traversal.c rename to misc/construct-binary-tree-from-preorder-and-inorder-traversal.c diff --git a/container-with-most-water.c b/misc/container-with-most-water.c similarity index 100% rename from container-with-most-water.c rename to misc/container-with-most-water.c diff --git a/misc/contains-duplicate-ii.c b/misc/contains-duplicate-ii.c new file mode 100644 index 0000000..b711e76 --- /dev/null +++ b/misc/contains-duplicate-ii.c @@ -0,0 +1,10 @@ +bool containsNearbyDuplicate(int* nums, int numsSize, int k) { + int i,j; + for(i = 0; i < numsSize; ++i) + for(j = i; j <= i+k && j < numsSize; ++j){ + if(i != j && nums[i] == nums[j]) + return true; + } + + return false; +} diff --git a/misc/contains-duplicate-ii.cpp b/misc/contains-duplicate-ii.cpp new file mode 100644 index 0000000..85e843d --- /dev/null +++ b/misc/contains-duplicate-ii.cpp @@ -0,0 +1,13 @@ +class Solution { +public: + bool containsNearbyDuplicate(vector& nums, int k) { + map m; + int len = nums.size(); + for(int i = 0; i < len; ++i){ + if(m.find(nums[i]) != m.end() && i-m[nums[i]] <= k) + return true; + m[nums[i]] = i; + } + return false; + } +}; diff --git a/misc/contains-duplicate-iii.c b/misc/contains-duplicate-iii.c new file mode 100644 index 0000000..fc4b3ec --- /dev/null +++ b/misc/contains-duplicate-iii.c @@ -0,0 +1,11 @@ +bool containsNearbyAlmostDuplicate(int* nums, int numsSize, int k, int t) { + int i,j; + + for(i = 0; i < numsSize; ++i){ + for(j = i;j < numsSize && j <= i + k; ++j) + if(i != j && labs(nums[j] - nums[i]) <= t) + return true; + } + + return false; +} diff --git a/misc/contains-duplicate.c b/misc/contains-duplicate.c new file mode 100644 index 0000000..c0c0c5d --- /dev/null +++ b/misc/contains-duplicate.c @@ -0,0 +1,15 @@ +tatic int cmp(const void *a, const void *b) +{ + return *(int *)a - *(int *)b; +} +bool containsDuplicate(int* nums, int numsSize) { + int i; + qsort(nums,numsSize,sizeof(int),cmp); + i = 1; + while(i < numsSize){ + if(nums[i] == nums[i-1]) + return true; + ++i; + } + return false; +} diff --git a/convert-sorted-array-to-binary-search-tree.c b/misc/convert-sorted-array-to-binary-search-tree.c similarity index 100% rename from convert-sorted-array-to-binary-search-tree.c rename to misc/convert-sorted-array-to-binary-search-tree.c diff --git a/convert-sorted-list-to-binary-search-tree.c b/misc/convert-sorted-list-to-binary-search-tree.c similarity index 100% rename from convert-sorted-list-to-binary-search-tree.c rename to misc/convert-sorted-list-to-binary-search-tree.c diff --git a/copy-list-with-random-pointer.c b/misc/copy-list-with-random-pointer.c similarity index 100% rename from copy-list-with-random-pointer.c rename to misc/copy-list-with-random-pointer.c diff --git a/copy-list-with-random-pointer.cpp b/misc/copy-list-with-random-pointer.cpp similarity index 100% rename from copy-list-with-random-pointer.cpp rename to misc/copy-list-with-random-pointer.cpp diff --git a/count-and-say.c b/misc/count-and-say.c similarity index 100% rename from count-and-say.c rename to misc/count-and-say.c diff --git a/count-primes.c b/misc/count-primes.c similarity index 100% rename from count-primes.c rename to misc/count-primes.c diff --git a/count-primes.cpp b/misc/count-primes.cpp similarity index 100% rename from count-primes.cpp rename to misc/count-primes.cpp diff --git a/decode-ways.c b/misc/decode-ways.c similarity index 100% rename from decode-ways.c rename to misc/decode-ways.c diff --git a/misc/delete-node-in-a-linked-list.c b/misc/delete-node-in-a-linked-list.c new file mode 100644 index 0000000..ead0764 --- /dev/null +++ b/misc/delete-node-in-a-linked-list.c @@ -0,0 +1,11 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +void deleteNode(struct ListNode* node) { + node->val = node->next->val; + node->next = node->next->next; +} diff --git a/misc/distinct-subsequences.c b/misc/distinct-subsequences.c new file mode 100644 index 0000000..e3a11dd --- /dev/null +++ b/misc/distinct-subsequences.c @@ -0,0 +1,33 @@ +int numDistinct(char* s, char* t) { + int lens = strlen(s); + int lent = strlen(t); + int **dp; + int i,j; + int ret; + + dp = (int **)malloc(sizeof(int *) * (lens+1)); + for(i = 0; i <= lens; ++i){ + dp[i] = (int *)malloc(sizeof(int) * (lent + 1)); + memset(dp[i],0,sizeof(int) * (lent+1)); + } + + for(i = 0; i <= lens; ++i){ + dp[i][0] = 1; + } + + for(i = 1; i <= lens; ++i){ + for(j = 1; j <= lent; ++j){ + dp[i][j] += dp[i-1][j]; + if(s[i-1] == t[j-1]) + dp[i][j] += dp[i-1][j-1]; + } + } + + ret = dp[lens][lent]; + + for(i = 0; i <= lens; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/misc/distinct-subsequences[1].c b/misc/distinct-subsequences[1].c new file mode 100644 index 0000000..1db25ec --- /dev/null +++ b/misc/distinct-subsequences[1].c @@ -0,0 +1,33 @@ +int numDistinct(char* s, char* t) { + int lens = strlen(s); + int lent = strlen(t); + int **dp; + int i,j; + int ret; + + dp = (int **)malloc(sizeof(int *) * (lent+1)); + for(i = 0; i <= lent; ++i){ + dp[i] = (int *)malloc(sizeof(int) * (lens + 1)); + memset(dp[i],0,sizeof(int) * (lens+1)); + } + + for(j = 0; j <= lens; ++j){ + dp[0][j] = 1; + } + + for(i = 1; i <= lent; ++i){ + for(j = 1; j <= lens; ++j){ + dp[i][j] += dp[i][j-1]; + if(t[i-1] == s[j-1]) + dp[i][j] += dp[i-1][j-1]; + } + } + + ret = dp[lent][lens]; + + for(i = 0; i <= lent; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/divide-two-integers.c b/misc/divide-two-integers.c similarity index 100% rename from divide-two-integers.c rename to misc/divide-two-integers.c diff --git a/dungeon-game.c b/misc/dungeon-game.c similarity index 100% rename from dungeon-game.c rename to misc/dungeon-game.c diff --git a/misc/edit-distance.c b/misc/edit-distance.c new file mode 100644 index 0000000..1ceddcf --- /dev/null +++ b/misc/edit-distance.c @@ -0,0 +1,38 @@ +int min_3(int a, int b, int c) +{ + int m = a < b ? a : b; + return m < c ? m : c; +} + +int minDistance(char* word1, char* word2) { + int **dp; + int len1 = strlen(word1); + int len2 = strlen(word2); + int i,j; + int ret; + + dp = (int **)malloc(sizeof(int *) * (len1 + 1)); + for(i = 0; i <= len1; ++i){ + dp[i] = (int *)malloc(sizeof(int) * (len2 + 1)); + } + + for(i = 0; i <= len1; ++i) + dp[i][0] = i; + for(j = 0; j <= len2; ++j) + dp[0][j] = j; + + for(i = 1; i <= len1; ++i){ + for(j = 1; j <= len2; ++j){ + dp[i][j] = min_3(dp[i-1][j] + 1, dp[i][j-1] + 1, + dp[i-1][j-1] + (word1[i-1] == word2[j-1] ? 0 : 1)); + } + } + + ret = dp[len1][len2]; + + for(i = 0; i <= len1; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/misc/evaluate-reverse-polish-notation.c b/misc/evaluate-reverse-polish-notation.c new file mode 100644 index 0000000..d8b2802 --- /dev/null +++ b/misc/evaluate-reverse-polish-notation.c @@ -0,0 +1,38 @@ +int evalRPN(char** tokens, int tokensSize) { + int i; + int ret; + int *stack; + int top = 0; + + stack = (int *)malloc(sizeof(int) * tokensSize); + + for(i = 0; i < tokensSize; ++i){ + if(isdigit(tokens[i][0]) || strlen(tokens[i]) > 1){ + stack[top++] = strtol(tokens[i],0,10); + continue; + } + + top--; + switch(tokens[i][0]){ + case '+': + stack[top-1] += stack[top]; + break; + case '-': + stack[top-1] -= stack[top]; + break; + case '*': + stack[top-1] *= stack[top]; + break; + case '/': + stack[top-1] /= stack[top]; + break; + default: + break; + } + } + + ret = stack[0]; + free(stack); + + return ret; +} diff --git a/excel-sheet-column-number.c b/misc/excel-sheet-column-number.c similarity index 100% rename from excel-sheet-column-number.c rename to misc/excel-sheet-column-number.c diff --git a/excel-sheet-column-title.c b/misc/excel-sheet-column-title.c similarity index 100% rename from excel-sheet-column-title.c rename to misc/excel-sheet-column-title.c diff --git a/factorial-trailing-zeroes.c b/misc/factorial-trailing-zeroes.c similarity index 100% rename from factorial-trailing-zeroes.c rename to misc/factorial-trailing-zeroes.c diff --git a/find-minimum-in-rotated-sorted-array-ii.c b/misc/find-minimum-in-rotated-sorted-array-ii.c similarity index 100% rename from find-minimum-in-rotated-sorted-array-ii.c rename to misc/find-minimum-in-rotated-sorted-array-ii.c diff --git a/find-minimum-in-rotated-sorted-array.c b/misc/find-minimum-in-rotated-sorted-array.c similarity index 100% rename from find-minimum-in-rotated-sorted-array.c rename to misc/find-minimum-in-rotated-sorted-array.c diff --git a/find-peak-element.c b/misc/find-peak-element.c similarity index 100% rename from find-peak-element.c rename to misc/find-peak-element.c diff --git a/find-peak-element[2].c b/misc/find-peak-element[2].c similarity index 100% rename from find-peak-element[2].c rename to misc/find-peak-element[2].c diff --git a/first-missing-positive.c b/misc/first-missing-positive.c similarity index 100% rename from first-missing-positive.c rename to misc/first-missing-positive.c diff --git a/flatten-binary-tree-to-linked-list.c b/misc/flatten-binary-tree-to-linked-list.c similarity index 100% rename from flatten-binary-tree-to-linked-list.c rename to misc/flatten-binary-tree-to-linked-list.c diff --git a/misc/flatten-nested-list-iterator.cpp b/misc/flatten-nested-list-iterator.cpp new file mode 100644 index 0000000..e8ded2f --- /dev/null +++ b/misc/flatten-nested-list-iterator.cpp @@ -0,0 +1,54 @@ +/** + * // This is the interface that allows for creating nested lists. + * // You should not implement it, or speculate about its implementation + * class NestedInteger { + * public: + * // Return true if this NestedInteger holds a single integer, rather than a nested list. + * bool isInteger() const; + * + * // Return the single integer that this NestedInteger holds, if it holds a single integer + * // The result is undefined if this NestedInteger holds a nested list + * int getInteger() const; + * + * // Return the nested list that this NestedInteger holds, if it holds a nested list + * // The result is undefined if this NestedInteger holds a single integer + * const vector &getList() const; + * }; + */ +class NestedIterator { +public: + NestedIterator(vector &nestedList) { + for(int i = nestedList.size() - 1; i >= 0; --i) + st.push(nestedList[i]); + } + + int next() { + NestedInteger nested = st.top(); + st.pop(); + return nested.getInteger(); + } + + bool hasNext() { + while(!st.empty()){ + NestedInteger nested = st.top(); + if(nested.isInteger()) + return true; + st.pop(); + + vector nestedList = nested.getList(); + for(int i = nestedList.size() - 1; i >= 0; --i) + st.push(nestedList[i]); + } + + return false; + } + +private: + stack st; +}; + +/** + * Your NestedIterator object will be instantiated and called as such: + * NestedIterator i(nestedList); + * while (i.hasNext()) cout << i.next(); + */ diff --git a/misc/gas-station.c b/misc/gas-station.c new file mode 100644 index 0000000..33ffd88 --- /dev/null +++ b/misc/gas-station.c @@ -0,0 +1,17 @@ +int canCompleteCircuit(int* gas, int gasSize, int* cost, int costSize) { + int i; + int cur = 0; + int ret = 0; + int sum = 0; + + for(i = 0; i < gasSize; ++i){ + cur += gas[i] - cost[i]; + sum += gas[i] - cost[i]; + if(cur < 0){ + cur = 0; + ret = i+1; + } + } + + return sum < 0 ? -1 : ret; +} diff --git a/generate-parentheses.cpp b/misc/generate-parentheses.cpp similarity index 100% rename from generate-parentheses.cpp rename to misc/generate-parentheses.cpp diff --git a/misc/gray-code.c b/misc/gray-code.c new file mode 100644 index 0000000..75a07c0 --- /dev/null +++ b/misc/gray-code.c @@ -0,0 +1,35 @@ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +void rec(int *ret, int n, int *count) +{ + if(n == 0){ + ret[*count] = 0; + (*count)++; + return ; + } + + int i,j; + int add = 1 << (n-1); + + rec(ret,n-1,count); + + j = *count; + for(i = *count-1; i >= 0; --i) + ret[j++] = ret[i] + add; + + (*count) = j; +} + +int* grayCode(int n, int* returnSize) { + int len = 1 << n; + int *ret; + + ret = (int *)malloc(sizeof(int) * len); + + (*returnSize) = 0; + rec(ret,n,returnSize); + + return ret; +} diff --git a/happy-number.c b/misc/happy-number.c similarity index 100% rename from happy-number.c rename to misc/happy-number.c diff --git a/happy-number[2].c b/misc/happy-number[2].c similarity index 100% rename from happy-number[2].c rename to misc/happy-number[2].c diff --git a/happy-number[3].c b/misc/happy-number[3].c similarity index 100% rename from happy-number[3].c rename to misc/happy-number[3].c diff --git a/misc/house-robber-ii.c b/misc/house-robber-ii.c new file mode 100644 index 0000000..0f5533e --- /dev/null +++ b/misc/house-robber-ii.c @@ -0,0 +1,26 @@ +int rob(int* nums, int numsSize) { + int *dp0,*dp1; + int i,ret; + dp0 = (int *)malloc(sizeof(int) * (numsSize + 1)); + dp1 = (int *)malloc(sizeof(int) * (numsSize + 1)); + + dp0[0] = 0; + dp0[1] = nums[0]; + for(i = 2; i < numsSize; ++i) + dp0[i] = (dp0[i-1] > dp0[i-2] + nums[i-1] ? + dp0[i-1] : dp0[i-2] + nums[i-1]); + dp0[i] = dp0[i-1] > dp0[i-2] ? dp0[i-1] : dp0[i-2]; + + dp1[0] = 0; + dp1[1] = 0; + for(i = 2; i <= numsSize; ++i) + dp1[i] = (dp1[i-1] > dp1[i-2] + nums[i-1] ? + dp1[i-1] : dp1[i-2] + nums[i-1]); + + ret = dp0[numsSize] > dp1[numsSize] ? + dp0[numsSize] : dp1[numsSize]; + free(dp0); + free(dp1); + + return ret; +} diff --git a/house-robber.c b/misc/house-robber.c similarity index 79% rename from house-robber.c rename to misc/house-robber.c index 0a24ca0..e4c2b28 100644 --- a/house-robber.c +++ b/misc/house-robber.c @@ -1,11 +1,14 @@ int rob(int num[], int n) { int *dp; - int i; + int i,ret; dp = (int *)malloc(sizeof(int) * (n+1)); dp[0] = 0; dp[1] = num[0]; for(i = 2; i <= n; ++i) dp[i] = (dp[i-1] > (dp[i-2] + num[i-1])) ? dp[i-1] : dp[i-2] + num[i-1]; - return dp[n]; + ret = dp[n]; + + free(dp); + return ret; } diff --git a/misc/implement-queue-using-stacks.c b/misc/implement-queue-using-stacks.c new file mode 100644 index 0000000..3bff917 --- /dev/null +++ b/misc/implement-queue-using-stacks.c @@ -0,0 +1,61 @@ +typedef struct { + int *st1; + int *st2; + int top1; + int top2; +} Queue; + +/* Create a queue */ +void queueCreate(Queue *queue, int maxSize) { + queue->st1 = (int *)malloc(sizeof(int) * maxSize); + queue->st2 = (int *)malloc(sizeof(int) * maxSize); + queue->top1 = 0; + queue->top2 = 0; +} + +/* Push element x to the back of queue */ +void queuePush(Queue *queue, int element) { + queue->st1[queue->top1++] = element; + //queue->top1++; +} + +/* Removes the element from front of queue */ +void queuePop(Queue *queue) { + if(queue->top2 > 0){ + queue->top2--; + return ; + } + + while(queue->top1 > 0){ + queue->st2[queue->top2++] = queue->st1[--queue->top1]; + } + + queue->top2--; +} + +/* Get the front element */ +int queuePeek(Queue *queue) { + if(queue->top2 > 0){ + return queue->st2[queue->top2-1]; + } + + while(queue->top1 > 0){ + queue->st2[queue->top2++] = queue->st1[--queue->top1]; + } + + return queue->st2[queue->top2-1]; +} + +/* Return whether the queue is empty */ +bool queueEmpty(Queue *queue) { + return queue->top1 == 0 && queue->top2 == 0; +} + +/* Destroy the queue */ +void queueDestroy(Queue *queue) { + if(!queue) + return ; + + free(queue->st1); + free(queue->st2); +} diff --git a/misc/implement-stack-using-queues.c b/misc/implement-stack-using-queues.c new file mode 100644 index 0000000..b0c670b --- /dev/null +++ b/misc/implement-stack-using-queues.c @@ -0,0 +1,70 @@ +typedef struct { + int *queue1; + int f1,e1; + int *queue2; + int f2,e2; +} Stack; + +/* Create a stack */ +void stackCreate(Stack *stack, int maxSize) { + stack->queue1 = (int *)malloc(sizeof(int) * maxSize); + stack->queue2 = (int *)malloc(sizeof(int) * maxSize); + stack->f1 = 0; + stack->e1 = 0; + stack->f2 = 0; + stack->e2 = 0; +} + +/* Push element x onto stack */ +void stackPush(Stack *stack, int element) { + stack->queue1[stack->e1++] = element; +} + + +/* Removes the element on top of the stack */ +void stackPop(Stack *stack) { + while(stack->e1 - stack->f1 > 1){ + stack->queue2[stack->e2++] = stack->queue1[stack->f1++]; + } + + int *tmp = stack->queue1; + stack->queue1 = stack->queue2; + stack->queue2 = tmp; + stack->f1 = stack->f2; + stack->e1 = stack->e2; + stack->f2 = 0; + stack->e2 = 0; +} + +/* Get the top element */ +int stackTop(Stack *stack) { + while(stack->e1 - stack->f1 > 1){ + stack->queue2[stack->e2++] = stack->queue1[stack->f1++]; + } + + int *tmp = stack->queue1; + int ret = stack->queue1[stack->f1]; + stack->queue2[stack->e2++] = stack->queue1[stack->f1++]; + stack->queue1 = stack->queue2; + stack->queue2 = tmp; + stack->f1 = stack->f2; + stack->e1 = stack->e2; + stack->f2 = 0; + stack->e2 = 0; + + return ret; +} + +/* Return whether the stack is empty */ +bool stackEmpty(Stack *stack) { + return stack->f1 == stack->e1; +} + +/* Destroy the stack */ +void stackDestroy(Stack *stack) { + if(stack == NULL) + return ; + + free(stack->queue1); + free(stack->queue2); +} diff --git a/implement-strstr.c b/misc/implement-strstr.c similarity index 100% rename from implement-strstr.c rename to misc/implement-strstr.c diff --git a/misc/implement-trie-prefix-tree.c b/misc/implement-trie-prefix-tree.c new file mode 100644 index 0000000..9906c22 --- /dev/null +++ b/misc/implement-trie-prefix-tree.c @@ -0,0 +1,73 @@ +struct TrieNode { + struct TrieNode *child[26]; + int is_word; +}; + +/** Initialize your data structure here. */ +struct TrieNode* trieCreate() { + struct TrieNode *root; + root = (struct TrieNode *)malloc(sizeof(struct TrieNode)); + memset(root,0,sizeof(struct TrieNode)); + + return root; +} + +/** Inserts a word into the trie. */ +void insert(struct TrieNode* root, char* word) { + int key; + while(*word){ + key = *word - 'a'; + if(root->child[key] == NULL) + root->child[key] = trieCreate(); + root = root->child[key]; + word++; + } + + root->is_word = 1; +} + +/** Returns if the word is in the trie. */ +bool search(struct TrieNode* root, char* word) { + int key; + while(*word){ + key = *word - 'a'; + if(root->child[key] == NULL) + return false; + root = root->child[key]; + word++; + } + + return root->is_word; +} + +/** Returns if there is any word in the trie + that starts with the given prefix. */ +bool startsWith(struct TrieNode* root, char* prefix) { + int key; + while(*prefix){ + key = *prefix - 'a'; + if(root->child[key] == NULL) + return false; + root = root->child[key]; + prefix++; + } + + return true; +} + +/** Deallocates memory previously allocated for the TrieNode. */ +void trieFree(struct TrieNode* root) { + int i; + if(root == NULL) + return ; + + for(i = 0; i < 26; ++i) + trieFree(root->child[i]); + free(root); +} + +// Your Trie object will be instantiated and called as such: +// struct TrieNode* node = trieCreate(); +// insert(node, "somestring"); +// search(node, "key"); +// trieFree(node); diff --git a/insert-interval.cpp b/misc/insert-interval.cpp similarity index 100% rename from insert-interval.cpp rename to misc/insert-interval.cpp diff --git a/insertion-sort-list.c b/misc/insertion-sort-list.c similarity index 100% rename from insertion-sort-list.c rename to misc/insertion-sort-list.c diff --git a/integer-to-roman.c b/misc/integer-to-roman.c similarity index 100% rename from integer-to-roman.c rename to misc/integer-to-roman.c diff --git a/misc/interleaving-string.c b/misc/interleaving-string.c new file mode 100644 index 0000000..f83816f --- /dev/null +++ b/misc/interleaving-string.c @@ -0,0 +1,33 @@ +bool isInterleave(char* s1, char* s2, char* s3) { + bool **dp; + bool ret; + int len1 = strlen(s1); + int len2 = strlen(s2); + int len3 = strlen(s3); + int i,j; + + if(len1 + len2 != len3) + return false; + + dp = (bool **)malloc(sizeof(bool *) * (len1 + 1)); + for(i = 0; i <= len1; ++i) + dp[i] = (bool *)malloc(sizeof(bool) * (len2 + 1)); + + dp[0][0] = true; + for(i = 1; i <= len1; ++i) + dp[i][0] = (dp[i-1][0] && s1[i-1] == s3[i-1]); + for(j = 1; j <= len2; ++j) + dp[0][j] = (dp[0][j-1] && s2[j-1] == s3[j-1]); + + for(i = 1; i <= len1; ++i) + for(j = 1; j <= len2; ++j){ + dp[i][j] = ((dp[i-1][j] && s1[i-1] == s3[i+j-1]) || + (dp[i][j-1] && s2[j-1] == s3[i+j-1])); + } + + ret = dp[len1][len2]; + for(i = 0; i <= len1; ++i) + free(dp[i]); + free(dp); + return ret; +} diff --git a/intersection-of-two-linked-lists.c b/misc/intersection-of-two-linked-lists.c similarity index 100% rename from intersection-of-two-linked-lists.c rename to misc/intersection-of-two-linked-lists.c diff --git a/misc/invert-binary-tree.c b/misc/invert-binary-tree.c new file mode 100644 index 0000000..f415323 --- /dev/null +++ b/misc/invert-binary-tree.c @@ -0,0 +1,19 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +struct TreeNode* invertTree(struct TreeNode* root) { + if(!root) + return NULL; + + struct TreeNode *tmp; + tmp = root->left; + root->left = invertTree(root->right); + root->right = invertTree(tmp); + + return root; +} diff --git a/isomorphic-strings.c b/misc/isomorphic-strings.c similarity index 100% rename from isomorphic-strings.c rename to misc/isomorphic-strings.c diff --git a/jump-game-ii.c b/misc/jump-game-ii.c similarity index 100% rename from jump-game-ii.c rename to misc/jump-game-ii.c diff --git a/jump-game.c b/misc/jump-game.c similarity index 100% rename from jump-game.c rename to misc/jump-game.c diff --git a/jump-game[2].c b/misc/jump-game[2].c similarity index 100% rename from jump-game[2].c rename to misc/jump-game[2].c diff --git a/misc/kth-largest-element-in-an-array.c b/misc/kth-largest-element-in-an-array.c new file mode 100644 index 0000000..256563c --- /dev/null +++ b/misc/kth-largest-element-in-an-array.c @@ -0,0 +1,8 @@ +static int cmp(const int *a, const int *b) +{ + return *(int *)b - *(int *)a; +} +int findKthLargest(int* nums, int numsSize, int k) { + qsort(nums,numsSize,sizeof(int),cmp); + return nums[k-1]; +} diff --git a/misc/kth-largest-element-in-an-array[1].c b/misc/kth-largest-element-in-an-array[1].c new file mode 100644 index 0000000..1ec60ad --- /dev/null +++ b/misc/kth-largest-element-in-an-array[1].c @@ -0,0 +1,31 @@ +#define _cmp(a,b) ((a) > (b)) +int findKthLargest(int* nums, int numsSize, int k) { + int start,end,tmp; + int i,j; + int value; + start = 0; + end = numsSize - 1; + k--; + while(start < end){ + i = start - 1; + j = end + 1; + value = nums[(i+j) >> 1]; + while(i < j){ + for(--j; _cmp(value,nums[j]); --j) ; + + for(++i; _cmp(nums[i],value); ++i) ; + + if(i < j){ + tmp = nums[i]; + nums[i] = nums[j]; + nums[j] = tmp; + } + } + if(k > j) + start = j + 1; + else + end = j; + } + + return nums[k]; +} diff --git a/misc/kth-smallest-element-in-a-bst.c b/misc/kth-smallest-element-in-a-bst.c new file mode 100644 index 0000000..4025031 --- /dev/null +++ b/misc/kth-smallest-element-in-a-bst.c @@ -0,0 +1,34 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +int getKth(struct TreeNode *root, int k, int *val) +{ + if(root == NULL) + return 0; + + int right; + int left = getKth(root->left,k,val); + if(left > k){ + return left; + } + + if(k - left == 1){ + *val = root->val; + return left + 1; + } + + right = getKth(root->right,k - left - 1, val); + return left + 1 + right; +} + +int kthSmallest(struct TreeNode* root, int k) { + int val; + getKth(root,k,&val); + + return val; +} diff --git a/largest-number.c b/misc/largest-number.c similarity index 100% rename from largest-number.c rename to misc/largest-number.c diff --git a/largest-number.cpp b/misc/largest-number.cpp similarity index 100% rename from largest-number.cpp rename to misc/largest-number.cpp diff --git a/misc/largest-rectangle-in-histogram.c b/misc/largest-rectangle-in-histogram.c new file mode 100644 index 0000000..90993b8 --- /dev/null +++ b/misc/largest-rectangle-in-histogram.c @@ -0,0 +1,24 @@ +int largestRectangleArea(int* height, int heightSize) { + int *stack; + int top = -1; + int i; + int curh; + int max = 0; + + stack = (int *)malloc(sizeof(int) * heightSize); + + for(i = 0; i <= heightSize; ++i){ + curh = (i == heightSize) ? -1 : height[i]; + while(top != -1 && curh <= height[stack[top]]){ + int h = height[stack[top--]]; + int w = ((top == -1) ? i : i - stack[top] - 1); + + if(h * w > max) + max = h * w; + } + stack[++top] = i; + } + + free(stack); + return max; +} diff --git a/length-of-last-word.c b/misc/length-of-last-word.c similarity index 100% rename from length-of-last-word.c rename to misc/length-of-last-word.c diff --git a/misc/letter-combinations-of-a-phone-number.c b/misc/letter-combinations-of-a-phone-number.c new file mode 100644 index 0000000..76ca4e1 --- /dev/null +++ b/misc/letter-combinations-of-a-phone-number.c @@ -0,0 +1,62 @@ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ + +char *arr[10] = {" ","","abc","def","ghi","jkl", + "mno", "pqrs","tuv","wxyz"}; +int len; +int count; +int total; + +void helper(char **ret, char *digits, char *member, int start, int index) +{ + int i,j,str_len; + char *str; + + if( start == len){ + if(index != 0) + ret[count++] = strdup(member); + return ; + } + + str = arr[digits[start] - '0']; + + str_len = strlen(str); + if(str_len == 0){ + helper(ret,digits,member,start+1,index); + return ; + } + + for(i = 0 ; i < str_len; ++i){ + member[index] = str[i]; + helper(ret,digits,member,start+1,index+1); + } +} + +char** letterCombinations(char* digits, int* returnSize) { + int i; + char **ret; + char *member; + char *str; + + len = strlen(digits); + total = 1; + for(i = 0; i < len; ++i){ + str = arr[digits[i] - '0']; + if(strlen(str) == 0) + continue; + total *= strlen(str); + } + + ret = (char **)malloc(sizeof(char *) * total); + member = (char *)malloc(sizeof(char) * (len + 1)); + memset(member, 0, sizeof(char) * (len + 1)); + + count = 0; + helper(ret,digits,member,0,0); + *returnSize = count; + + free(member); + return ret; +} diff --git a/linked-list-cycle-ii.c b/misc/linked-list-cycle-ii.c similarity index 100% rename from linked-list-cycle-ii.c rename to misc/linked-list-cycle-ii.c diff --git a/linked-list-cycle-ii[2].c b/misc/linked-list-cycle-ii[2].c similarity index 100% rename from linked-list-cycle-ii[2].c rename to misc/linked-list-cycle-ii[2].c diff --git a/linked-list-cycle.c b/misc/linked-list-cycle.c similarity index 100% rename from linked-list-cycle.c rename to misc/linked-list-cycle.c diff --git a/misc/longest-common-prefix.c b/misc/longest-common-prefix.c new file mode 100644 index 0000000..c409f1f --- /dev/null +++ b/misc/longest-common-prefix.c @@ -0,0 +1,18 @@ +ar* longestCommonPrefix(char** strs, int strsSize) { + if(strsSize == 0) + return ""; + int len0 = strlen(strs[0]); + char *prefix = (char *)malloc(sizeof(char) * (len0 + 1)); + memset(prefix,0,sizeof(char) * (len0 + 1)); + int i,j; + for(i = 0; i < len0; ++i){ + for(j = 1; j < strsSize; ++j) + if(strs[j][i] != strs[0][i]) + break; + if(j != strsSize) + break; + prefix[i] = strs[0][i]; + } + + return prefix; +} diff --git a/misc/longest-common-prefix.cpp b/misc/longest-common-prefix.cpp new file mode 100644 index 0000000..3c02ec4 --- /dev/null +++ b/misc/longest-common-prefix.cpp @@ -0,0 +1,24 @@ +class Solution { +public: + string longestCommonPrefix(vector& strs) { + string prefix = ""; + int len = strs.size(); + if(len == 0) + return prefix; + int len0 = strs[0].size(); + int i,j; + + for(i = 0; i < len0; ++i){ + for(j = 1; j < len; ++j){ + if(strs[j][i] != strs[0][i]){ + break; + } + } + if(j != len) + break; + prefix += strs[0][i]; + } + + return prefix; + } +}; diff --git a/longest-consecutive-sequence.c b/misc/longest-consecutive-sequence.c similarity index 100% rename from longest-consecutive-sequence.c rename to misc/longest-consecutive-sequence.c diff --git a/longest-consecutive-sequence.cpp b/misc/longest-consecutive-sequence.cpp similarity index 100% rename from longest-consecutive-sequence.cpp rename to misc/longest-consecutive-sequence.cpp diff --git a/misc/longest-palindromic-substring.c b/misc/longest-palindromic-substring.c new file mode 100644 index 0000000..fed9bbb --- /dev/null +++ b/misc/longest-palindromic-substring.c @@ -0,0 +1,44 @@ +char* longestPalindrome(char* s) { + int i,j,len; + int dp[1000][1000]; + int max,index; + char *ret; + + len = strlen(s); + for(i = 0; i < len; ++i){ + memset(dp[i],0,sizeof(int) * len); + } + + for(i = 0; i < len; ++i){ + dp[i][i] = 1; + if(i < len - 1 && s[i] == s[i+1]) + dp[i][i+1] = 1; + } + + for(i = 2; i < len; ++i){ + for(j = 0; j+i < len; ++j){ + if(s[j] == s[j+i] && dp[j+1][j+i-1]) + dp[j][j+i] = 1; + } + } + + max = 0; + index = -1; + for(i = 0; i < len; ++i) { + for(j = i;j < len; ++j) + if(dp[i][j] && j - i + 1 > max){ + max = j - i + 1; + index = i; + } + } + + ret = (char *)malloc(sizeof(char) * (max + 1)); + i = 0; + while(i < max){ + ret[i] = s[i+index]; + ++i; + } + ret[max] = '\0'; + + return ret; +} diff --git a/misc/longest-palindromic-substring[1].c b/misc/longest-palindromic-substring[1].c new file mode 100644 index 0000000..c396def --- /dev/null +++ b/misc/longest-palindromic-substring[1].c @@ -0,0 +1,33 @@ +static int expand(char *s, int start, int end){ + while(start >= 0 && s[end] && s[start] == s[end]){ + --start; + ++end; + } + return end - start - 1; +} +char* longestPalindrome(char* s) { + int i; + int len = strlen(s); + int index,max; + char *ret; + max = 0; + for(i = 0; i < len; ++i){ + int len1 = expand(s,i,i); + int len2 = expand(s,i,i+1); + int len = len1 > len2 ? len1 : len2; + if(len > max){ + max = len; + index = i - (len - 1) / 2; + } + } + + ret = (char *)malloc(sizeof(char) * (max + 1)); + i = 0; + while(i < max){ + ret[i] = s[i+index]; + i++; + } + ret[max] = '\0'; + + return ret; +} diff --git a/longest-substring-without-repeating-characters.c b/misc/longest-substring-without-repeating-characters.c similarity index 100% rename from longest-substring-without-repeating-characters.c rename to misc/longest-substring-without-repeating-characters.c diff --git a/longest-substring-without-repeating-characters[2].c b/misc/longest-substring-without-repeating-characters[2].c similarity index 100% rename from longest-substring-without-repeating-characters[2].c rename to misc/longest-substring-without-repeating-characters[2].c diff --git a/misc/longest-valid-parentheses.c b/misc/longest-valid-parentheses.c new file mode 100644 index 0000000..c39d6fd --- /dev/null +++ b/misc/longest-valid-parentheses.c @@ -0,0 +1,37 @@ +int longestValidParentheses(char* s) { + int *stack; + int *match; + int top; + int len = strlen(s); + int i; + int cur_len,max_len; + + stack = (int *)malloc(sizeof(int) * len); + match = (int *)malloc(sizeof(int) * len); + memset(match,0,sizeof(int)*len); + + top = -1; + for(i = 0; i < len; ++i){ + if(s[i] == '('){ + top++; + stack[top] = i; + }else if(top > -1){ + match[i] = 1; + match[stack[top]] = 1; + top--; + } + } + + max_len = cur_len = 0; + for(i = 0; i < len; ++i){ + if(match[i]) + cur_len++; + else + cur_len = 0; + max_len = cur_len > max_len ? cur_len : max_len; + } + + free(stack); + free(match); + return max_len; +} diff --git a/misc/lowest-common-ancestor-of-a-binary-search-tree.c b/misc/lowest-common-ancestor-of-a-binary-search-tree.c new file mode 100644 index 0000000..820f79d --- /dev/null +++ b/misc/lowest-common-ancestor-of-a-binary-search-tree.c @@ -0,0 +1,25 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +int is_ancestor(struct TreeNode *root, struct TreeNode *child) +{ + if(root == NULL) + return 0; + if(root == child) + return 1; + return is_ancestor(root->left,child) || is_ancestor(root->right,child); +} + +struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) { + if(is_ancestor(root->left,p) && is_ancestor(root->left,q)) + return lowestCommonAncestor(root->left,p,q); + if(is_ancestor(root->right,p) && is_ancestor(root->right,q)) + return lowestCommonAncestor(root->right,p,q); + + return root; +} diff --git a/misc/lowest-common-ancestor-of-a-binary-search-tree[1].c b/misc/lowest-common-ancestor-of-a-binary-search-tree[1].c new file mode 100644 index 0000000..c6d91f0 --- /dev/null +++ b/misc/lowest-common-ancestor-of-a-binary-search-tree[1].c @@ -0,0 +1,16 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) { + if(root->val > p->val && root->val > q->val) + return lowestCommonAncestor(root->left,p,q); + if(root->val < p->val && root->val < q->val) + return lowestCommonAncestor(root->right,p,q); + + return root; +} diff --git a/misc/lowest-common-ancestor-of-a-binary-search-tree[2].c b/misc/lowest-common-ancestor-of-a-binary-search-tree[2].c new file mode 100644 index 0000000..865caec --- /dev/null +++ b/misc/lowest-common-ancestor-of-a-binary-search-tree[2].c @@ -0,0 +1,20 @@ +/** + * Definition for a binary tree node. + * 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) + return root; + + struct TreeNode *left = lowestCommonAncestor(root->left,p,q); + struct TreeNode *right = lowestCommonAncestor(root->right,p,q); + + if(left && right) + return root; + + return left ? left : right; +} diff --git a/misc/lowest-common-ancestor-of-a-binary-tree.c b/misc/lowest-common-ancestor-of-a-binary-tree.c new file mode 100644 index 0000000..770f0da --- /dev/null +++ b/misc/lowest-common-ancestor-of-a-binary-tree.c @@ -0,0 +1,20 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * struct TreeNode *left; + * struct TreeNode *right; + * }; + */ +struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) { + if(!root || root == p || root == q) + return root; + + struct TreeNode *left = lowestCommonAncestor(root->left,p,q); + struct TreeNode *right = lowestCommonAncestor(root->right,p,q); + + if(left && right) + return root; + + return left ? left : right; +} diff --git a/misc/majority-element-ii.c b/misc/majority-element-ii.c new file mode 100644 index 0000000..2a743c2 --- /dev/null +++ b/misc/majority-element-ii.c @@ -0,0 +1,34 @@ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +static int cmp(const void *a, const void *b) +{ + return *(int *)a - *(int *)b; +} + +int* majorityElement(int* nums, int numsSize, int* returnSize) { + int *ret; + int less = numsSize / 3; + int cur; + int i,count; + + ret = (int *)malloc(sizeof(int) * (less + 2)); + qsort(nums,numsSize,sizeof(int),cmp); + + cur = 0; + i = 0; + count = 0; + while(i+count < numsSize){ + while(i + count < numsSize && nums[i+count] == nums[i]){ + count++; + } + if(count > less) + ret[cur++] = nums[i]; + i += count; + count = 0; + } + + *returnSize = cur; + return ret; +} diff --git a/misc/majority-element-ii[1].c b/misc/majority-element-ii[1].c new file mode 100644 index 0000000..8b5087e --- /dev/null +++ b/misc/majority-element-ii[1].c @@ -0,0 +1,56 @@ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* majorityElement(int* nums, int numsSize, int* returnSize) { + int *ret; + int i,c1,c2,arr1, arr2; + + arr1 = arr2 = 0; + c1 = c2 = 0; + for(i = 0; i < numsSize; ++i){ + if(arr1 == nums[i]){ + c1++; + continue; + } + + if(arr2 == nums[i]){ + c2++; + continue; + } + + if(c1 == 0){ + arr1 = nums[i]; + c1++; + continue; + } + + if(c2 == 0){ + arr2 = nums[i]; + c2++; + continue; + } + + c1--; + c2--; + } + + c1 = c2 = 0; + for(i = 0; i < numsSize; ++i){ + if(arr1 == nums[i]) + c1++; + else if(arr2 == nums[i]) + c2++; + } + + i = 0; + ret = (int *)malloc(sizeof(int) * 2); + if(c1 > numsSize / 3) + ret[i++] = arr1; + + if(c2 > numsSize/3 ) + ret[i++] = arr2; + + *returnSize = i; + return ret; +} diff --git a/majority-element.c b/misc/majority-element.c similarity index 100% rename from majority-element.c rename to misc/majority-element.c diff --git a/majority-element[2].c b/misc/majority-element[2].c similarity index 100% rename from majority-element[2].c rename to misc/majority-element[2].c diff --git a/misc/maximal-square.c b/misc/maximal-square.c new file mode 100644 index 0000000..62e85f9 --- /dev/null +++ b/misc/maximal-square.c @@ -0,0 +1,37 @@ +int maximalSquare(char** matrix, int row, int col) { + int **dp; + int i,j; + int ret,min; + + dp = (int **)malloc(sizeof(int *) * row); + for(i = 0; i < row; ++i){ + dp[i] = (int *)malloc(sizeof(int) * col); + memset(dp[i],0,sizeof(int) * col); + } + + ret = 0; + for(i = 0; i < row; ++i){ + for(j = 0; j < col; ++j){ + if(i-1 < 0 || j-1 < 0 || matrix[i][j] == '0') + min = 0; + else{ + min = dp[i-1][j] < dp[i][j-1] ? dp[i-1][j] : dp[i][j-1]; + min = dp[i-1][j-1] < min ? dp[i-1][j-1] : min; + } + + if(matrix[i][j] == '1') + min++; + + dp[i][j] = min; + + if(min * min > ret) + ret = min * min; + } + } + + for(i = 0; i < row; ++i) + free(dp[i]); + free(dp); + + return ret; +} diff --git a/maximum-depth-of-binary-tree.c b/misc/maximum-depth-of-binary-tree.c similarity index 100% rename from maximum-depth-of-binary-tree.c rename to misc/maximum-depth-of-binary-tree.c diff --git a/maximum-gap.c b/misc/maximum-gap.c similarity index 100% rename from maximum-gap.c rename to misc/maximum-gap.c diff --git a/misc/maximum-product-subarray.c b/misc/maximum-product-subarray.c new file mode 100644 index 0000000..949c2bc --- /dev/null +++ b/misc/maximum-product-subarray.c @@ -0,0 +1,25 @@ +int maxProduct(int* nums, int numsSize) { + int *min,*max; + int i; + int ret = nums[0]; + min = (int *)malloc(sizeof(int) * numsSize); + max = (int *)malloc(sizeof(int) * numsSize); + + min[0] = max[0] = nums[0]; + for(i = 1; i < numsSize; ++i){ + min[i] = max[i] = nums[i]; + if(nums[i] > 0){ + max[i] = max[i] > max[i-1] * nums[i] ? max[i] : max[i-1] * nums[i]; + min[i] = min[i] < min[i-1] * nums[i] ? min[i] : min[i-1] * nums[i]; + }else if(nums[i] < 0){ + max[i] = max[i] > min[i-1] * nums[i] ? max[i] : min[i-1] * nums[i]; + min[i] = min[i] < max[i-1] * nums[i] ? min[i] : max[i-1] * nums[i]; + } + if(max[i] > ret) + ret = max[i]; + } + + free(max); + free(min); + return ret; +} diff --git a/misc/maximum-product-subarray[1].c b/misc/maximum-product-subarray[1].c new file mode 100644 index 0000000..f2a2e07 --- /dev/null +++ b/misc/maximum-product-subarray[1].c @@ -0,0 +1,24 @@ +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; +} + +int maxProduct(int* nums, int numsSize) { + int i,cur_min,cur_max,ret,tmp_min,tmp_max; + + ret = cur_min = cur_max = nums[0]; + for(i = 1; i < numsSize; ++i){ + tmp_max = max(nums[i], max(cur_max * nums[i], cur_min*nums[i])); + tmp_min = min(nums[i], min(cur_max * nums[i], cur_min*nums[i])); + + cur_max = tmp_max; + cur_min = tmp_min; + ret = max(cur_max,ret); + } + + return ret; +} diff --git a/maximum-subarray.c b/misc/maximum-subarray.c similarity index 100% rename from maximum-subarray.c rename to misc/maximum-subarray.c diff --git a/median-of-two-sorted-arrays.c b/misc/median-of-two-sorted-arrays.c similarity index 100% rename from median-of-two-sorted-arrays.c rename to misc/median-of-two-sorted-arrays.c diff --git a/merge-intervals.c b/misc/merge-intervals.c similarity index 100% rename from merge-intervals.c rename to misc/merge-intervals.c diff --git a/merge-k-sorted-lists.c b/misc/merge-k-sorted-lists.c similarity index 100% rename from merge-k-sorted-lists.c rename to misc/merge-k-sorted-lists.c diff --git a/merge-sorted-array.c b/misc/merge-sorted-array.c similarity index 100% rename from merge-sorted-array.c rename to misc/merge-sorted-array.c diff --git a/merge-sorted-array[2].c b/misc/merge-sorted-array[2].c similarity index 100% rename from merge-sorted-array[2].c rename to misc/merge-sorted-array[2].c diff --git a/merge-two-sorted-lists.c b/misc/merge-two-sorted-lists.c similarity index 100% rename from merge-two-sorted-lists.c rename to misc/merge-two-sorted-lists.c diff --git a/min-stack.c b/misc/min-stack.c similarity index 100% rename from min-stack.c rename to misc/min-stack.c diff --git a/min-stack.cpp b/misc/min-stack.cpp similarity index 100% rename from min-stack.cpp rename to misc/min-stack.cpp diff --git a/minimum-depth-of-binary-tree.c b/misc/minimum-depth-of-binary-tree.c similarity index 100% rename from minimum-depth-of-binary-tree.c rename to misc/minimum-depth-of-binary-tree.c diff --git a/minimum-path-sum.c b/misc/minimum-path-sum.c similarity index 100% rename from minimum-path-sum.c rename to misc/minimum-path-sum.c diff --git a/misc/minimum-size-subarray-sum.c b/misc/minimum-size-subarray-sum.c new file mode 100644 index 0000000..ce6bd9d --- /dev/null +++ b/misc/minimum-size-subarray-sum.c @@ -0,0 +1,19 @@ +int minSubArrayLen(int s, int* nums, int numsSize) { + int ret = numsSize + 1; + int i,j; + int sum = 0; + i = j = 0; + + while(j < numsSize){ + sum += nums[j]; + while(sum >= s){ + if(j - i + 1 < ret) + ret = j - i + 1; + sum -= nums[i]; + i++; + } + j++; + } + + return (ret == (numsSize + 1)) ? 0 : ret; +} diff --git a/minimum-window-substring.c b/misc/minimum-window-substring.c similarity index 100% rename from minimum-window-substring.c rename to misc/minimum-window-substring.c diff --git a/misc/n-queens-ii.c b/misc/n-queens-ii.c new file mode 100644 index 0000000..f4b1824 --- /dev/null +++ b/misc/n-queens-ii.c @@ -0,0 +1,49 @@ +static int is_ok(int **queue, int n, int index, int y) +{ + int i,j; + for(i = 0; i < n; ++i){ + for(j = 0; j < n; ++j){ + if(queue[index][j] || queue[i][y] || + (queue[i][j] && abs(i-index) == abs(j-y))) + return 0; + } + } + return 1; +} + +void helper(int **queue, int n, int *count, int index) +{ + int i; + if(index == n){ + (*count)++; + return ; + } + for(i = 0; i < n; ++i){ + if(is_ok(queue,n,index,i)){ + queue[index][i] = 1; + helper(queue,n,count,index+1); + queue[index][i] = 0; + } + } +} + +int totalNQueens(int n) { + int **queue; + int i; + int ret; + + queue = (int **)malloc(sizeof(int *) * n); + for(i = 0; i < n; ++i){ + queue[i] = (int *)malloc(sizeof(int) * n); + memset(queue[i],0,sizeof(int) * n); + } + + ret = 0; + helper(queue,n,&ret,0); + + + for(i = 0; i < n; ++i) + free(queue[i]); + free(queue); + return ret; +} diff --git a/misc/n-queens-ii[1].c b/misc/n-queens-ii[1].c new file mode 100644 index 0000000..a4221b4 --- /dev/null +++ b/misc/n-queens-ii[1].c @@ -0,0 +1,38 @@ +int total; + +static int is_ok(int *queue, int k, int pos) +{ + int i; + for(i = 0; i < k; ++i){ + if(queue[i] == pos || abs(pos - queue[i]) == (k - i)) + return 0; + } + + return 1; +} + +void helper(int *queue, int n, int k) +{ + if(k == n){ + total++; + return ; + } + + int i; + for(i = 0; i < n; ++i){ + if(!is_ok(queue,k,i)) + continue; + queue[k] = i; + helper(queue,n,k+1); + } +} + +int totalNQueens(int n) { + int *queue; + queue = (int *)malloc(sizeof(int) * n); + total = 0; + helper(queue,n,0); + + free(queue); + return total; +} diff --git a/misc/n-queens.cpp b/misc/n-queens.cpp new file mode 100644 index 0000000..9b11027 --- /dev/null +++ b/misc/n-queens.cpp @@ -0,0 +1,42 @@ +class Solution { +public: + vector> vret; + bool is_ok(int *queue, int k, int pos) + { + for(int i = 0; i < k; ++i) + if(queue[i] == pos || abs(pos - queue[i]) == (k - i)) + return false; + + return true; + } + + int helper(int *queue, int n, int k) + { + int i; + if(n == k){ + vector vs; + for(i = 0; i < n; ++i){ + string s(n,'.'); + s[queue[i]] = 'Q'; + vs.push_back(s); + } + vret.push_back(vs); + } + + for(i = 0; i < n; ++i){ + if(!is_ok(queue,k,i)) + continue; + queue[k] = i; + helper(queue,n,k+1); + } + } + + vector> solveNQueens(int n) { + int *queue = new int[n]; + + helper(queue,n,0); + + free(queue); + return vret; + } +}; diff --git a/misc/next-permutation.c b/misc/next-permutation.c new file mode 100644 index 0000000..a1632bd --- /dev/null +++ b/misc/next-permutation.c @@ -0,0 +1,38 @@ +void reverse(int *nums, int start, int end) +{ + while(start < end){ + int tmp = nums[start]; + nums[start] = nums[end]; + nums[end] = tmp; + ++start; + --end; + } +} + +void nextPermutation(int* nums, int numsSize) { + int index = -1; + int i; + + for(i = numsSize - 2; i >= 0; --i){ + if(nums[i] < nums[i+1]){ + index = i; + break; + } + } + + if(index == -1){ + reverse(nums,0,numsSize - 1); + return ; + } + + for(i = numsSize - 1; i > index; --i){ + if(nums[i] > nums[index]){ + int tmp = nums[index]; + nums[index] = nums[i]; + nums[i] = tmp; + break; + } + } + + reverse(nums,index+1,numsSize - 1); +} diff --git a/number-of-1-bits.c b/misc/number-of-1-bits.c similarity index 100% rename from number-of-1-bits.c rename to misc/number-of-1-bits.c diff --git a/misc/number-of-digit-one.c b/misc/number-of-digit-one.c new file mode 100644 index 0000000..83aaf45 --- /dev/null +++ b/misc/number-of-digit-one.c @@ -0,0 +1,14 @@ +int countDigitOne(int n) { + int ret = 0; + long m; + + for(m = 1; m <= n; m *= 10){ + long a = n / m; + long b = n % m; + ret += (a + 8) / 10 * m; + if(a % 10 == 1) + ret += (b + 1); + } + + return ret; +} diff --git a/number-of-islands.c b/misc/number-of-islands.c similarity index 100% rename from number-of-islands.c rename to misc/number-of-islands.c diff --git a/misc/palindrome-linked-list.c b/misc/palindrome-linked-list.c new file mode 100644 index 0000000..b112f74 --- /dev/null +++ b/misc/palindrome-linked-list.c @@ -0,0 +1,43 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ +bool isPalindrome(struct ListNode* head) { + struct ListNode *start,*tmp; + struct ListNode right; + int len,i; + len = 0; + start = head; + while(head){ + len++; + head = head->next; + } + + head = start; + i = 0; + while(i < (len+1)/2){ + head = head->next; + i++; + } + + right.next = NULL; + while(head){ + tmp = head; + head = head->next; + tmp->next = right.next; + right.next = tmp; + } + + tmp = right.next; + while(tmp){ + if(start->val != tmp->val) + return false; + start = start->next; + tmp = tmp->next; + } + + return true; +} diff --git a/palindrome-number.c b/misc/palindrome-number.c similarity index 100% rename from palindrome-number.c rename to misc/palindrome-number.c diff --git a/misc/palindrome-partitioning-ii.c b/misc/palindrome-partitioning-ii.c new file mode 100644 index 0000000..879263b --- /dev/null +++ b/misc/palindrome-partitioning-ii.c @@ -0,0 +1,35 @@ +int minCut(char* s) { + int *dp; + int **is_palin; + int len = strlen(s); + int i,j,ret; + + dp = (int *)malloc(sizeof(int) * (len+1)); + is_palin = (int **)malloc(sizeof(int *) * len); + for(i = 0; i < len; ++i){ + is_palin[i] = (int *)malloc(sizeof(int) * len); + memset(is_palin[i],0,sizeof(int) * len); + is_palin[i][i] = 1; + } + + dp[len] = -1; + for(i = len - 1; i >= 0; --i){ + dp[i] = dp[i+1] + 1; + for(j = i+1; j < len; ++j){ + if(s[i] == s[j]){ + if(j - i < 2 || is_palin[i+1][j-1]){ + is_palin[i][j] = 1; + dp[i] = dp[j+1] + 1 < dp[i] ? dp[j+1] + 1 : dp[i]; + } + } + } + } + + ret = dp[0]; + for(i = 0; i < len; ++i) + free(is_palin[i]); + free(is_palin); + free(dp); + + return ret; +} diff --git a/misc/palindrome-partitioning.cpp b/misc/palindrome-partitioning.cpp new file mode 100644 index 0000000..e22a67e --- /dev/null +++ b/misc/palindrome-partitioning.cpp @@ -0,0 +1,40 @@ +class Solution { +public: + void dfs(string s, vector > &vret, vector &vs) + { + int size = s.size(); + if(size < 1){ + vret.push_back(vs); + return ; + } + + for(int i = 0; i < size; ++i){ + int begin = 0; + int end = i; + bool is_pal = true; + + while(begin < end){ + if(s[begin] != s[end]){ + is_pal = false; + break; + } + ++begin; + --end; + } + + if(is_pal){ + vs.push_back(s.substr(0,i+1)); + dfs(s.substr(i+1),vret,vs); + vs.pop_back(); + } + } + } + vector> partition(string s) { + vector > vret; + vector vs; + + dfs(s,vret,vs); + + return vret; + } +}; diff --git a/partition-list.c b/misc/partition-list.c similarity index 100% rename from partition-list.c rename to misc/partition-list.c diff --git a/misc/pascals-triangle-ii.cpp b/misc/pascals-triangle-ii.cpp new file mode 100644 index 0000000..3e61cff --- /dev/null +++ b/misc/pascals-triangle-ii.cpp @@ -0,0 +1,25 @@ +class Solution { +public: + vector getRow(int rowIndex) { + int i = 0,cnt = 0,size; + vector > vret; + vector vi,prev; + + vi.push_back(1); + vret.push_back(vi); + + while(cnt < rowIndex){ + prev = vret[cnt++]; + size = prev.size(); + vi.clear(); + vi.push_back(1); + for(i = 0; i < size-1; ++i) + vi.push_back(prev[i] + prev[i+1]); + vi.push_back(1); + + vret.push_back(vi); + } + + return vi; + } +}; diff --git a/pascals-triangle.cpp b/misc/pascals-triangle.cpp similarity index 100% rename from pascals-triangle.cpp rename to misc/pascals-triangle.cpp diff --git a/path-sum-ii.cpp b/misc/path-sum-ii.cpp similarity index 100% rename from path-sum-ii.cpp rename to misc/path-sum-ii.cpp diff --git a/path-sum.c b/misc/path-sum.c similarity index 100% rename from path-sum.c rename to misc/path-sum.c diff --git a/misc/permutation-sequence.c b/misc/permutation-sequence.c new file mode 100644 index 0000000..b547f89 --- /dev/null +++ b/misc/permutation-sequence.c @@ -0,0 +1,35 @@ +char* getPermutation(int n, int k) { + char *ret; + int i,j; + int A,num,len; + int arr[10]; + int val; + + ret = (char *)malloc(sizeof(char) * (n+1)); + memset(ret,0,sizeof(char) * (n+1)); + memset(arr,0,sizeof(int) * 10); + + len = 0; + for(i = n; i >= 1; --i){ + A = 1; + for(j = i-1; j > 1; --j) + A *= j; + + val = (k - 1) / A + 1; + k = (k - 1) % A + 1; + + num = 0; + for(j = 1; j <= n; ++j){ + if(arr[j] == 0){ + num++; + } + if(num == val) + break; + } + arr[j] = 1; + ret[len] = j + '0'; + len++; + } + + return ret; +} diff --git a/misc/permutation-sequence[1].c b/misc/permutation-sequence[1].c new file mode 100644 index 0000000..79dc640 --- /dev/null +++ b/misc/permutation-sequence[1].c @@ -0,0 +1,31 @@ +char* getPermutation(int n, int k) { + char *ret; + int arr[9]; + int A; + int i,j; + int len; + int key; + + ret = (char *)malloc(sizeof(char) * (n+1)); + ret[n] = 0; + + A = 1; + for(i = 1; i <= n; ++i){ + A *= i; + arr[i-1] = i + '0'; + } + + k--; + len = 0; + for(i = n;i >= 1; --i){ + A /= i; + key = k / A; + k %= A; + ret[len++] = arr[key]; + + for(j = key; j < n-1; ++j) + arr[j] = arr[j+1]; + } + + return ret; +} diff --git a/misc/permutations-ii.cpp b/misc/permutations-ii.cpp new file mode 100644 index 0000000..baadd14 --- /dev/null +++ b/misc/permutations-ii.cpp @@ -0,0 +1,55 @@ +class Solution { +public: + int size; + int k; + void rec(vector> &vret, int *mem, + vector &vt,int *c,int count) + { + if(count == size){ + vret.push_back(vt); + }else{ + for(int i = 0; i < k; ++i){ + if(c[i] > 0){ + c[i]--; + vt.push_back(mem[i]); + rec(vret,mem,vt,c,count+1); + vt.pop_back(); + c[i]++; + } + } + } + } + + vector> permuteUnique(vector& nums) { + int i,j; + int *mem; + vector> vret; + vector vt; + int *c; + + size = nums.size(); + c = new int[size]; + memset(c,0,sizeof(int)*size); + mem = new int[size]; + + k = 0; + for(i = 0; i < size; ++i){ + for(j = 0; j < k; ++j) + if(mem[j] == nums[i]){ + c[j]++; + break; + } + if(j == k){ + mem[k] = nums[i]; + c[k] = 1; + k++; + } + } + + rec(vret,mem,vt,c,0); + + delete[] mem; + delete[] c; + return vret; + } +}; diff --git a/misc/permutations.c b/misc/permutations.c new file mode 100644 index 0000000..5c953dc --- /dev/null +++ b/misc/permutations.c @@ -0,0 +1,49 @@ +/** + * Return an array of arrays of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +void recursion(int **ret,int *flag,int *arr,int *nums, + int numsSize,int *index,int count) +{ + int i; + if(count == numsSize){ + for(i = 0; i < numsSize; ++i) + ret[*index][i] = arr[i]; + (*index)++; + }else{ + for(i = 0; i < numsSize; ++i){ + if(!flag[i]){ + arr[count] = nums[i]; + flag[i] = 1; + recursion(ret,flag,arr,nums,numsSize,index,count+1); + flag[i] = 0; + } + } + } +} + +int** permute(int* nums, int numsSize, int* returnSize) { + int **ret; + int i,len; + int *flag; + int *arr; + + len = 1; + for(i = 2; i <= numsSize; ++i) + len *= i; + + ret = (int **)malloc(sizeof(int *) * len); + for(i = 0; i < len; ++i) + ret[i] = (int *)malloc(sizeof(int) * numsSize); + + flag = (int *)malloc(sizeof(int) * numsSize); + memset(flag,0,sizeof(int) * numsSize); + + arr = (int *)malloc(sizeof(int) * numsSize); + + recursion(ret,flag,arr,nums,numsSize,returnSize,0); + + free(flag); + free(arr); + return ret; +} diff --git a/misc/permutations.cpp b/misc/permutations.cpp new file mode 100644 index 0000000..9ae32da --- /dev/null +++ b/misc/permutations.cpp @@ -0,0 +1,31 @@ +class Solution { +public: + void rec(vector>& vret, vector& nums, vector& vt, + int size, int *flag, int count) + { + if(count == size){ + vret.push_back(vt); + }else{ + for(int i = 0; i < size; ++i){ + if(!flag[i]){ + flag[i] = 1; + vt.push_back(nums[i]); + rec(vret,nums,vt,size,flag,count+1); + vt.pop_back(); + flag[i] = 0; + } + } + } + } + vector> permute(vector& nums) { + vector > vret; + vector vt; + int len = nums.size(); + int *flag = new int[len]; + memset(flag,0,sizeof(int)*len); + rec(vret,nums,vt,len,flag,0); + + delete[] flag; + return vret; + } +}; diff --git a/plus-one.cpp b/misc/plus-one.cpp similarity index 100% rename from plus-one.cpp rename to misc/plus-one.cpp diff --git a/populating-next-right-pointers-in-each-node-ii.c b/misc/populating-next-right-pointers-in-each-node-ii.c similarity index 100% rename from populating-next-right-pointers-in-each-node-ii.c rename to misc/populating-next-right-pointers-in-each-node-ii.c diff --git a/populating-next-right-pointers-in-each-node.c b/misc/populating-next-right-pointers-in-each-node.c similarity index 100% rename from populating-next-right-pointers-in-each-node.c rename to misc/populating-next-right-pointers-in-each-node.c diff --git a/misc/power-of-two.c b/misc/power-of-two.c new file mode 100644 index 0000000..70e8000 --- /dev/null +++ b/misc/power-of-two.c @@ -0,0 +1,10 @@ +bool isPowerOfTwo(int n) { + int count = 0; + + while(n > 0){ + count += (n & 0x1); + n >>= 1; + } + + return count == 1; +} diff --git a/powx-n.c b/misc/powx-n.c similarity index 100% rename from powx-n.c rename to misc/powx-n.c diff --git a/powx-n[2].c b/misc/powx-n[2].c similarity index 100% rename from powx-n[2].c rename to misc/powx-n[2].c diff --git a/misc/product-of-array-except-self.c b/misc/product-of-array-except-self.c new file mode 100644 index 0000000..26fdf93 --- /dev/null +++ b/misc/product-of-array-except-self.c @@ -0,0 +1,31 @@ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int* productExceptSelf(int* nums, int numsSize, int* returnSize) { + int *ret; + int *front; + int *back; + int i; + front = (int *)malloc(sizeof(int) * numsSize); + back = (int *)malloc(sizeof(int) * numsSize); + ret = (int *)malloc(sizeof(int) * numsSize); + + front[0] = 1; + for(i = 1; i < numsSize; ++i) + front[i] = front[i-1]*nums[i-1]; + + back[numsSize-1] = 1; + for(i = numsSize-2; i >= 0; --i) + back[i] = back[i+1] * nums[i+1]; + + for(i = 0; i < numsSize; ++i) + ret[i] = front[i] * back[i]; + + *returnSize = numsSize; + + free(front); + free(back); + + return ret; +} diff --git a/recover-binary-search-tree.c b/misc/recover-binary-search-tree.c similarity index 100% rename from recover-binary-search-tree.c rename to misc/recover-binary-search-tree.c diff --git a/misc/rectangle-area.c b/misc/rectangle-area.c new file mode 100644 index 0000000..37d9731 --- /dev/null +++ b/misc/rectangle-area.c @@ -0,0 +1,12 @@ +int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) { + int ret = (C - A) * (D - B) + (G - E) * (H - F); + int x0 = A > E ? A : E; + int y0 = B > F ? B : F; + int x1 = C < G ? C : G; + int y1 = D < H ? D : H; + + if(x1 <= x0 || y1 <= y0) + return ret; + + return ret - (x1 - x0) * (y1 - y0); +} diff --git a/misc/regular-expression-matching.c b/misc/regular-expression-matching.c new file mode 100644 index 0000000..cb4f9ee --- /dev/null +++ b/misc/regular-expression-matching.c @@ -0,0 +1,16 @@ +bool isMatch(char* s, char* p) { + if(*p == 0) + return *s == 0; + + if(p[1] != '*') + return ((*p == *s) || (*p == '.' && *s != 0)) + && isMatch(s+1,p+1); + + while((*s == *p) || (*p == '.' && *s != 0)){ + if(isMatch(s,p+2)) + return true; + s++; + } + + return isMatch(s,p+2); +} diff --git a/remove-duplicates-from-sorted-array-ii.c b/misc/remove-duplicates-from-sorted-array-ii.c similarity index 100% rename from remove-duplicates-from-sorted-array-ii.c rename to misc/remove-duplicates-from-sorted-array-ii.c diff --git a/remove-duplicates-from-sorted-array.c b/misc/remove-duplicates-from-sorted-array.c similarity index 100% rename from remove-duplicates-from-sorted-array.c rename to misc/remove-duplicates-from-sorted-array.c diff --git a/remove-duplicates-from-sorted-array[2].c b/misc/remove-duplicates-from-sorted-array[2].c similarity index 100% rename from remove-duplicates-from-sorted-array[2].c rename to misc/remove-duplicates-from-sorted-array[2].c diff --git a/remove-duplicates-from-sorted-list-ii.c b/misc/remove-duplicates-from-sorted-list-ii.c similarity index 100% rename from remove-duplicates-from-sorted-list-ii.c rename to misc/remove-duplicates-from-sorted-list-ii.c diff --git a/remove-duplicates-from-sorted-list.c b/misc/remove-duplicates-from-sorted-list.c similarity index 100% rename from remove-duplicates-from-sorted-list.c rename to misc/remove-duplicates-from-sorted-list.c diff --git a/remove-element.c b/misc/remove-element.c similarity index 100% rename from remove-element.c rename to misc/remove-element.c diff --git a/remove-element[2].c b/misc/remove-element[2].c similarity index 100% rename from remove-element[2].c rename to misc/remove-element[2].c diff --git a/remove-linked-list-elements.c b/misc/remove-linked-list-elements.c similarity index 100% rename from remove-linked-list-elements.c rename to misc/remove-linked-list-elements.c diff --git a/remove-nth-node-from-end-of-list.c b/misc/remove-nth-node-from-end-of-list.c similarity index 100% rename from remove-nth-node-from-end-of-list.c rename to misc/remove-nth-node-from-end-of-list.c diff --git a/reorder-list.c b/misc/reorder-list.c similarity index 100% rename from reorder-list.c rename to misc/reorder-list.c diff --git a/misc/restore-ip-addresses.c b/misc/restore-ip-addresses.c new file mode 100644 index 0000000..737b56e --- /dev/null +++ b/misc/restore-ip-addresses.c @@ -0,0 +1,76 @@ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ +int **ret; +int size; + +int cmp(char *a, char *b, int n) +{ + int i; + for(i = 0; i < n; ++i) + if(a[i] != b[i]) + return a[i] - b[i]; + return 0; +} + +int is_valid(char *s,int len) +{ + if(len == 1 && cmp(s,"0",len) >= 0 && + cmp(s,"9",len) <= 0) + return 1; + if(len == 2 && cmp(s,"10",len) >= 0 && + cmp(s,"99",len) <= 0) + return 1; + if(len == 3 && cmp(s,"100",len) >= 0 && + cmp(s,"255",len) <= 0) + return 1; + + return 0; +} + +void helper(char *s, char *ip,int flag) +{ + int n,len,ip_len; + char *tmp; + + len = strlen(s); + if(flag == 3){ + if(!is_valid(s,len)) + return ; + strcat(ip,s); + ret[size++] = strdup(ip); + return ; + } + + ip_len = strlen(ip); + for(n = 1; n <= 3; ++n){ + if(n > len) + break; + tmp = strndup(s,n); + if(!is_valid(tmp,n)) + continue; + + strcat(ip,tmp); + strcat(ip,"."); + helper(s+n,ip,flag+1); + *(ip+ip_len) = 0; + free(tmp); + tmp = NULL; + } +} + +char** restoreIpAddresses(char* s, int* returnSize) { + char *ip; + size = 0; + + ip = (char *)malloc(sizeof(char) * 16); + memset(ip,0,sizeof(char) * 16); + + ret = (char **)malloc(sizeof(char*) * 1000); + helper(s,ip,0); + *returnSize = size; + + ret = (char **)realloc(ret,sizeof(char *) * size); + return ret; +} diff --git a/reverse-bits.c b/misc/reverse-bits.c similarity index 100% rename from reverse-bits.c rename to misc/reverse-bits.c diff --git a/reverse-integer.c b/misc/reverse-integer.c similarity index 100% rename from reverse-integer.c rename to misc/reverse-integer.c diff --git a/reverse-integer[2].c b/misc/reverse-integer[2].c similarity index 100% rename from reverse-integer[2].c rename to misc/reverse-integer[2].c diff --git a/reverse-linked-list-ii.c b/misc/reverse-linked-list-ii.c similarity index 100% rename from reverse-linked-list-ii.c rename to misc/reverse-linked-list-ii.c diff --git a/reverse-linked-list.c b/misc/reverse-linked-list.c similarity index 100% rename from reverse-linked-list.c rename to misc/reverse-linked-list.c diff --git a/reverse-nodes-in-k-group.c b/misc/reverse-nodes-in-k-group.c similarity index 100% rename from reverse-nodes-in-k-group.c rename to misc/reverse-nodes-in-k-group.c diff --git a/reverse-words-in-a-string.c b/misc/reverse-words-in-a-string.c similarity index 100% rename from reverse-words-in-a-string.c rename to misc/reverse-words-in-a-string.c diff --git a/reverse-words-in-a-string.cpp b/misc/reverse-words-in-a-string.cpp similarity index 100% rename from reverse-words-in-a-string.cpp rename to misc/reverse-words-in-a-string.cpp diff --git a/roman-to-integer.c b/misc/roman-to-integer.c similarity index 100% rename from roman-to-integer.c rename to misc/roman-to-integer.c diff --git a/rotate-array.c b/misc/rotate-array.c similarity index 100% rename from rotate-array.c rename to misc/rotate-array.c diff --git a/rotate-array[2].c b/misc/rotate-array[2].c similarity index 100% rename from rotate-array[2].c rename to misc/rotate-array[2].c diff --git a/rotate-array[3].c b/misc/rotate-array[3].c similarity index 100% rename from rotate-array[3].c rename to misc/rotate-array[3].c diff --git a/rotate-image.c b/misc/rotate-image.c similarity index 100% rename from rotate-image.c rename to misc/rotate-image.c diff --git a/rotate-list.c b/misc/rotate-list.c similarity index 100% rename from rotate-list.c rename to misc/rotate-list.c diff --git a/same-tree.c b/misc/same-tree.c similarity index 100% rename from same-tree.c rename to misc/same-tree.c diff --git a/search-a-2d-matrix.c b/misc/search-a-2d-matrix.c similarity index 100% rename from search-a-2d-matrix.c rename to misc/search-a-2d-matrix.c diff --git a/search-for-a-range.c b/misc/search-for-a-range.c similarity index 100% rename from search-for-a-range.c rename to misc/search-for-a-range.c diff --git a/search-in-rotated-sorted-array-ii.c b/misc/search-in-rotated-sorted-array-ii.c similarity index 100% rename from search-in-rotated-sorted-array-ii.c rename to misc/search-in-rotated-sorted-array-ii.c diff --git a/search-in-rotated-sorted-array.c b/misc/search-in-rotated-sorted-array.c similarity index 100% rename from search-in-rotated-sorted-array.c rename to misc/search-in-rotated-sorted-array.c diff --git a/search-insert-position.c b/misc/search-insert-position.c similarity index 100% rename from search-insert-position.c rename to misc/search-insert-position.c diff --git a/set-matrix-zeroes.c b/misc/set-matrix-zeroes.c similarity index 100% rename from set-matrix-zeroes.c rename to misc/set-matrix-zeroes.c diff --git a/misc/simplify-path.c b/misc/simplify-path.c new file mode 100644 index 0000000..c613d20 --- /dev/null +++ b/misc/simplify-path.c @@ -0,0 +1,78 @@ +struct path +{ + char *name; + struct path *parent; + struct path *child; +}; + +struct path *get_path(char *name) +{ + struct path *ret; + ret = (struct path *)malloc(sizeof(struct path)); + ret->name = strdup(name); + ret->parent = NULL; + ret->child = NULL; +} + +void handle_dotdot(struct path **cur) +{ + struct path *tmp; + if(!strcmp((*cur)->name,"/")) + return ; + tmp = *cur; + *cur = (*cur)->parent; + (*cur)->child = NULL; + free(tmp->name); + free(tmp); +} + +char* simplifyPath(char* str) { + struct path *root,*cur,*tmp; + char *start,*ret,*name; + + root = get_path("/"); + cur = root; + + while(*str){ + while(*str == '/') + str++; + if(*str) + goto out; + + start = str; + while(*str && *str != '/') + str++; + + name = strndup(start,str-start); + + if(strcmp(name,".") == 0 || strcmp(name,"..") == 0){ + if(strcmp(name,"..") == 0){ + handle_dotdot(&cur); + } + continue; + } + + tmp = get_path(name); + cur->child = tmp; + tmp->parent = cur; + cur = tmp; + } + +out: + ret = (char *)malloc(sizeof(char) * 4096); + ret[0] = 0; + while(root){ + cur = root; + strcat(ret, root->name); + + if(strcmp(root->name, "/") != 0 && root->child){ + strcat(ret,"/"); + } + root = root->child; + + free(cur->name); + free(cur); + } + + return ret; +} diff --git a/single-number-ii.c b/misc/single-number-ii.c similarity index 100% rename from single-number-ii.c rename to misc/single-number-ii.c diff --git a/single-number-ii[2].c b/misc/single-number-ii[2].c similarity index 100% rename from single-number-ii[2].c rename to misc/single-number-ii[2].c diff --git a/single-number.c b/misc/single-number.c similarity index 100% rename from single-number.c rename to misc/single-number.c diff --git a/sort-colors.c b/misc/sort-colors.c similarity index 100% rename from sort-colors.c rename to misc/sort-colors.c diff --git a/sort-colors[2].c b/misc/sort-colors[2].c similarity index 100% rename from sort-colors[2].c rename to misc/sort-colors[2].c diff --git a/sort-list.c b/misc/sort-list.c similarity index 100% rename from sort-list.c rename to misc/sort-list.c diff --git a/sort-list[2].c b/misc/sort-list[2].c similarity index 100% rename from sort-list[2].c rename to misc/sort-list[2].c diff --git a/spiral-matrix-ii.c b/misc/spiral-matrix-ii.c similarity index 100% rename from spiral-matrix-ii.c rename to misc/spiral-matrix-ii.c diff --git a/spiral-matrix.c b/misc/spiral-matrix.c similarity index 100% rename from spiral-matrix.c rename to misc/spiral-matrix.c diff --git a/sqrtx.c b/misc/sqrtx.c similarity index 100% rename from sqrtx.c rename to misc/sqrtx.c diff --git a/string-to-integer-atoi.c b/misc/string-to-integer-atoi.c similarity index 100% rename from string-to-integer-atoi.c rename to misc/string-to-integer-atoi.c diff --git a/misc/subset.c b/misc/subset.c new file mode 100644 index 0000000..436506d --- /dev/null +++ b/misc/subset.c @@ -0,0 +1,44 @@ +/** + * 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 cmp(const void *a, const void *b) +{ + return *(int *)a - *(int *)b; +} + +int** subsets(int* nums, int numsSize, int** columnSizes, int* returnSize) { + int **ret,*col; + int *tmp; + int count = 1 << numsSize; + int i,j,value,k; + ret = (int **)malloc(sizeof(int *) * count); + tmp = (int *) malloc(sizeof(int) * numsSize); + col = (int *)malloc(sizeof(int) * count); + + qsort(nums,numsSize,sizeof(int),cmp); + for(i = 0; i < count; ++i){ + j = 0; + value = i; + k = 0; + while(value){ + if(value & 0x1){ + tmp[k++] = nums[j]; + } + value >>= 1; + j++; + } + ret[i] = (int *)malloc(sizeof(int) * k); + for(j = 0; j < k; ++j){ + ret[i][j] = tmp[j]; + } + col[i] = k; + } + free(tmp); + + *returnSize = count; + *columnSizes = col; + return ret; +} diff --git a/misc/subsets-ii.cpp b/misc/subsets-ii.cpp new file mode 100644 index 0000000..80660fd --- /dev/null +++ b/misc/subsets-ii.cpp @@ -0,0 +1,41 @@ +class Solution { +public: + static int my_cmp(vector v1,vector v2) + { + int len1 = v1.size(); + int len2 = v2.size(); + if(len1 == len2){ + for(int i = 0; i < len1; ++i) + if(v1[i] != v2[i]) + return v1[i] < v2[i]; + return 0; + } + return len1 < len2; + } + vector> subsetsWithDup(vector& nums) { + vector > ret; + int len = nums.size(); + int i,value,count; + count = 1 << len; + + sort(nums.begin(),nums.end()); + for(i = 0; i < count; ++i){ + vector tmp; + value = i; + int j = 0; + while(value){ + if(value & 0x1) + tmp.push_back(nums[j]); + ++j; + value >>= 1; + } + ret.push_back(tmp); + } + + sort(ret.begin(),ret.end(),my_cmp); + vector >::iterator vit = unique(ret.begin(),ret.end()); + ret.erase(vit,ret.end()); + + return ret; + } +}; diff --git a/misc/subsets-ii[2].cpp b/misc/subsets-ii[2].cpp new file mode 100644 index 0000000..91326b7 --- /dev/null +++ b/misc/subsets-ii[2].cpp @@ -0,0 +1,42 @@ +class Solution { +public: + static int my_cmp(vector v1,vector v2) + { + int len1 = v1.size(); + int len2 = v2.size(); + if(len1 == len2){ + for(int i = 0; i < len1; ++i) + if(v1[i] != v2[i]) + return 1; + return 0; + } + return 1; + } + vector> subsetsWithDup(vector& nums) { + vector > ret; + int len = nums.size(); + int i,value,count; + count = 1 << len; + + sort(nums.begin(),nums.end()); + for(i = 0; i < count; ++i){ + vector tmp; + value = i; + int j = 0; + while(value){ + if(value & 0x1) + tmp.push_back(nums[j]); + ++j; + value >>= 1; + } + int r = ret.size(); + int flag = 0; + for(j = 0; j < r; ++j) + if(!my_cmp(ret[j],tmp)) + flag = 1; + if(!flag) + ret.push_back(tmp); + } + return ret; + } +}; diff --git a/misc/subsets-ii[3].cpp b/misc/subsets-ii[3].cpp new file mode 100644 index 0000000..151f6bf --- /dev/null +++ b/misc/subsets-ii[3].cpp @@ -0,0 +1,23 @@ +ass Solution { +public: + static void subsets(vector> &ret, vector &nums, vector &tmp, int begin) + { + ret.push_back(tmp); + int len = nums.size(); + for(int i = begin; i < len; ++i){ + if(i == begin || nums[i] != nums[i-1]){ + tmp.push_back(nums[i]); + subsets(ret,nums,tmp,i+1); + tmp.pop_back(); + } + } + } + vector> subsetsWithDup(vector& nums) { + sort(nums.begin(),nums.end()); + vector > ret; + vector tmp; + subsets(ret,nums,tmp,0); + return ret; + } + +}; diff --git a/misc/subsets.cpp b/misc/subsets.cpp new file mode 100644 index 0000000..12fd724 --- /dev/null +++ b/misc/subsets.cpp @@ -0,0 +1,23 @@ +class Solution { +public: + vector> subsets(vector& nums) { + vector > ret; + int len = nums.size(); + int num = 1 << len; + int i,k,value; + sort(nums.begin(),nums.end()); + for(i = 0; i < num; ++i){ + vector tmp; + k = 0; + value = i; + while(value){ + if(value & 0x1) + tmp.push_back(nums[k]); + value >>= 1; + ++k; + } + ret.push_back(tmp); + } + return ret; + } +}; diff --git a/substring-with-concatenation-of-all-words.cpp b/misc/substring-with-concatenation-of-all-words.cpp similarity index 100% rename from substring-with-concatenation-of-all-words.cpp rename to misc/substring-with-concatenation-of-all-words.cpp diff --git a/sum-root-to-leaf-numbers.c b/misc/sum-root-to-leaf-numbers.c similarity index 100% rename from sum-root-to-leaf-numbers.c rename to misc/sum-root-to-leaf-numbers.c diff --git a/misc/summary-ranges.c b/misc/summary-ranges.c new file mode 100644 index 0000000..0daa7ac --- /dev/null +++ b/misc/summary-ranges.c @@ -0,0 +1,35 @@ +/** + * Return an array of size *returnSize. + * Note: The returned array must be malloced, assume caller calls free(). + */ + +char *convert_summary(int start, int end){ + char *buf; + buf = (char *)malloc(sizeof(char) * 20); + if(end > start){ + sprintf(buf,"%d->%d",start,end); + }else{ + sprintf(buf,"%d",start); + } + + return buf; +} + +char** summaryRanges(int* nums, int numsSize, int* returnSize) { + char **ret; + int start,i; + + ret = (char **)malloc(sizeof(char *) * numsSize); + start = nums[0]; + *returnSize = 0; + for(i = 0; i < numsSize; ++i){ + if(i == numsSize - 1 || nums[i]+1 != nums[i+1]){ + ret[*returnSize] = convert_summary(start,nums[i]); + if(i != numsSize - 1) + start = nums[i+1]; + (*returnSize)++; + } + } + + return ret; +} diff --git a/swap-nodes-in-pairs.c b/misc/swap-nodes-in-pairs.c similarity index 100% rename from swap-nodes-in-pairs.c rename to misc/swap-nodes-in-pairs.c diff --git a/symmetric-tree.c b/misc/symmetric-tree.c similarity index 100% rename from symmetric-tree.c rename to misc/symmetric-tree.c diff --git a/trapping-rain-water.c b/misc/trapping-rain-water.c similarity index 100% rename from trapping-rain-water.c rename to misc/trapping-rain-water.c diff --git a/misc/triangle.c b/misc/triangle.c new file mode 100644 index 0000000..f58e623 --- /dev/null +++ b/misc/triangle.c @@ -0,0 +1,29 @@ +int minimumTotal(int **triangle, int numRows) { + int **dp; + int i,j,k,m; + dp = (int **)malloc(sizeof(int *) * numRows); + for(k = 1; k <= numRows; ++k) + dp[k-1] = (int *)malloc(sizeof(int *) * k); + + dp[0][0] = triangle[0][0]; + for(i = 1; i < numRows; ++i){ + dp[i][0] = dp[i-1][0] + triangle[i][0]; + for(j = 1; j < i; ++j){ + m = dp[i-1][j-1] < dp[i-1][j] ? dp[i-1][j-1] + : dp[i-1][j]; + dp[i][j] = m + triangle[i][j]; + } + dp[i][j] = dp[i-1][j-1] + triangle[i][j]; + } + + m = dp[numRows-1][0]; + for(i = 1; i < numRows; ++i) + if(dp[numRows-1][i] < m) + m = dp[numRows-1][i]; + + for(i = 0; i < numRows; ++i) + free(dp[i]); + free(dp); + + return m; +} diff --git a/misc/triangle[1].c b/misc/triangle[1].c new file mode 100644 index 0000000..a571961 --- /dev/null +++ b/misc/triangle[1].c @@ -0,0 +1,30 @@ +int minimumTotal(int **triangle, int numRows) { + int *dp; + int i,j,m,prev; + + dp = (int *)malloc(sizeof(int) * numRows); + + dp[0] = triangle[0][0]; + for(i = 1; i < numRows; ++i){ + prev = dp[0] + triangle[i][0]; + for(j = 1; j < i; ++j){ + m = dp[j-1] < dp[j] ? dp[j-1] : dp[j]; + m += triangle[i][j]; + + dp[j-1] = prev; + prev = m; + } + m = dp[j-1] + triangle[i][j]; + dp[j-1] = prev; + dp[j] = m; + } + + m = dp[0]; + for(i = 1; i < numRows; ++i) + if(dp[i] < m) + m = dp[i]; + + free(dp); + + return m; +} diff --git a/two-sum.c b/misc/two-sum.c similarity index 100% rename from two-sum.c rename to misc/two-sum.c diff --git a/unique-binary-search-trees-ii.cpp b/misc/unique-binary-search-trees-ii.cpp similarity index 100% rename from unique-binary-search-trees-ii.cpp rename to misc/unique-binary-search-trees-ii.cpp diff --git a/unique-binary-search-trees.c b/misc/unique-binary-search-trees.c similarity index 100% rename from unique-binary-search-trees.c rename to misc/unique-binary-search-trees.c diff --git a/unique-paths-ii.c b/misc/unique-paths-ii.c similarity index 100% rename from unique-paths-ii.c rename to misc/unique-paths-ii.c diff --git a/unique-paths.c b/misc/unique-paths.c similarity index 100% rename from unique-paths.c rename to misc/unique-paths.c diff --git a/valid-number.c b/misc/valid-number.c similarity index 100% rename from valid-number.c rename to misc/valid-number.c diff --git a/valid-palindrome.c b/misc/valid-palindrome.c similarity index 100% rename from valid-palindrome.c rename to misc/valid-palindrome.c diff --git a/valid-parentheses.c b/misc/valid-parentheses.c similarity index 100% rename from valid-parentheses.c rename to misc/valid-parentheses.c diff --git a/misc/valid-sudoku.c b/misc/valid-sudoku.c new file mode 100644 index 0000000..72dfd53 --- /dev/null +++ b/misc/valid-sudoku.c @@ -0,0 +1,46 @@ +bool isValidSudoku(char** board, int row, int col) { + int i,j; + int key; + int mem[10]; + + for(i = 0; i < row; ++i){ + memset(mem,0,sizeof(int) * 10); + for(j = 0; j < col; ++j){ + if(board[i][j] == '.') + continue; + key = board[i][j] - '0'; + if(mem[key] > 0) + return false; + mem[key]++; + } + } + + for(j = 0; j < col; ++j){ + memset(mem,0,sizeof(int)*10); + for(i = 0; i < row; ++i){ + if(board[i][j] == '.') + continue; + key = board[i][j] - '0'; + if(mem[key] > 0) + return false; + mem[key]++; + } + } + + for(i = 0; i < 9; ++i){ + memset(mem,0,sizeof(int) * 10); + for(j = 0; j < 9; ++j){ + int x = (i / 3) * 3 + (j / 3); + int y = (i % 3) * 3 + (j % 3); + + if(board[x][y] == '.') + continue; + key = board[x][y] - '0'; + if(mem[key] > 0) + return false; + mem[key]++; + } + } + + return true; +} diff --git a/validate-binary-search-tree.c b/misc/validate-binary-search-tree.c similarity index 100% rename from validate-binary-search-tree.c rename to misc/validate-binary-search-tree.c diff --git a/validate-binary-search-tree.cpp b/misc/validate-binary-search-tree.cpp similarity index 100% rename from validate-binary-search-tree.cpp rename to misc/validate-binary-search-tree.cpp diff --git a/validate-binary-search-tree[2].c b/misc/validate-binary-search-tree[2].c similarity index 100% rename from validate-binary-search-tree[2].c rename to misc/validate-binary-search-tree[2].c diff --git a/misc/word-break-ii.cpp b/misc/word-break-ii.cpp new file mode 100644 index 0000000..35a9ca9 --- /dev/null +++ b/misc/word-break-ii.cpp @@ -0,0 +1,42 @@ +class Solution { +public: + void searchWord(vector &ret, string& s, unordered_set& dict, + int idx, string str, int *dp) + { + int size = s.size(); + for(int len = 1; len + idx <= size; ++len){ + string substr = s.substr(idx,len); + if(dp[idx+len] && dict.find(substr) != dict.end()){ + if(idx + len < size){ + searchWord(ret,s,dict,idx+len,str+substr+" ",dp); + }else{ + ret.push_back(str+substr); + return ; + } + } + + } + } + vector wordBreak(string s, unordered_set& wordDict) { + int len = s.size(); + int *dp = new int[len+1]; + vector ret; + memset(dp,0,sizeof(int) * (len+1)); + + dp[0] = 1; + for(int i = 0; i < len; ++i){ + if(dp[i]){ + for(int l = 1; i+l <= len; ++l){ + if(wordDict.find(s.substr(i,l)) != wordDict.end()) + dp[i+l] = 1; + } + } + } + + if(dp[len]) + searchWord(ret,s,wordDict,0,"",dp); + + delete[] dp; + return ret; + } +}; diff --git a/misc/word-break-ii[1].cpp b/misc/word-break-ii[1].cpp new file mode 100644 index 0000000..33dab75 --- /dev/null +++ b/misc/word-break-ii[1].cpp @@ -0,0 +1,45 @@ +class Solution { +public: + void searchWord(vector &ret, string s, unordered_set& dict, + int idx, string str, int *dp) + { + int len = s.size(); + for(int i = 0; i + idx < len; ++i){ + string substr = s.substr(idx,i+1); + if(dp[idx+i] && dict.find(substr) != dict.end()){ + if(idx + i < len-1){ + searchWord(ret,s,dict,idx+i+1,str+substr+" ",dp); + }else{ + ret.push_back(str+substr); + return ; + } + } + } + } + + vector wordBreak(string s, unordered_set& wordDict) { + int len = s.size(); + int *dp = new int[len]; + vector ret; + memset(dp,0,sizeof(int) * len); + + for(int i = 0; i < len; ++i){ + if(wordDict.find(s.substr(0,i+1)) != wordDict.end()){ + dp[i] = 1; + continue; + } + for(int j = 0; j < i; ++j){ + if(dp[j] && wordDict.find(s.substr(j+1,i-j)) != wordDict.end()){ + dp[i] = 1; + break; + } + } + } + + if(dp[len-1]) + searchWord(ret,s,wordDict,0,"",dp); + + delete[] dp; + return ret; + } +}; diff --git a/misc/word-break.cpp b/misc/word-break.cpp new file mode 100644 index 0000000..e529c70 --- /dev/null +++ b/misc/word-break.cpp @@ -0,0 +1,28 @@ +class Solution { +public: + bool wordBreak(string s, unordered_set& wordDict) { + int len = s.size(); + bool *flag = new bool[len]; + bool ret; + memset(flag,0,sizeof(bool) * len); + + for(int i = 0; i < len; ++i){ + if(wordDict.find(s.substr(0,i+1)) != wordDict.end()){ + flag[i] = true; + continue; + } + for(int j = 0; j < i; ++j){ + if(flag[j] && + wordDict.find(s.substr(j+1,i-j)) != wordDict.end()){ + flag[i] = true; + break; + } + } + } + + ret = flag[len-1]; + delete flag; + + return ret; + } +}; diff --git a/misc/word-break[1].cpp b/misc/word-break[1].cpp new file mode 100644 index 0000000..fbcdbcf --- /dev/null +++ b/misc/word-break[1].cpp @@ -0,0 +1,18 @@ +class Solution { +public: + bool wordBreak(string s, unordered_set& wordDict) { + int size = s.size(); + vector dp(size+1,false); + dp[0] = true; + for(int i = 0; i < size; ++i){ + if(dp[i]){ + for(int len = 1; len + i <= size; ++len){ + if(wordDict.find(s.substr(i,len)) != wordDict.end()) + dp[i+len] = true; + } + } + } + + return dp[size]; + } +}; diff --git a/word-search.cpp b/misc/word-search.cpp similarity index 100% rename from word-search.cpp rename to misc/word-search.cpp diff --git a/zigzag-conversion.c b/misc/zigzag-conversion.c similarity index 100% rename from zigzag-conversion.c rename to misc/zigzag-conversion.c diff --git a/python/greedy/assign-cookies.py b/python/greedy/assign-cookies.py new file mode 100644 index 0000000..33f352d --- /dev/null +++ b/python/greedy/assign-cookies.py @@ -0,0 +1,19 @@ +class Solution(object): + def findContentChildren(self, g, s): + """ + :type g: List[int] + :type s: List[int] + :rtype: int + """ + i, j = len(g) - 1, len(s) - 1 + g, s = sorted(g), sorted(s) + ret = 0 + + while min(i, j) >= 0: + if s[j] >= g[i]: + ret += 1 + j -= 1 + + i -= 1 + + return ret diff --git a/python/hash-table/4sum-ii.py b/python/hash-table/4sum-ii.py new file mode 100644 index 0000000..46eb808 --- /dev/null +++ b/python/hash-table/4sum-ii.py @@ -0,0 +1,21 @@ +class Solution(object): + def fourSumCount(self, A, B, C, D): + """ + :type A: List[int] + :type B: List[int] + :type C: List[int] + :type D: List[int] + :rtype: int + """ + d1 = {} + ret = 0; + for a in A: + for b in B: + d1[a+b] = d1.get(a+b,0) + 1 + + for c in C: + for d in D: + key = c + d + ret += d1.get(-key, 0) + + return ret diff --git a/python/hash-table/4sum.py b/python/hash-table/4sum.py new file mode 100644 index 0000000..4fcdee9 --- /dev/null +++ b/python/hash-table/4sum.py @@ -0,0 +1,32 @@ +class Solution(object): + def fourSum(self, nums, target): + nums.sort() + ret = [] + length = len(nums) + for i in range(0,length-3): + if i and nums[i] == nums[i-1]: + continue + + for j in range(i+1,length-2): + if j != i+1 and nums[j] == nums[j-1]: + continue + + start = j + 1 + end = length - 1 + + sum = target - nums[i] - nums[j] + while start < end: + if sum == nums[start] + nums[end]: + ret.append([nums[i], nums[j], nums[start], nums[end]]) + start += 1 + end -= 1 + while start < end and nums[start] == nums[start-1]: + start += 1 + while start < end and nums[end] == nums[end+1]: + end -= 1 + elif sum < nums[start] + nums[end]: + end -= 1 + else: + start += 1 + + return ret diff --git a/python/hash-table/anagrams.py b/python/hash-table/anagrams.py new file mode 100644 index 0000000..e78408f --- /dev/null +++ b/python/hash-table/anagrams.py @@ -0,0 +1,16 @@ +class Solution(object): + def groupAnagrams(self, strs): + d = {} + ret = [] + + for s in strs: + key = ''.join(sorted(s)) + + if d.get(key, -1) == -1: + d[key] = len(ret) + ret.append([s]) + continue + + ret[d[key]].append(s) + + return ret diff --git a/python/hash-table/binary-tree-inorder-traversal.py b/python/hash-table/binary-tree-inorder-traversal.py new file mode 100644 index 0000000..5f8fc8e --- /dev/null +++ b/python/hash-table/binary-tree-inorder-traversal.py @@ -0,0 +1,14 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def inorderTraversal(self, root): + if root is None: + return [] + + return self.inorderTraversal(root.left) + [root.val] \ + + self.inorderTraversal(root.right) diff --git a/python/hash-table/binary-tree-inorder-traversal[1].py b/python/hash-table/binary-tree-inorder-traversal[1].py new file mode 100644 index 0000000..8b402d7 --- /dev/null +++ b/python/hash-table/binary-tree-inorder-traversal[1].py @@ -0,0 +1,22 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def inorderTraversal(self, root): + res = [] + st = [] + + while root or st: + while root: + st.append(root) + root = root.left + + root = st.pop() + res.append(root.val) + root = root.right + + return res diff --git a/python/hash-table/bulls-and-cows.py b/python/hash-table/bulls-and-cows.py new file mode 100644 index 0000000..fed101a --- /dev/null +++ b/python/hash-table/bulls-and-cows.py @@ -0,0 +1,20 @@ +class Solution(object): + def getHint(self, secret, guess): + d = {} + bulls, cows = 0, 0 + for i in xrange(len(secret)): + if secret[i] == guess[i]: + bulls += 1 + else: + if d.get(secret[i]): + d[secret[i]] += 1 + else: + d[secret[i]] = 1 + + for i in xrange(len(secret)): + if secret[i] != guess[i] and \ + d.get(guess[i]) > 0: + cows += 1 + d[guess[i]] -= 1 + + return str(bulls) + 'A' + str(cows) + 'B' diff --git a/python/hash-table/contains-duplicate-ii.py b/python/hash-table/contains-duplicate-ii.py new file mode 100644 index 0000000..331cf64 --- /dev/null +++ b/python/hash-table/contains-duplicate-ii.py @@ -0,0 +1,11 @@ +class Solution(object): + def containsNearbyDuplicate(self, nums, k): + d = {} + for i in range(len(nums)): + idx = d.get(nums[i]) + if idx >= 0 and i - idx <= k: + return True + + d[nums[i]] = i + + return False diff --git a/python/hash-table/contains-duplicate.py b/python/hash-table/contains-duplicate.py new file mode 100644 index 0000000..b86ec89 --- /dev/null +++ b/python/hash-table/contains-duplicate.py @@ -0,0 +1,8 @@ +class Solution(object): + def containsDuplicate(self, nums): + nums.sort() + for i in range(len(nums)-1): + if nums[i] == nums[i+1]: + return True + + return False diff --git a/python/hash-table/contains-duplicate[1].py b/python/hash-table/contains-duplicate[1].py new file mode 100644 index 0000000..fa0c3a1 --- /dev/null +++ b/python/hash-table/contains-duplicate[1].py @@ -0,0 +1,3 @@ +class Solution(object): + def containsDuplicate(self, nums): + return len(nums) != len(set(nums)) diff --git a/python/hash-table/contiguous-array.py b/python/hash-table/contiguous-array.py new file mode 100644 index 0000000..6d24d4c --- /dev/null +++ b/python/hash-table/contiguous-array.py @@ -0,0 +1,18 @@ +class Solution(object): + def findMaxLength(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + d = {0 : -1} + cur_sum = 0 + res = 0 + + for i in range(len(nums)): + cur_sum += (2 * nums[i] - 1) + if cur_sum in d: + res = res if res > i - d[cur_sum] else i - d[cur_sum] + else: + d[cur_sum] = i + + return res diff --git a/python/hash-table/copy-list-with-random-pointer.py b/python/hash-table/copy-list-with-random-pointer.py new file mode 100644 index 0000000..b46d7ea --- /dev/null +++ b/python/hash-table/copy-list-with-random-pointer.py @@ -0,0 +1,36 @@ +# Definition for singly-linked list with a random pointer. +# class RandomListNode(object): +# def __init__(self, x): +# self.label = x +# self.next = None +# self.random = None + +class Solution(object): + def copyRandomList(self, head): + root = RandomListNode(0) + root.next = head + while head: + new_node = RandomListNode(head.label) + new_node.next = head.next + head.next = new_node + head = head.next.next + + head = root.next + while head: + new_node = head.next + if head.random: + new_node.random = head.random.next + + head = head.next.next + + + prev = root + head = root.next + while head: + new_node = head.next + head.next = head.next.next + prev.next = new_node + prev = new_node + head = head.next + + return root.next diff --git a/python/hash-table/copy-list-with-random-pointer[1].py b/python/hash-table/copy-list-with-random-pointer[1].py new file mode 100644 index 0000000..20b5007 --- /dev/null +++ b/python/hash-table/copy-list-with-random-pointer[1].py @@ -0,0 +1,28 @@ +# Definition for singly-linked list with a random pointer. +# class RandomListNode(object): +# def __init__(self, x): +# self.label = x +# self.next = None +# self.random = None + +class Solution(object): + def copyRandomList(self, head): + d = {} + root = RandomListNode(0) + + d[None] = None + saved_head = head + prev = root + while head: + new_node = RandomListNode(head.label) + prev.next = new_node + prev = prev.next + d[head] = new_node + head = head.next + + head = saved_head + while head: + d[head].random = d[head.random] + head = head.next + + return root.next diff --git a/python/hash-table/count-primes.py b/python/hash-table/count-primes.py new file mode 100644 index 0000000..c674193 --- /dev/null +++ b/python/hash-table/count-primes.py @@ -0,0 +1,12 @@ +class Solution(object): + def countPrimes(self, n): + arr = [0] * n + count = 0 + for i in xrange(2,n): + if arr[i] != 0: + continue + count += 1 + for j in xrange(2*i,n,i): + arr[j] = 1 + + return count diff --git a/python/hash-table/encode-and-decode-tinyurl.py b/python/hash-table/encode-and-decode-tinyurl.py new file mode 100644 index 0000000..b7fb20e --- /dev/null +++ b/python/hash-table/encode-and-decode-tinyurl.py @@ -0,0 +1,42 @@ +class Codec: + def __init__(self): + self.d = {} + self.s = '0123456789qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM' + + def spliturl(self, url): + index = url.find("/",7) + return url[0:index + 1], url[index+1:] + + def getshort(self): + while True: + short = "" + for i in range(7): + short += random.choice(self.s) + if short not in self.d: + return short + + return '' + + def encode(self, longUrl): + """Encodes a URL to a shortened URL. + + :type longUrl: str + :rtype: str + """ + addr, long = self.spliturl(longUrl) + short = self.getshort() + self.d[short] = long + return addr + short + + def decode(self, shortUrl): + """Decodes a shortened URL to its original URL. + + :type shortUrl: str + :rtype: str + """ + addr, short = self.spliturl(shortUrl) + return addr + self.d[short] + +# Your Codec object will be instantiated and called as such: +# codec = Codec() +# codec.decode(codec.encode(url)) diff --git a/python/hash-table/find-all-anagrams-in-a-string.py b/python/hash-table/find-all-anagrams-in-a-string.py new file mode 100644 index 0000000..0076a4a --- /dev/null +++ b/python/hash-table/find-all-anagrams-in-a-string.py @@ -0,0 +1,23 @@ +class Solution(object): + def findAnagrams(self, s, p): + """ + :type s: str + :type p: str + :rtype: List[int] + """ + ls, lp = len(s), len(p) + ret = [] + cp = collections.Counter(p) + cs = collections.Counter() + + for i in range(ls): + cs[s[i]] += 1 + + if i >= lp: + cs[s[i - lp]] -= 1 + if cs[s[i - lp]] == 0: + del cs[s[i - lp]] + if cs == cp: + ret.append(i - lp + 1) + + return ret diff --git a/python/hash-table/find-all-anagrams-in-a-string[1].py b/python/hash-table/find-all-anagrams-in-a-string[1].py new file mode 100644 index 0000000..99fcccf --- /dev/null +++ b/python/hash-table/find-all-anagrams-in-a-string[1].py @@ -0,0 +1,25 @@ +class Solution(object): + def findAnagrams(self, s, p): + """ + :type s: str + :type p: str + :rtype: List[int] + """ + ls, lp = len(s), len(p) + cp = collections.Counter(p) + ret = [] + count = lp + + for i in range(ls): + if cp[s[i]] > 0: + count -= 1 + cp[s[i]] -= 1 + if i >= lp: + if cp[s[i - lp]] >= 0: + count += 1 + cp[s[i - lp]] += 1 + + if count == 0: + ret.append(i - lp + 1) + + return ret diff --git a/python/hash-table/find-the-difference.py b/python/hash-table/find-the-difference.py new file mode 100644 index 0000000..816252b --- /dev/null +++ b/python/hash-table/find-the-difference.py @@ -0,0 +1,13 @@ +class Solution(object): + def findTheDifference(self, s, t): + h = {}; + for key in s: + if h.get(key) is None: + h[key] = 1 + else: + h[key] += 1 + + for key in t: + if h.get(key,0) == 0: + return key + h[key] -= 1 diff --git a/python/hash-table/happy-number.py b/python/hash-table/happy-number.py new file mode 100644 index 0000000..98ea652 --- /dev/null +++ b/python/hash-table/happy-number.py @@ -0,0 +1,19 @@ +class Solution(object): + def __init__(self): + self.count = 0 + + def isHappy(self, n): + if n == 1: + return True + if self.count == 100: + return False + + d = 0 + tmp = 0 + while n > 0: + d = n % 10 + n /= 10 + tmp += (d * d) + + self.count += 1 + return self.isHappy(tmp) diff --git a/python/hash-table/happy-number[1].py b/python/hash-table/happy-number[1].py new file mode 100644 index 0000000..2be671d --- /dev/null +++ b/python/hash-table/happy-number[1].py @@ -0,0 +1,11 @@ +class Solution(object): + def isHappy(self, n): + s = set() + + while True: + s.add(n) + n = sum([int(x) * int(x) for x in list(str(n))]) + if n == 1 or n in s: + break + + return n == 1 diff --git a/python/hash-table/insert-delete-getrandom-o1-duplicates-allowed.py b/python/hash-table/insert-delete-getrandom-o1-duplicates-allowed.py new file mode 100644 index 0000000..7d9f2f8 --- /dev/null +++ b/python/hash-table/insert-delete-getrandom-o1-duplicates-allowed.py @@ -0,0 +1,51 @@ +class RandomizedCollection(object): + + def __init__(self): + """ + Initialize your data structure here. + """ + self.d = collections.defaultdict(set) + self.l = [] + + def insert(self, val): + """ + Inserts a value to the collection. Returns true if the collection did not already contain the specified element. + :type val: int + :rtype: bool + """ + bool_ret = val not in self.l + self.d[val].add(len(self.l)) + self.l.append(val) + return bool_ret + + def remove(self, val): + """ + Removes a value from the collection. Returns true if the collection contained the specified element. + :type val: int + :rtype: bool + """ + if val not in self.l: + return False + last_val = self.l.pop() + self.d[last_val].remove(len(self.l)) + if val != last_val: + index = self.d[val].pop() + self.l[index] = last_val + self.d[last_val].add(index) + + if not self.d[val]: + del self.d[val] + return True + + def getRandom(self): + """ + Get a random element from the collection. + :rtype: int + """ + return self.l[random.randint(0, len(self.l) - 1)] + +# Your RandomizedCollection object will be instantiated and called as such: +# obj = RandomizedCollection() +# param_1 = obj.insert(val) +# param_2 = obj.remove(val) +# param_3 = obj.getRandom() diff --git a/python/hash-table/insert-delete-getrandom-o1.py b/python/hash-table/insert-delete-getrandom-o1.py new file mode 100644 index 0000000..4018e6e --- /dev/null +++ b/python/hash-table/insert-delete-getrandom-o1.py @@ -0,0 +1,48 @@ +class RandomizedSet(object): + + def __init__(self): + """ + Initialize your data structure here. + """ + self.d = {} + self.l = [] + + def insert(self, val): + """ + Inserts a value to the set. Returns true if the set did not already contain the specified element. + :type val: int + :rtype: bool + """ + if val in self.d: + return False + self.l.append(val) + self.d[val] = len(self.l) - 1 + return True + + def remove(self, val): + """ + Removes a value from the set. Returns true if the set contained the specified element. + :type val: int + :rtype: bool + """ + if val not in self.d: + return False + self.l[self.d[val]] = self.l[-1] + self.d[self.l[-1]] = self.d[val] + self.l.pop() + del self.d[val] + + return True + + def getRandom(self): + """ + Get a random element from the set. + :rtype: int + """ + return self.l[random.randint(0, len(self.d) - 1)] + +# Your RandomizedSet object will be instantiated and called as such: +# obj = RandomizedSet() +# param_1 = obj.insert(val) +# param_2 = obj.remove(val) +# param_3 = obj.getRandom() diff --git a/python/hash-table/intersection-of-two-arrays-ii.py b/python/hash-table/intersection-of-two-arrays-ii.py new file mode 100644 index 0000000..50858c1 --- /dev/null +++ b/python/hash-table/intersection-of-two-arrays-ii.py @@ -0,0 +1,17 @@ +class Solution(object): + def intersect(self, nums1, nums2): + ret = [] + d = {} + + for val in nums1: + if d.get(val): + d[val] += 1 + else: + d[val] = 1 + + for val in nums2: + if d.get(val,0) > 0: + ret.append(val) + d[val] -= 1 + + return ret diff --git a/python/hash-table/intersection-of-two-arrays.py b/python/hash-table/intersection-of-two-arrays.py new file mode 100644 index 0000000..735cfc6 --- /dev/null +++ b/python/hash-table/intersection-of-two-arrays.py @@ -0,0 +1,4 @@ +class Solution(object): + def intersection(self, nums1, nums2): + return [val for val in set(nums1) if val in nums2] + #'return list(set(nums1) & set(nums2))' is also OK diff --git a/python/hash-table/island-perimeter.py b/python/hash-table/island-perimeter.py new file mode 100644 index 0000000..e6ab88d --- /dev/null +++ b/python/hash-table/island-perimeter.py @@ -0,0 +1,17 @@ +class Solution(object): + def islandPerimeter(self, grid): + row = len(grid) + col = len(grid[0]) if row else 0 + p = 0 + for i in range(row): + for j in range(col): + if grid[i][j] == 0: + continue + p += 4 + + if i > 0 and grid[i-1][j]: + p -= 2 + if j > 0 and grid[i][j-1]: + p -= 2 + + return p diff --git a/python/hash-table/isomorphic-strings.py b/python/hash-table/isomorphic-strings.py new file mode 100644 index 0000000..245b58d --- /dev/null +++ b/python/hash-table/isomorphic-strings.py @@ -0,0 +1,17 @@ +class Solution(object): + def isIsomorphic(self, s, t): + slen = len(s) + flag = {} + visited = {} + + for i in range(slen): + if flag.get(s[i],-1) == -1: + if visited.get(t[i],-1) != -1: + return False + + flag[s[i]] = t[i] + visited[t[i]] = 1 + elif flag.get(s[i]) != t[i]: + return False + + return True diff --git a/python/hash-table/isomorphic-strings[1].py b/python/hash-table/isomorphic-strings[1].py new file mode 100644 index 0000000..9ede251 --- /dev/null +++ b/python/hash-table/isomorphic-strings[1].py @@ -0,0 +1,13 @@ +class Solution(object): + def isIsomorphic(self, s, t): + ms = {} + mt = {} + + for i in range(len(s)): + if ms.get(s[i],-1) != mt.get(t[i],-1): + return False + + ms[s[i]] = i + mt[t[i]] = i + + return True diff --git a/python/hash-table/keyboard-row.py b/python/hash-table/keyboard-row.py new file mode 100644 index 0000000..6278c0c --- /dev/null +++ b/python/hash-table/keyboard-row.py @@ -0,0 +1,22 @@ +class Solution(object): + def findWords(self, words): + """ + :type words: List[str] + :rtype: List[str] + """ + line = ["qwertyuiop", "asdfghjkl", "zxcvbnm"] + res = [] + for word in words: + for m in line: + if word[0].lower() in m: + l = m + break + flag = 1 + for w in word: + if w.lower() not in l: + flag = 0 + break + if flag: + res.append(word) + + return res diff --git a/python/hash-table/keyboard-row[1].py b/python/hash-table/keyboard-row[1].py new file mode 100644 index 0000000..6d507de --- /dev/null +++ b/python/hash-table/keyboard-row[1].py @@ -0,0 +1,17 @@ +class Solution(object): + def findWords(self, words): + """ + :type words: List[str] + :rtype: List[str] + """ + s1 = set("qwertyuiop") + s2 = set("asdfghjkl") + s3 = set("zxcvbnm") + + res = [] + for word in words: + sw = set(word.lower()) + if sw.issubset(s1) or sw.issubset(s2) or sw.issubset(s3): + res.append(word) + + return res diff --git a/python/hash-table/longest-palindrome.py b/python/hash-table/longest-palindrome.py new file mode 100644 index 0000000..79c0e65 --- /dev/null +++ b/python/hash-table/longest-palindrome.py @@ -0,0 +1,19 @@ +class Solution(object): + def longestPalindrome(self, s): + """ + :type s: str + :rtype: int + """ + d = {} + ret = 0 + plus = 0 + for c in s: + d[c] = d.get(c,0) + 1 + + for (key,count) in d.items(): + ret += count + if count % 2 : + ret -= 1 + plus = 1 + + return ret + plus diff --git a/python/hash-table/longest-substring-without-repeating-characters.py b/python/hash-table/longest-substring-without-repeating-characters.py new file mode 100644 index 0000000..8c28f52 --- /dev/null +++ b/python/hash-table/longest-substring-without-repeating-characters.py @@ -0,0 +1,12 @@ +class Solution(object): + def lengthOfLongestSubstring(self, s): + index = {} + last_index = 0 + ret = 0 + for i in xrange(len(s)): + if index.get(s[i],-1) >= last_index: + last_index = index[s[i]] + 1 + index[s[i]] = i + ret = max((i - last_index + 1),ret) + + return ret diff --git a/python/hash-table/maximal-rectangle.py b/python/hash-table/maximal-rectangle.py new file mode 100644 index 0000000..7db62d7 --- /dev/null +++ b/python/hash-table/maximal-rectangle.py @@ -0,0 +1,24 @@ +class Solution(object): + def maximalRectangle(self, matrix): + if len(matrix) == 0: + return 0 + + max_area = 0 + st = [0] * (len(matrix[0]) + 1) + height = [0] * (len(matrix[0]) + 1) + for i in range(len(matrix)): + top = -1 + for j in range(len(matrix[i]) + 1): + if j < len(matrix[i]): + height[j] = ((height[j] + 1) if (matrix[i][j] == '1') else 0) + + while top > -1 and height[j] < height[st[top]]: + h = height[st[top]] + top -= 1 + w = j if (top == -1) else (j - st[top] - 1) + if h * w > max_area: + max_area = h * w + top += 1 + st[top] = j + + return max_area diff --git a/python/hash-table/minimum-window-substring.py b/python/hash-table/minimum-window-substring.py new file mode 100644 index 0000000..f1d06fa --- /dev/null +++ b/python/hash-table/minimum-window-substring.py @@ -0,0 +1,35 @@ +class Solution(object): + def minWindow(self, s, t): + """ + :type s: str + :type t: str + :rtype: str + """ + init_hash = {} + cur_hash = dict.fromkeys(t,0) + for ch in t: + init_hash[ch] = init_hash.get(ch, 0) + 1 + end = 0 + start = 0 + t_match = 0 + ret = "" + for end in range(len(s)): + if init_hash.get(s[end], 0) == 0: + continue + cur_hash[s[end]] += 1 + if cur_hash[s[end]] <= init_hash[s[end]]: + t_match += 1 + if t_match < len(t): + continue + while init_hash.get(s[start], 0) == 0 or \ + cur_hash[s[start]] > init_hash[s[start]]: + if cur_hash.get(s[start], 0) > 0: + cur_hash[s[start]] -= 1 + start += 1 + if len(ret) == 0 or end - start + 1 < len(ret): + ret = s[start:end+1] + t_match -= 1 + cur_hash[s[start]] -= 1 + start += 1 + + return ret diff --git a/python/hash-table/most-frequent-subtree-sum.py b/python/hash-table/most-frequent-subtree-sum.py new file mode 100644 index 0000000..052dc4b --- /dev/null +++ b/python/hash-table/most-frequent-subtree-sum.py @@ -0,0 +1,38 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def __init__(self): + self.d = {} + + def depth(self, root): + if not root: + return 0 + left = self.depth(root.left) + right = self.depth(root.right) + + total = root.val + left + right + self.d[total] = self.d.get(total, 0) + 1 + return total + + def findFrequentTreeSum(self, root): + """ + :type root: TreeNode + :rtype: List[int] + """ + self.depth(root) + res = [] + prev = -1 + for value, count in sorted(self.d.items(), reverse=True, key=lambda x:x[1]): + if prev == -1: + prev = count + if count == prev: + res.append(value) + else: + break + + return res diff --git a/python/hash-table/most-frequent-subtree-sum[1].py b/python/hash-table/most-frequent-subtree-sum[1].py new file mode 100644 index 0000000..9255888 --- /dev/null +++ b/python/hash-table/most-frequent-subtree-sum[1].py @@ -0,0 +1,30 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def __init__(self): + self.c = collections.Counter() + + def depth(self, root): + if not root: + return 0 + left = self.depth(root.left) + right = self.depth(root.right) + + total = root.val + left + right + self.c[total] += 1 + return total + + def findFrequentTreeSum(self, root): + """ + :type root: TreeNode + :rtype: List[int] + """ + self.depth(root) + maxfreq = max(self.c.values() + [None]) + + return [k for k, v in self.c.items() if v == maxfreq] diff --git a/python/hash-table/number-of-boomerangs.py b/python/hash-table/number-of-boomerangs.py new file mode 100644 index 0000000..8168bf5 --- /dev/null +++ b/python/hash-table/number-of-boomerangs.py @@ -0,0 +1,21 @@ +class Solution(object): + def dist(self, x1, y1, x2, y2): + return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) + + def numberOfBoomerangs(self, points): + """ + :type points: List[List[int]] + :rtype: int + """ + ret = 0 + for i in range(len(points)): + d = {} + for j in range(len(points)): + if i == j: + continue + key = self.dist(points[i][0], points[i][1], \ + points[j][0], points[j][1]) + ret += (2 * d.get(key,0)) + d[key] = d.get(key, 0) + 1 + + return ret diff --git a/python/hash-table/palindrome-pairs.py b/python/hash-table/palindrome-pairs.py new file mode 100644 index 0000000..5ef5cb8 --- /dev/null +++ b/python/hash-table/palindrome-pairs.py @@ -0,0 +1,26 @@ +class Solution(object): + def palindromePairs(self, words): + """ + :type words: List[str] + :rtype: List[List[int]] + """ + d = {word: i for i, word in enumerate(words)} + res = collections.defaultdict(set) + + for index, word in enumerate(words): + for i in range(len(word)): + r_suf = word[i:][::-1] + w = r_suf + word + if r_suf in d and w == w[::-1] and index != d[r_suf]: + res[d[r_suf]].add(index) + + r_pre = word[:i][::-1] + w = word + r_pre + if r_pre in d and w == w[::-1] and index != d[r_pre]: + res[index].add(d[r_pre]) + + if "" in d and word == word[::-1] and index != d[""]: + res[d[""]].add(index) + res[index].add(d[""]) + + return [[key, value] for key, values in res.items() for value in values] diff --git a/python/hash-table/palindrome-pairs[1].py b/python/hash-table/palindrome-pairs[1].py new file mode 100644 index 0000000..15533f2 --- /dev/null +++ b/python/hash-table/palindrome-pairs[1].py @@ -0,0 +1,20 @@ +class Solution(object): + def palindromePairs(self, words): + """ + :type words: List[str] + :rtype: List[List[int]] + """ + d = {word: i for i, word in enumerate(words)} + res = [] + + for index, word in enumerate(words): + for i in range(len(word) + 1): + right = word[i:][::-1] + left = word[:i][::-1] + if left in d and right == right[::-1] and index != d[left]: + res.append([index, d[left]]) + + if i > 0 and right in d and left == left[::-1] and index != d[right]: + res.append([d[right], index]) + + return res diff --git a/python/hash-table/repeated-dna-sequences.py b/python/hash-table/repeated-dna-sequences.py new file mode 100644 index 0000000..d5468ca --- /dev/null +++ b/python/hash-table/repeated-dna-sequences.py @@ -0,0 +1,15 @@ +class Solution(object): + def findRepeatedDnaSequences(self, s): + """ + :type s: str + :rtype: List[str] + """ + d = set() + res = set() + for i in range(len(s)-9): + if s[i:i + 10] in d: + res.add(s[i:i + 10]) + else: + d.add(s[i:i + 10]) + + return list(res) diff --git a/python/hash-table/single-number.py b/python/hash-table/single-number.py new file mode 100644 index 0000000..77688be --- /dev/null +++ b/python/hash-table/single-number.py @@ -0,0 +1,7 @@ +class Solution(object): + def singleNumber(self, nums): + ret = 0 + for val in nums: + ret ^= val + + return ret diff --git a/python/hash-table/single-number[1].py b/python/hash-table/single-number[1].py new file mode 100644 index 0000000..fcc2048 --- /dev/null +++ b/python/hash-table/single-number[1].py @@ -0,0 +1,10 @@ +class Solution(object): + def singleNumber(self, nums): + h = {} + + for val in nums: + h[val] = 1 if h.get(val,-1) == -1 else 2 + + for val in nums: + if h[val] == 1: + return val diff --git a/python/hash-table/sort-characters-by-frequency.py b/python/hash-table/sort-characters-by-frequency.py new file mode 100644 index 0000000..983c480 --- /dev/null +++ b/python/hash-table/sort-characters-by-frequency.py @@ -0,0 +1,24 @@ +class Solution(object): + def frequencySort(self, s): + """ + :type s: str + :rtype: str + """ + d = {} + l = [] + for c in s: + d[c] = d.get(c, 0) + 1 + + for c in d: + index = 0 + while index < len(l): + if d[l[index]] < d[c]: + break + index += 1 + l.insert(index, c) + + res = "" + for c in l: + res += c * d[c] + + return res diff --git a/python/hash-table/sort-characters-by-frequency[1].py b/python/hash-table/sort-characters-by-frequency[1].py new file mode 100644 index 0000000..251dd6d --- /dev/null +++ b/python/hash-table/sort-characters-by-frequency[1].py @@ -0,0 +1,7 @@ +class Solution(object): + def frequencySort(self, s): + """ + :type s: str + :rtype: str + """ + return ''.join(c * t for c, t in collections.Counter(s).most_common()) diff --git a/python/hash-table/sudoku-solver.py b/python/hash-table/sudoku-solver.py new file mode 100644 index 0000000..8827965 --- /dev/null +++ b/python/hash-table/sudoku-solver.py @@ -0,0 +1,37 @@ +class Solution(object): + def solveSudoku(self, board): + """ + :type board: List[List[str]] + :rtype: void Do not return anything, modify board in-place instead. + """ + def isVaild(x, y): + tmp = board[x][y] + board[x][y] = 'D' + for i in range(9): + if board[i][y] == tmp: + return False + if board[x][i] == tmp: + return False + + for i in range(3): + for j in range(3): + if board[(x // 3) * 3 + i][(y // 3) * 3 + j] == tmp: + return False + + board[x][y] = tmp + return True + + def dfs(board): + for i in range(9): + for j in range(9): + if board[i][j] != '.': + continue + for val in '123456789': + board[i][j] = val + if isVaild(i, j) and dfs(board): + return True + board[i][j] = '.' + return False + return True + + dfs(board) diff --git a/python/hash-table/top-k-frequent-elements.py b/python/hash-table/top-k-frequent-elements.py new file mode 100644 index 0000000..17ee2a3 --- /dev/null +++ b/python/hash-table/top-k-frequent-elements.py @@ -0,0 +1,8 @@ +class Solution(object): + def topKFrequent(self, nums, k): + """ + :type nums: List[int] + :type k: int + :rtype: List[int] + """ + return [c for c, t in collections.Counter(nums).most_common(k)] diff --git a/python/hash-table/top-k-frequent-elements[1].py b/python/hash-table/top-k-frequent-elements[1].py new file mode 100644 index 0000000..7bcbafe --- /dev/null +++ b/python/hash-table/top-k-frequent-elements[1].py @@ -0,0 +1,19 @@ +class Solution(object): + def topKFrequent(self, nums, k): + """ + :type nums: List[int] + :type k: int + :rtype: List[int] + """ + d = {} + for val in nums: + d[val] = d.get(val, 0) + 1 + + res = [] + for val, count in sorted(d.items(), reverse=True, key=lambda x:x[1]): + res.append(val) + k -= 1 + if k == 0: + break + + return res diff --git a/python/hash-table/two-sum.py b/python/hash-table/two-sum.py new file mode 100644 index 0000000..7439af2 --- /dev/null +++ b/python/hash-table/two-sum.py @@ -0,0 +1,14 @@ +class Solution(object): + def twoSum(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: List[int] + """ + d = {} + for index, val in enumerate(nums): + if target - val in d: + return [d[target-val], index] + d[val] = index + + return [] diff --git a/python/hash-table/valid-anagram.py b/python/hash-table/valid-anagram.py new file mode 100644 index 0000000..339abfd --- /dev/null +++ b/python/hash-table/valid-anagram.py @@ -0,0 +1,15 @@ +class Solution(object): + def isAnagram(self, s, t): + if len(s) != len(t): + return False + + h = [0] * 26 + for i in range(len(s)): + h[ord(s[i]) - ord('a')] = h[ord(s[i]) - ord('a')] + 1 + h[ord(t[i]) - ord('a')] = h[ord(t[i]) - ord('a')] - 1 + + for val in h: + if val != 0: + return False + + return True diff --git a/python/hash-table/valid-sudoku.py b/python/hash-table/valid-sudoku.py new file mode 100644 index 0000000..fa115dc --- /dev/null +++ b/python/hash-table/valid-sudoku.py @@ -0,0 +1,36 @@ +class Solution(object): + def isValidSudoku(self, board): + """ + :type board: List[List[str]] + :rtype: bool + """ + for i in range(len(board)): + d = {} + for j in range(len(board[i])): + if board[i][j] == '.': + continue + if board[i][j] in d: + return False + d[board[i][j]] = 1 + + for j in range(len(board[0])): + d = {} + for i in range(len(board)): + if board[i][j] == '.': + continue + if board[i][j] in d: + return False + d[board[i][j]] = 1 + + for i in range(9): + d = {} + for j in range(9): + row = (i // 3) * 3 + j // 3 + col = (i % 3) * 3 + j % 3 + if board[row][col] == '.': + continue + if board[row][col] in d: + return False + d[board[row][col]] = 1 + + return True diff --git a/python/hash-table/word-pattern.py b/python/hash-table/word-pattern.py new file mode 100644 index 0000000..8b0bd8c --- /dev/null +++ b/python/hash-table/word-pattern.py @@ -0,0 +1,21 @@ +class Solution(object): + def wordPattern(self, pattern, str): + """ + :type pattern: str + :type str: str + :rtype: bool + """ + ls = str.split() + d1 = {} + d2 = {} + if(len(ls) != len(pattern)): + return False + for c1, c2 in zip(pattern, ls): + if c1 not in d1: + d1[c1] = c2 + if c2 not in d2: + d2[c2] = c1 + if d1[c1] != c2 or d2[c2] != c1: + return False + + return True diff --git a/python/hash-table/word-pattern[1].py b/python/hash-table/word-pattern[1].py new file mode 100644 index 0000000..3fccac9 --- /dev/null +++ b/python/hash-table/word-pattern[1].py @@ -0,0 +1,9 @@ +class Solution(object): + def wordPattern(self, pattern, str): + """ + :type pattern: str + :type str: str + :rtype: bool + """ + words = str.split() + return map(pattern.find, pattern) == map(words.index, words) diff --git a/python/stack/binary-tree-inorder-traversal.py b/python/stack/binary-tree-inorder-traversal.py new file mode 100644 index 0000000..742cda8 --- /dev/null +++ b/python/stack/binary-tree-inorder-traversal.py @@ -0,0 +1,13 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def inorderTraversal(self, root): + if root is None: + return [] + return self.inorderTraversal(root.left) + [root.val] + \ + self.inorderTraversal(root.right) diff --git a/python/stack/binary-tree-inorder-traversal[2].py b/python/stack/binary-tree-inorder-traversal[2].py new file mode 100644 index 0000000..642518c --- /dev/null +++ b/python/stack/binary-tree-inorder-traversal[2].py @@ -0,0 +1,22 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def inorderTraversal(self, root): + st = [] + list = [] + + while root or st: + while root: + st.append(root) + root = root.left + + root = st.pop() + list.append(root.val) + root = root.right + + return list diff --git a/python/stack/binary-tree-postorder-traversal.py b/python/stack/binary-tree-postorder-traversal.py new file mode 100644 index 0000000..9e30925 --- /dev/null +++ b/python/stack/binary-tree-postorder-traversal.py @@ -0,0 +1,13 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def postorderTraversal(self, root): + if root is None: + return [] + return self.postorderTraversal(root.left) +\ + self.postorderTraversal(root.right) + [root.val] diff --git a/python/stack/binary-tree-postorder-traversal[2].py b/python/stack/binary-tree-postorder-traversal[2].py new file mode 100644 index 0000000..68b499b --- /dev/null +++ b/python/stack/binary-tree-postorder-traversal[2].py @@ -0,0 +1,29 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def postorderTraversal(self, root): + st = [] + data = [] + pre = None + + if root: + st.append(root) + while st: + cur = st[len(st)-1] + if ((cur.left == None and cur.right == None) or \ + (pre and (pre == cur.left or pre == cur.right))): + data.append(cur.val) + st.pop() + pre = cur + else: + if cur.right: + st.append(cur.right) + if cur.left: + st.append(cur.left) + + return data diff --git a/python/stack/binary-tree-preorder-traversal.py b/python/stack/binary-tree-preorder-traversal.py new file mode 100644 index 0000000..f095d84 --- /dev/null +++ b/python/stack/binary-tree-preorder-traversal.py @@ -0,0 +1,24 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def preorderTraversal(self, root): + st = [] + data = [] + + if root: + st.append(root) + + while st: + cur = st.pop() + data.append(cur.val) + if cur.right: + st.append(cur.right) + if cur.left: + st.append(cur.left) + + return data diff --git a/python/stack/binary-tree-preorder-traversal[2].py b/python/stack/binary-tree-preorder-traversal[2].py new file mode 100644 index 0000000..7747140 --- /dev/null +++ b/python/stack/binary-tree-preorder-traversal[2].py @@ -0,0 +1,13 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def preorderTraversal(self, root): + if root: + return [root.val] + self.preorderTraversal(root.left) + \ + self.preorderTraversal(root.right) + return [] diff --git a/python/stack/binary-tree-zigzag-level-order-traversal.py b/python/stack/binary-tree-zigzag-level-order-traversal.py new file mode 100644 index 0000000..bd3833d --- /dev/null +++ b/python/stack/binary-tree-zigzag-level-order-traversal.py @@ -0,0 +1,40 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def zigzagLevelOrder(self, root): + cur_st = [] + next_st = [] + data = [] + left2right = 0 + + if root: + cur_st.append(root) + + while cur_st: + cur_data = [] + while cur_st: + node = cur_st.pop() + if left2right: + if node.right: + next_st.append(node.right) + if node.left: + next_st.append(node.left) + else: + if node.left: + next_st.append(node.left) + if node.right: + next_st.append(node.right) + + cur_data.append(node.val) + + data.append(cur_data) + left2right ^= 1 + cur_st = next_st + next_st = [] + + return data diff --git a/python/stack/evaluate-reverse-polish-notation.py b/python/stack/evaluate-reverse-polish-notation.py new file mode 100644 index 0000000..2d5d6d7 --- /dev/null +++ b/python/stack/evaluate-reverse-polish-notation.py @@ -0,0 +1,17 @@ +class Solution(object): + def evalRPN(self, tokens): + ops = {'+': operator.add, '-': operator.sub, '*': operator.mul, '/': operator.div} + st = [] + opstr = '+-*/' + for t in tokens: + if t in opstr: + right = st.pop() + left = st.pop() + if(t == '/'): + st.append(int(ops[t](left * 1.0,right))) + else: + st.append(ops[t](left,right)) + else: + st.append(int(t)) + + return st[0]; diff --git a/python/stack/flatten-nested-list-iterator.py b/python/stack/flatten-nested-list-iterator.py new file mode 100644 index 0000000..a400286 --- /dev/null +++ b/python/stack/flatten-nested-list-iterator.py @@ -0,0 +1,60 @@ +# """ +# This is the interface that allows for creating nested lists. +# You should not implement it, or speculate about its implementation +# """ +#class NestedInteger(object): +# def isInteger(self): +# """ +# @return True if this NestedInteger holds a single integer, rather than a nested list. +# :rtype bool +# """ +# +# def getInteger(self): +# """ +# @return the single integer that this NestedInteger holds, if it holds a single integer +# Return None if this NestedInteger holds a nested list +# :rtype int +# """ +# +# def getList(self): +# """ +# @return the nested list that this NestedInteger holds, if it holds a nested list +# Return None if this NestedInteger holds a single integer +# :rtype List[NestedInteger] +# """ + +class NestedIterator(object): + + def __init__(self, nestedList): + self.st = [] + + i = len(nestedList) - 1 + while i >= 0: + self.st.append(nestedList[i]) + i -= 1 + + + def next(self): + nested = self.st[-1] + self.st.pop() + return nested.getInteger() + + + def hasNext(self): + while self.st: + nested = self.st[-1] + if nested.isInteger(): + return True + self.st.pop() + nestedList = nested.getList() + i = len(nestedList) - 1 + while i >= 0: + self.st.append(nestedList[i]) + i -= 1 + + return False + + +# Your NestedIterator object will be instantiated and called as such: +# i, v = NestedIterator(nestedList), [] +# while i.hasNext(): v.append(i.next()) diff --git a/python/stack/implement-queue-using-stacks.py b/python/stack/implement-queue-using-stacks.py new file mode 100644 index 0000000..420a73a --- /dev/null +++ b/python/stack/implement-queue-using-stacks.py @@ -0,0 +1,24 @@ +class Queue(object): + def __init__(self): + self.st1 = [] + self.st2 = [] + + def push(self, x): + self.st1.append(x) + + def pop(self): + if len(self.st2) == 0: + while len(self.st1) != 0: + self.st2.append(self.st1.pop()) + + return self.st2.pop() + + def peek(self): + if len(self.st2) == 0: + while len(self.st1) != 0: + self.st2.append(self.st1.pop()) + + return self.st2[-1] + + def empty(self): + return len(self.st1) == 0 and len(self.st2) == 0 diff --git a/python/stack/implement-stack-using-queues.py b/python/stack/implement-stack-using-queues.py new file mode 100644 index 0000000..2da8947 --- /dev/null +++ b/python/stack/implement-stack-using-queues.py @@ -0,0 +1,49 @@ +class Stack(object): + def __init__(self): + """ + initialize your data structure here. + """ + self.q1 = [] + self.q2 = [] + + + def push(self, x): + """ + :type x: int + :rtype: nothing + """ + if self.q1: + self.q1.append(x) + while self.q2: + self.q1.append(self.q2[0]) + self.q2.pop() + else: + self.q2.append(x) + while self.q1: + self.q2.append(self.q1[0]) + self.q1.pop() + + def pop(self): + """ + :rtype: nothing + """ + if self.q1: + self.q1.pop() + else: + self.q2.pop() + + + def top(self): + """ + :rtype: int + """ + if self.q1: + return self.q1[-1] + else: + return self.q2[-1] + + def empty(self): + """ + :rtype: bool + """ + return not self.q1 and not self.q2 diff --git a/python/stack/largest-rectangle-in-histogram.py b/python/stack/largest-rectangle-in-histogram.py new file mode 100644 index 0000000..46314e7 --- /dev/null +++ b/python/stack/largest-rectangle-in-histogram.py @@ -0,0 +1,22 @@ +class Solution(object): + def largestRectangleArea(self, heights): + max_area = 0 + st = [] + heights.append(0) + hlen = len(heights) + i = 0; + + while i < hlen: + while st and heights[i] <= heights[st[-1]]: + h = heights[st[-1]] + st.pop() + w = i + if st: + w = i - st[-1] - 1 + if h * w > max_area: + max_area = h * w + + st.append(i) + i += 1 + + return max_area; diff --git a/python/stack/maximal-rectangle.py b/python/stack/maximal-rectangle.py new file mode 100644 index 0000000..4f94278 --- /dev/null +++ b/python/stack/maximal-rectangle.py @@ -0,0 +1,38 @@ +class Solution(object): + def maxArea(self, heights): + area = 0 + st = [] + + for i in range(len(heights)): + while st and heights[i] <= heights[st[-1]]: + h = heights[st[-1]] + st.pop() + w = i if not st else (i - st[-1] - 1) + + if h * w > area: + area = h * w + + st.append(i) + + return area + + def maximalRectangle(self, matrix): + if not matrix: + return 0 + + heights = [0] * (len(matrix[0])+1) + max_area = 0; + + for row in matrix: + for j in range(len(row)): + if row[j] == '1': + heights[j] += 1 + else: + heights[j] = 0; + + area = self.maxArea(heights) + if area > max_area: + max_area = area + + + return max_area diff --git a/python/stack/min-stack.py b/python/stack/min-stack.py new file mode 100644 index 0000000..1a5ee88 --- /dev/null +++ b/python/stack/min-stack.py @@ -0,0 +1,34 @@ +class MinStack(object): + + def __init__(self): + self.st = [] + self.min_st = [] + + + def push(self, x): + self.st.append(x) + if len(self.min_st) == 0 or x <= self.min_st[-1]: + self.min_st.append(x) + + + def pop(self): + if self.st[-1] <= self.min_st[-1]: + self.min_st.pop() + return self.st.pop() + + + def top(self): + return self.st[-1] + + + def getMin(self): + return self.min_st[-1] + + + +# Your MinStack object will be instantiated and called as such: +# obj = MinStack() +# obj.push(x) +# obj.pop() +# param_3 = obj.top() +# param_4 = obj.getMin() diff --git a/python/stack/remove-duplicate-letters.py b/python/stack/remove-duplicate-letters.py new file mode 100644 index 0000000..c4aeeb0 --- /dev/null +++ b/python/stack/remove-duplicate-letters.py @@ -0,0 +1,22 @@ +class Solution(object): + def removeDuplicateLetters(self, s): + h = {} + st = [] + + for ch in s: + if ch in h.keys(): + h[ch] += 1 + else: + h[ch] = 1 + + for ch in s: + h[ch] -= 1 + if ch in st: + continue + + while st and ch < st[-1] and h[st[-1]] > 0: + st.pop() + + st.append(ch) + + return ''.join(st) diff --git a/python/stack/remove-duplicate-letters[2].py b/python/stack/remove-duplicate-letters[2].py new file mode 100644 index 0000000..f3c5427 --- /dev/null +++ b/python/stack/remove-duplicate-letters[2].py @@ -0,0 +1,14 @@ +class Solution(object): + def removeDuplicateLetters(self, s): + count = collections.Counter(s) + st = [] + + for ch in s: + count[ch] -= 1 + if ch in st: + continue + while st and ch < st[-1] and count[st[-1]] > 0: + st.pop() + st.append(ch) + + return ''.join(st) diff --git a/python/stack/simplify-path.py b/python/stack/simplify-path.py new file mode 100644 index 0000000..5d1194b --- /dev/null +++ b/python/stack/simplify-path.py @@ -0,0 +1,34 @@ +class Solution(object): + def simplifyPath(self, path): + st = [] + i = 0 + j = 0 + plen = len(path) + while j < plen: + while j < plen and path[j] == '/': + j += 1 + if j == plen: + break + + i = j + while j < plen and path[j] != '/': + j += 1 + + str = path[i:j] + if str == '.': + continue + + if str == '..': + if st: + st.pop() + else: + st.append(str) + + if st == []: + return '/' + + ret = '' + for str in st: + ret += '/' + str + + return ret diff --git a/python/stack/simplify-path[2].py b/python/stack/simplify-path[2].py new file mode 100644 index 0000000..bf0aaae --- /dev/null +++ b/python/stack/simplify-path[2].py @@ -0,0 +1,19 @@ +class Solution(object): + def simplifyPath(self, path): + st = [] + str_list = path.split('/') + for str in str_list: + if len(str) > 0: + if str == '..': + if st: + st.pop() + elif str != '.': + st.append(str) + + if st == []: + return '/' + ret = '' + for str in st: + ret += '/' + str + + return ret diff --git a/python/stack/trapping-rain-water.py b/python/stack/trapping-rain-water.py new file mode 100644 index 0000000..1a6242f --- /dev/null +++ b/python/stack/trapping-rain-water.py @@ -0,0 +1,33 @@ +class Solution(object): + def trap(self, height): + if not height: + return 0 + + max_index = 0 + max_height = 0 + + for i in range(len(height)): + if height[i] > max_height: + max_index = i + max_height = height[i] + + max_height = 0 + i = 0 + ret = 0 + while i < max_index: + if max_height > height[i]: + ret += (max_height - height[i]) + else: + max_height = height[i] + i += 1 + + max_height = 0 + i = len(height) - 1 + while i > max_index: + if max_height > height[i]: + ret += (max_height - height[i]) + else: + max_height = height[i] + i -= 1 + + return ret diff --git a/python/stack/valid-parentheses.py b/python/stack/valid-parentheses.py new file mode 100644 index 0000000..807e0d1 --- /dev/null +++ b/python/stack/valid-parentheses.py @@ -0,0 +1,16 @@ +class Solution(object): + def isValid(self, s): + st = [] + left_s = '({[' + for c in s: + if c in left_s: + st.append(c) + elif st and \ + ((c == ')' and st[-1] == '(') \ + or (c == '}' and st[-1] == '{') \ + or (c == ']' and st[-1] == '[')): + st.pop(); + else: + return False + + return not st diff --git a/python/stack/verify-preorder-serialization-of-a-binary-tree.py b/python/stack/verify-preorder-serialization-of-a-binary-tree.py new file mode 100644 index 0000000..f9b975a --- /dev/null +++ b/python/stack/verify-preorder-serialization-of-a-binary-tree.py @@ -0,0 +1,23 @@ +class Solution(object): + def isValidSerialization(self, preorder): + count = 0 + s = preorder.split(',') + slen = len(s) + if s[0] != '#': + count += 1 + + i = 1; + while count: + if i == slen or i + 1 == slen: + return False + count -= 1 + if s[i] != '#': + count += 1 + if s[i+1] != '#': + count += 1 + i += 2 + + if i < slen: + return False + + return True diff --git a/python/string/add-binary.py b/python/string/add-binary.py new file mode 100644 index 0000000..1acdebc --- /dev/null +++ b/python/string/add-binary.py @@ -0,0 +1,24 @@ +class Solution(object): + def addBinary(self, a, b): + """ + :type a: str + :type b: str + :rtype: str + """ + indexa = len(a) - 1 + indexb = len(b) - 1 + res = '' + carry = 0 + while indexa >= 0 or indexb >= 0: + x = int(a[indexa]) if indexa >= 0 else 0 + y = int(b[indexb]) if indexb >= 0 else 0 + value = x + y + carry + carry = value // 2 + value = value % 2 + res = str(value) + res + indexa, indexb = indexa - 1, indexb - 1 + + if carry == 1: + res = '1' + res + + return res diff --git a/python/tree/balanced-binary-tree.py b/python/tree/balanced-binary-tree.py new file mode 100644 index 0000000..d0a728c --- /dev/null +++ b/python/tree/balanced-binary-tree.py @@ -0,0 +1,24 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def depth(self,root): + if not root: + return 0 + left = self.depth(root.left) + right = self.depth(root.right) + if left == -1 or right == -1 or \ + abs(left-right) > 1: + return -1 + return max(left,right) + 1 + + def isBalanced(self, root): + """ + :type root: TreeNode + :rtype: bool + """ + return self.depth(root) != -1 diff --git a/python/tree/binary-search-tree-iterator.py b/python/tree/binary-search-tree-iterator.py new file mode 100644 index 0000000..a59a134 --- /dev/null +++ b/python/tree/binary-search-tree-iterator.py @@ -0,0 +1,27 @@ +# Definition for a binary tree node +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class BSTIterator(object): + def __init__(self, root): + self.st = [] + self.cur = root + + def hasNext(self): + return self.st or self.cur + + def next(self): + while self.cur: + self.st.append(self.cur) + self.cur = self.cur.left + + tmp = self.st.pop() + self.cur = tmp.right + return tmp.val + +# Your BSTIterator will be called like this: +# i, v = BSTIterator(root), [] +# while i.hasNext(): v.append(i.next()) diff --git a/python/tree/binary-tree-inorder-traversal.py b/python/tree/binary-tree-inorder-traversal.py new file mode 100644 index 0000000..686e383 --- /dev/null +++ b/python/tree/binary-tree-inorder-traversal.py @@ -0,0 +1,20 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def inorderTraversal(self, root): + arr = [] + st = [] + cur = root + while cur or st: + while cur: + st.append(cur) + cur = cur.left + arr.append(st[-1].val) + cur = st.pop().right + + return arr diff --git a/python/tree/binary-tree-level-order-traversal-ii.py b/python/tree/binary-tree-level-order-traversal-ii.py new file mode 100644 index 0000000..d44a292 --- /dev/null +++ b/python/tree/binary-tree-level-order-traversal-ii.py @@ -0,0 +1,27 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def levelOrderBottom(self, root): + if not root: + return [] + + ret = [] + q = [root] + while q: + new_q = [] + li = [] + for node in q: + li.append(node.val) + if node.left: + new_q.append(node.left) + if node.right: + new_q.append(node.right) + q = new_q; + ret.insert(0,li) + + return ret diff --git a/python/tree/binary-tree-level-order-traversal-ii[1].py b/python/tree/binary-tree-level-order-traversal-ii[1].py new file mode 100644 index 0000000..511a935 --- /dev/null +++ b/python/tree/binary-tree-level-order-traversal-ii[1].py @@ -0,0 +1,31 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def levelOrderBottom(self, root): + arr = [] + cur_q = [] + next_q = [] + if root: + cur_q.append(root) + + while cur_q: + ele = [] + for node in cur_q: + ele.append(node.val) + if node.left: + next_q.append(node.left) + if node.right: + next_q.append(node.right) + + cur_q = next_q + next_q = [] + arr.append(ele) + + arr.reverse() + + return arr diff --git a/python/tree/binary-tree-level-order-traversal.py b/python/tree/binary-tree-level-order-traversal.py new file mode 100644 index 0000000..20f8985 --- /dev/null +++ b/python/tree/binary-tree-level-order-traversal.py @@ -0,0 +1,28 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def levelOrder(self, root): + self.ret = [] + + if root is None: + return self.ret + + q = [root] + while q: + tmp = [] + new_q = [] + for node in q: + tmp.append(node.val) + if node.left: + new_q.append(node.left) + if node.right: + new_q.append(node.right) + q = new_q + self.ret.append(tmp) + + return self.ret diff --git a/python/tree/binary-tree-maximum-path-sum.py b/python/tree/binary-tree-maximum-path-sum.py new file mode 100644 index 0000000..ec5d741 --- /dev/null +++ b/python/tree/binary-tree-maximum-path-sum.py @@ -0,0 +1,23 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def max_sum(self,root): + if not root: + return (0,-sys.maxint) + + left = self.max_sum(root.left) + right = self.max_sum(root.right) + + retval = max(left[0]+root.val, right[0]+root.val,0) + maxval = max(left[1],right[1],root.val+left[0]+right[0]) + + return (retval,maxval) + + def maxPathSum(self, root): + _, nodeval = self.max_sum(root) + return nodeval diff --git a/python/tree/binary-tree-paths.py b/python/tree/binary-tree-paths.py new file mode 100644 index 0000000..3d391b5 --- /dev/null +++ b/python/tree/binary-tree-paths.py @@ -0,0 +1,31 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution: + # @param {TreeNode} root + # @return {string[]} + def __init__(self): + self.path = [] + + def rescuive(self,root,cur_path): + if not root: + return + + cur_path += str(root.val) + if not root.left and not root.right: + self.path.append(cur_path) + return + + cur_path += '->' + if root.left: + self.rescuive(root.left,cur_path) + if root.right: + self.rescuive(root.right,cur_path) + + def binaryTreePaths(self, root): + self.rescuive(root,'') + return self.path diff --git a/python/tree/binary-tree-postorder-traversal.py b/python/tree/binary-tree-postorder-traversal.py new file mode 100644 index 0000000..5306412 --- /dev/null +++ b/python/tree/binary-tree-postorder-traversal.py @@ -0,0 +1,20 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def __init__(self): + self.result = [] + + def postorderTraversal(self, root): + if not root: + return self.result + + self.postorderTraversal(root.left) + self.postorderTraversal(root.right) + self.result.append(root.val) + + return self.result diff --git a/python/tree/binary-tree-postorder-traversal[1].py b/python/tree/binary-tree-postorder-traversal[1].py new file mode 100644 index 0000000..615967f --- /dev/null +++ b/python/tree/binary-tree-postorder-traversal[1].py @@ -0,0 +1,30 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def postorderTraversal(self, root): + st = [] + result = [] + pre = None + + if root: + st.append(root) + + while st: + cur = st[-1] + if (cur.left == None and cur.right == None) or \ + (pre and (pre == cur.left or pre == cur.right)): + result.append(cur.val) + st.pop() + pre = cur + else: + if cur.right: + st.append(cur.right) + if cur.left: + st.append(cur.left) + + return result diff --git a/python/tree/binary-tree-preorder-traversal.py b/python/tree/binary-tree-preorder-traversal.py new file mode 100644 index 0000000..2998eef --- /dev/null +++ b/python/tree/binary-tree-preorder-traversal.py @@ -0,0 +1,19 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def __init__(self): + self.arr = [] + + def preorderTraversal(self, root): + if root is None: + return self.arr + + self.arr.append(root.val) + self.preorderTraversal(root.left) + self.preorderTraversal(root.right) + return self.arr diff --git a/python/tree/binary-tree-preorder-traversal[1].py b/python/tree/binary-tree-preorder-traversal[1].py new file mode 100644 index 0000000..222fc39 --- /dev/null +++ b/python/tree/binary-tree-preorder-traversal[1].py @@ -0,0 +1,23 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def preorderTraversal(self, root): + st = [] + arr = [] + if root: + st.append(root) + + while st: + node = st.pop() + arr.append(node.val) + if node.right: + st.append(node.right) + if node.left: + st.append(node.left) + + return arr diff --git a/python/tree/binary-tree-right-side-view.py b/python/tree/binary-tree-right-side-view.py new file mode 100644 index 0000000..7b4c2d0 --- /dev/null +++ b/python/tree/binary-tree-right-side-view.py @@ -0,0 +1,26 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def rightSideView(self, root): + result = [] + + arr = [] + if root: + arr.append(root) + + while arr: + result.append(arr[-1].val) + next_arr = [] + for node in arr: + if node.left: + next_arr.append(node.left) + if node.right: + next_arr.append(node.right) + arr = next_arr + + return result diff --git a/python/tree/binary-tree-right-side-view[1].py b/python/tree/binary-tree-right-side-view[1].py new file mode 100644 index 0000000..15cb922 --- /dev/null +++ b/python/tree/binary-tree-right-side-view[1].py @@ -0,0 +1,24 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def __init__(self): + self.result = [] + + def dfs(self,root,dp): + if not root: + return + if len(self.result) <= dp: + self.result.append(root.val) + else: + self.result[dp] = root.val + self.dfs(root.left,dp+1) + self.dfs(root.right,dp+1) + + def rightSideView(self, root): + self.dfs(root,0) + return self.result diff --git a/python/tree/binary-tree-zigzag-level-order-traversal.py b/python/tree/binary-tree-zigzag-level-order-traversal.py new file mode 100644 index 0000000..f329678 --- /dev/null +++ b/python/tree/binary-tree-zigzag-level-order-traversal.py @@ -0,0 +1,39 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def zigzagLevelOrder(self, root): + left_first = 1 + st = [] + next_st = [] + arr = [] + + if root: + st.append(root) + + while st: + ele = [] + while st: + node = st.pop() + ele.append(node.val) + if left_first: + if node.left: + next_st.append(node.left) + if node.right: + next_st.append(node.right) + else: + if node.right: + next_st.append(node.right) + if node.left: + next_st.append(node.left) + + left_first ^= 1 + arr.append(ele) + st = next_st + next_st = [] + + return arr diff --git a/python/tree/construct-binary-tree-from-inorder-and-postorder-traversal.py b/python/tree/construct-binary-tree-from-inorder-and-postorder-traversal.py new file mode 100644 index 0000000..a7334c6 --- /dev/null +++ b/python/tree/construct-binary-tree-from-inorder-and-postorder-traversal.py @@ -0,0 +1,24 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def scan(self,in_pos, post_pos, count): + if count <= 0: + return None + + node = TreeNode(self.postorder[post_pos + count-1]) + idx = self.inorder.index(self.postorder[post_pos + count-1]) + + node.left = self.scan(in_pos,post_pos,idx - in_pos) + node.right = self.scan(idx+1,post_pos + idx - in_pos,count - 1 -idx + in_pos) + return node + + def buildTree(self, inorder, postorder): + self.inorder = inorder + self.postorder = postorder + + return self.scan(0,0,len(self.inorder)) diff --git a/python/tree/construct-binary-tree-from-preorder-and-inorder-traversal.py b/python/tree/construct-binary-tree-from-preorder-and-inorder-traversal.py new file mode 100644 index 0000000..824e7c6 --- /dev/null +++ b/python/tree/construct-binary-tree-from-preorder-and-inorder-traversal.py @@ -0,0 +1,25 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def rescan(self, left_pre, left_in, count): + if count <= 0: + return None + + node = TreeNode(self.preorder[left_pre]) + node_pos = self.inorder.index(self.preorder[left_pre]) + + node.left = self.rescan(left_pre + 1, left_in, node_pos - left_in) + node.right = self.rescan(left_pre + 1 + (node_pos - left_in), \ + node_pos + 1, count - 1 - (node_pos - left_in)) + return node + + def buildTree(self, preorder, inorder): + self.preorder = preorder + self.inorder = inorder + + return self.rescan(0, 0, len(inorder)) diff --git a/python/tree/convert-sorted-array-to-binary-search-tree.py b/python/tree/convert-sorted-array-to-binary-search-tree.py new file mode 100644 index 0000000..dae80b3 --- /dev/null +++ b/python/tree/convert-sorted-array-to-binary-search-tree.py @@ -0,0 +1,22 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def bcreate(self,start,end): + if end < start: + return None + + mid = (start + end) / 2 + node = TreeNode(self.nums[mid]) + node.left = self.bcreate(start,mid -1) + node.right = self.bcreate(mid + 1, end) + + return node + + def sortedArrayToBST(self, nums): + self.nums = nums + return self.bcreate(0,len(self.nums) - 1) diff --git a/python/tree/count-complete-tree-nodes.py b/python/tree/count-complete-tree-nodes.py new file mode 100644 index 0000000..1b48900 --- /dev/null +++ b/python/tree/count-complete-tree-nodes.py @@ -0,0 +1,28 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def countNodes(self, root): + if not root: + return 0 + + lh = 0 + tmp = root + while tmp: + lh += 1 + tmp = tmp.left + + rh = 0 + tmp = root + while tmp: + rh += 1 + tmp = tmp.right + + if lh == rh: + return (1 << lh) - 1 + + return 1 + self.countNodes(root.left) + self.countNodes(root.right) diff --git a/python/tree/flatten-binary-tree-to-linked-list.py b/python/tree/flatten-binary-tree-to-linked-list.py new file mode 100644 index 0000000..a1d551c --- /dev/null +++ b/python/tree/flatten-binary-tree-to-linked-list.py @@ -0,0 +1,25 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def flatten(self, root): + if not root: + return + + left = root.left + right = root.right + + root.left = None + root.right = left + + self.flatten(left) + self.flatten(right) + + while root.right: + root = root.right + + root.right = right diff --git a/python/tree/flatten-binary-tree-to-linked-list[2].py b/python/tree/flatten-binary-tree-to-linked-list[2].py new file mode 100644 index 0000000..9d8e8b5 --- /dev/null +++ b/python/tree/flatten-binary-tree-to-linked-list[2].py @@ -0,0 +1,23 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def flatten(self, root): + if not root: + return + + while root: + if root.left: + node = root.left + while node.right: + node = node.right + + node.right = root.right + root.right = root.left + root.left = None + + root = root.right diff --git a/python/tree/house-robber-iii.py b/python/tree/house-robber-iii.py new file mode 100644 index 0000000..22292e5 --- /dev/null +++ b/python/tree/house-robber-iii.py @@ -0,0 +1,24 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def dfs(self, root): + if root is None: + return 0,0 + + left,not_left = self.dfs(root.left) + right, not_right = self.dfs(root.right) + + cur = not_left + not_right + root.val + not_cur = max(left,not_left) + max(right,not_right) + + return cur, not_cur + + def rob(self, root): + cur,not_cur = self.dfs(root) + + return max(cur,not_cur) diff --git a/python/tree/invert-binary-tree.py b/python/tree/invert-binary-tree.py new file mode 100644 index 0000000..d01b531 --- /dev/null +++ b/python/tree/invert-binary-tree.py @@ -0,0 +1,17 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def invertTree(self, root): + if not root: + return None + + node = self.invertTree(root.left) + root.left = self.invertTree(root.right) + root.right = node + + return root diff --git a/python/tree/kth-smallest-element-in-a-bst.py b/python/tree/kth-smallest-element-in-a-bst.py new file mode 100644 index 0000000..e0b2abf --- /dev/null +++ b/python/tree/kth-smallest-element-in-a-bst.py @@ -0,0 +1,24 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def getKth(self,root,k): + if not root: + return 0,0 + + val,left = self.getKth(root.left,k) + if left + 1 > k: + return val,left + elif left + 1 == k: + return root.val,k + + val,right = self.getKth(root.right,k - left - 1) + return val, left + right + 1 + + def kthSmallest(self, root, k): + val, count = self.getKth(root,k) + return val diff --git a/python/tree/lowest-common-ancestor-of-a-binary-search-tree.py b/python/tree/lowest-common-ancestor-of-a-binary-search-tree.py new file mode 100644 index 0000000..0ed5242 --- /dev/null +++ b/python/tree/lowest-common-ancestor-of-a-binary-search-tree.py @@ -0,0 +1,19 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def lowestCommonAncestor(self, root, p, q): + if not root or root == p or root == q: + return root + + left = self.lowestCommonAncestor(root.left,p,q) + right = self.lowestCommonAncestor(root.right,p,q) + + if left and right: + return root + + return left if left else right diff --git a/python/tree/lowest-common-ancestor-of-a-binary-search-tree[1].py b/python/tree/lowest-common-ancestor-of-a-binary-search-tree[1].py new file mode 100644 index 0000000..19dc476 --- /dev/null +++ b/python/tree/lowest-common-ancestor-of-a-binary-search-tree[1].py @@ -0,0 +1,15 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def lowestCommonAncestor(self, root, p, q): + if min(p.val, q.val) > root.val: + return self.lowestCommonAncestor(root.right, p, q) + elif max(p.val, q.val) < root.val: + return self.lowestCommonAncestor(root.left, p, q) + else: + return root diff --git a/python/tree/lowest-common-ancestor-of-a-binary-search-tree[2].py b/python/tree/lowest-common-ancestor-of-a-binary-search-tree[2].py new file mode 100644 index 0000000..e129b5d --- /dev/null +++ b/python/tree/lowest-common-ancestor-of-a-binary-search-tree[2].py @@ -0,0 +1,47 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def lca(self,root,node,flag): + if root is None or self.find: + return + + self.rlist.append(root) + if root == node: + self.find = 1 + if flag == 0: + self.plist = self.rlist + else: + self.qlist = self.rlist + + return + + self.lca(root.left,node,flag) + if self.find: + return + + self.lca(root.right,node,flag) + if self.find: + return + + self.rlist.pop() + + def lowestCommonAncestor(self, root, p, q): + self.rlist = [] + self.find = 0 + self.lca(root,p,0) + + self.rlist = [] + self.find = 0 + self.lca(root,q,1) + + mlen = min(len(self.plist), len(self.qlist)) - 1 + + while self.plist[mlen] != self.qlist[mlen]: + mlen -= 1 + + return self.plist[mlen] diff --git a/python/tree/maximum-depth-of-binary-tree.py b/python/tree/maximum-depth-of-binary-tree.py new file mode 100644 index 0000000..14683b6 --- /dev/null +++ b/python/tree/maximum-depth-of-binary-tree.py @@ -0,0 +1,24 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def depth(self,root,cur_h): + if root is None: + return + + cur_h += 1 + if cur_h > self.max_h: + self.max_h = cur_h + + self.depth(root.left,cur_h) + self.depth(root.right,cur_h) + + def maxDepth(self, root): + self.max_h = 0 + self.depth(root,0) + + return self.max_h diff --git a/python/tree/maximum-depth-of-binary-tree[1].py b/python/tree/maximum-depth-of-binary-tree[1].py new file mode 100644 index 0000000..2a4b451 --- /dev/null +++ b/python/tree/maximum-depth-of-binary-tree[1].py @@ -0,0 +1,16 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def maxDepth(self, root): + if root is None: + return 0 + + left = self.maxDepth(root.left) + right = self.maxDepth(root.right) + + return max(left,right) + 1 diff --git a/python/tree/minimum-depth-of-binary-tree.py b/python/tree/minimum-depth-of-binary-tree.py new file mode 100644 index 0000000..f6df296 --- /dev/null +++ b/python/tree/minimum-depth-of-binary-tree.py @@ -0,0 +1,23 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def minDepth(self, root): + if root is None: + return 0 + + left = self.minDepth(root.left) + right = self.minDepth(root.right) + + if left == 0 and right == 0: + return 1 + elif left == 0: + return right + 1 + elif right == 0: + return left + 1 + else: + return min(left, right) + 1 diff --git a/python/tree/path-sum-ii.py b/python/tree/path-sum-ii.py new file mode 100644 index 0000000..8421668 --- /dev/null +++ b/python/tree/path-sum-ii.py @@ -0,0 +1,26 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def dfs(self,root,sum,cur_arr): + if root.left is None and root.right is None: + if root.val == sum: + self.result.append(cur_arr) + else: + if root.left: + self.dfs(root.left, sum - root.val,cur_arr + [root.left.val]) + if root.right: + self.dfs(root.right, sum - root.val,cur_arr + [root.right.val]) + + + def pathSum(self, root, sum): + self.result = [] + + if root: + self.dfs(root,sum,[root.val]) + + return self.result diff --git a/python/tree/path-sum.py b/python/tree/path-sum.py new file mode 100644 index 0000000..352447c --- /dev/null +++ b/python/tree/path-sum.py @@ -0,0 +1,18 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def hasPathSum(self, root, sum): + if root is None: + return False + + if root.left is None and root.right is None: + return root.val == sum + + bleft = self.hasPathSum(root.left, sum - root.val) + + return bleft if bleft else self.hasPathSum(root.right, sum - root.val) diff --git a/python/tree/populating-next-right-pointers-in-each-node-ii.py b/python/tree/populating-next-right-pointers-in-each-node-ii.py new file mode 100644 index 0000000..bfc4423 --- /dev/null +++ b/python/tree/populating-next-right-pointers-in-each-node-ii.py @@ -0,0 +1,38 @@ +# Definition for binary tree with next pointer. +# class TreeLinkNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None +# self.next = None + +class Solution(object): + def get_next(self, root): + while root and root.left == None and root.right == None: + root = root.next + + return root + + def get_next_child(self,root): + parent = self.get_next(root) + if parent: + return parent.left if parent.left else parent.right + + return None + + def connect(self, root): + parent = self.get_next(root) + next = self.get_next_child(root) + + while parent and next: + while parent: + if parent.left: + parent.left.next = parent.right if parent.right \ + else self.get_next_child(parent.next) + if parent.right: + parent.right.next = self.get_next_child(parent.next) + + parent = self.get_next(parent.next) + + parent = self.get_next(next) + next = self.get_next_child(next) diff --git a/python/tree/populating-next-right-pointers-in-each-node-ii[1].py b/python/tree/populating-next-right-pointers-in-each-node-ii[1].py new file mode 100644 index 0000000..0d45d80 --- /dev/null +++ b/python/tree/populating-next-right-pointers-in-each-node-ii[1].py @@ -0,0 +1,30 @@ +# Definition for binary tree with next pointer. +# class TreeLinkNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None +# self.next = None + +class Solution(object): + def connect(self, root): + if root is None: + return + + parent = root + while parent: + first, last = None, None + while parent: + for node in [parent.left, parent.right]: + if node is None: + continue + if first is None: + first = node + last = node + continue + last.next = node + last = node + + parent = parent.next + + parent = first diff --git a/python/tree/populating-next-right-pointers-in-each-node.py b/python/tree/populating-next-right-pointers-in-each-node.py new file mode 100644 index 0000000..f26d2c4 --- /dev/null +++ b/python/tree/populating-next-right-pointers-in-each-node.py @@ -0,0 +1,22 @@ +# Definition for binary tree with next pointer. +# class TreeLinkNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None +# self.next = None + +class Solution(object): + def connect(self, root): + if root is None: + return + + if root.left: + root.left.next = root.right + if root.next: + root.right.next = root.next.left + else: + root.right.next = None + + self.connect(root.left) + self.connect(root.right) diff --git a/python/tree/populating-next-right-pointers-in-each-node[1].py b/python/tree/populating-next-right-pointers-in-each-node[1].py new file mode 100644 index 0000000..944cf99 --- /dev/null +++ b/python/tree/populating-next-right-pointers-in-each-node[1].py @@ -0,0 +1,29 @@ +# Definition for binary tree with next pointer. +# class TreeLinkNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None +# self.next = None + +class Solution(object): + def connect(self, root): + if root is None: + return + + parent = root + next = root.left + while parent and next: + pre = None + while parent: + if pre is None: + pre = parent.left + else: + pre.next = parent.left + pre = pre.next + pre.next = parent.right + pre = pre.next + parent = parent.next + + parent = next + next = next.left diff --git a/python/tree/recover-binary-search-tree.py b/python/tree/recover-binary-search-tree.py new file mode 100644 index 0000000..d827c94 --- /dev/null +++ b/python/tree/recover-binary-search-tree.py @@ -0,0 +1,31 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def inOrder(self,root): + if root is None: + return + + self.inOrder(root.left) + + if self.prev and self.prev.val > root.val: + self.t2 = root + if self.t1 is None: + self.t1 = self.prev + + self.prev = root; + + self.inOrder(root.right) + + def recoverTree(self, root): + self.prev = None + self.t1 = None + self.t2 = None + + self.inOrder(root) + + self.t1.val, self.t2.val = self.t2.val,self.t1.val diff --git a/python/tree/same-tree.py b/python/tree/same-tree.py new file mode 100644 index 0000000..c7aea9c --- /dev/null +++ b/python/tree/same-tree.py @@ -0,0 +1,17 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def isSameTree(self, p, q): + if p and q: + if p.val != q.val: + return False + + return self.isSameTree(p.left,q.left) and \ + self.isSameTree(p.right,q.right) + + return p is None and q is None diff --git a/python/tree/serialize-and-deserialize-binary-tree.py b/python/tree/serialize-and-deserialize-binary-tree.py new file mode 100644 index 0000000..cf30369 --- /dev/null +++ b/python/tree/serialize-and-deserialize-binary-tree.py @@ -0,0 +1,55 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Codec: + def serialize(self, root): + queue = collections.deque() + data = '' + queue.append(root) + while queue: + node = queue.popleft() + if node is None: + data += 'null,' + else: + data += str(node.val) + ',' + queue.append(node.left) + queue.append(node.right) + + + return '[' + data[0:-1] + ']' + + def deserialize(self, data): + if data == '[]': + return None + + + list_data = data[1:-1].split(',') + nums = [0] * len(list_data) + arr = [] + for i in range(0,len(list_data)): + if i > 0: + nums[i] = nums[i-1] + if list_data[i] == 'null': + arr.append(None) + nums[i] += 1 + else: + arr.append(TreeNode(int(list_data[i]))) + + for i in range(0,len(arr)): + if arr[i] is None: + continue + if 2*(i-nums[i]) + 1 < len(arr): + arr[i].left = arr[2*(i-nums[i]) + 1] + if 2*(i-nums[i]) + 2 < len(arr): + arr[i].right = arr[2*(i-nums[i]) + 2] + + return arr[0] + + +# Your Codec object will be instantiated and called as such: +# codec = Codec() +# codec.deserialize(codec.serialize(root)) diff --git a/python/tree/sum-root-to-leaf-numbers.py b/python/tree/sum-root-to-leaf-numbers.py new file mode 100644 index 0000000..64b78c1 --- /dev/null +++ b/python/tree/sum-root-to-leaf-numbers.py @@ -0,0 +1,20 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def sum(self, root, cur_val): + if root is None: + return 0 + + val = cur_val * 10 + root.val + if root.left is None and root.right is None: + return val + + return self.sum(root.left,val) + self.sum(root.right,val) + + def sumNumbers(self, root): + return self.sum(root,0) diff --git a/python/tree/symmetric-tree.py b/python/tree/symmetric-tree.py new file mode 100644 index 0000000..b3ec02c --- /dev/null +++ b/python/tree/symmetric-tree.py @@ -0,0 +1,23 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def isSame(self, left, right): + if left and right: + if left.val != right.val: + return False + + return self.isSame(left.left,right.right) and \ + self.isSame(left.right,right.left) + + return left is None and right is None + + def isSymmetric(self, root): + if root is None: + return True + + return self.isSame(root.left,root.right) diff --git a/python/tree/unique-binary-search-trees-ii.py b/python/tree/unique-binary-search-trees-ii.py new file mode 100644 index 0000000..ffa3aad --- /dev/null +++ b/python/tree/unique-binary-search-trees-ii.py @@ -0,0 +1,28 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def generateTrees(self, n): + if n == 0: + return [] + return self.dfs(1,n) + + def dfs(self,start,end): + if start > end: + return [None] + ret = [] + for val in range(start, end+1): + left = self.dfs(start, val-1) + right = self.dfs(val+1,end) + for i in left: + for j in right: + root = TreeNode(val) + root.left = i + root.right = j + ret.append(root) + + return ret diff --git a/python/tree/unique-binary-search-trees.py b/python/tree/unique-binary-search-trees.py new file mode 100644 index 0000000..db9283d --- /dev/null +++ b/python/tree/unique-binary-search-trees.py @@ -0,0 +1,9 @@ +class Solution(object): + def numTrees(self, n): + num = [0] * (n+1) + num[0] = num[1] = 1 + for i in range(2,n+1): + for j in range(i): + num[i] += (num[j] * num[i-j-1]) + + return num[n] diff --git a/python/tree/validate-binary-search-tree.py b/python/tree/validate-binary-search-tree.py new file mode 100644 index 0000000..10f6da3 --- /dev/null +++ b/python/tree/validate-binary-search-tree.py @@ -0,0 +1,27 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def isValidBST(self, root): + if root is None: + return True + + node = root.left + while node and node.right: + node = node.right + + if node and node.val >= root.val: + return False + + node = root.right + while node and node.left: + node = node.left + + if node and node.val <= root.val: + return False + + return self.isValidBST(root.left) and self.isValidBST(root.right) diff --git a/python/tree/validate-binary-search-tree[1].py b/python/tree/validate-binary-search-tree[1].py new file mode 100644 index 0000000..aed13a2 --- /dev/null +++ b/python/tree/validate-binary-search-tree[1].py @@ -0,0 +1,23 @@ +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def __init__(self): + self.lastnode = None + + def isValidBST(self, root): + if root is None: + return True + + if not self.isValidBST(root.left): + return False + + if self.lastnode != None and self.lastnode.val >= root.val: + return False + + self.lastnode = root + return self.isValidBST(root.right)