diff --git a/3Sum/3Sum.cpp b/3Sum/3Sum.cpp index e810a40..d289944 100644 --- a/3Sum/3Sum.cpp +++ b/3Sum/3Sum.cpp @@ -1,34 +1,40 @@ class Solution { public: - vector> threeSum(vector& num) { - // Start typing your C/C++ solution below - // DO NOT write int main() function + vector > threeSum(vector &num) { vector> result; + if (num.empty()) { + return result; + } sort(num.begin(), num.end()); - int n = num.size(); - for (int i = 0; i < n; i++) { - int lf = i + 1; - int rt = n - 1; - while (lf < rt) { - int sum = num[i] + num[lf] + num[rt]; - if (sum < 0) { - lf += 1; - } - else if (sum > 0) { - rt -= 1; - } - else { - vector elem; - elem.push_back(num[i]); - elem.push_back(num[lf]); - elem.push_back(num[rt]); - if (find(result.begin(), result.end(), elem) == result.end()) - result.push_back(elem); - lf += 1; - rt -= 1; + for (int start = 0; start < num.size(); start++) { + int i = start + 1; + int j = num.size() - 1; + int target = -num[start]; + while (i < j) { + if (num[i] + num[j] == target) { + vector triple; + triple.push_back(num[start]); + triple.push_back(num[i]); + triple.push_back(num[j]); + result.push_back(triple); + while (i + 1 < num.size() && num[i] == num[i+1]) { + i++; + } + while (j - 1 >= 0 && num[j] == num[j-1]) { + j--; + } + i++; + j--; + } else if (num[i] + num[j] < target) { + i++; + } else { + j--; } } + while (start + 1 < num.size() && num[start] == num[start+1]) { + start++; + } } - return move(result); + return result; } -}; \ No newline at end of file +}; diff --git a/3SumClosest/3SumClosest.cpp b/3SumClosest/3SumClosest.cpp index d35f6e1..6e9a36e 100644 --- a/3SumClosest/3SumClosest.cpp +++ b/3SumClosest/3SumClosest.cpp @@ -1,36 +1,27 @@ class Solution { public: - int threeSumClosest(vector& num, int target) { - // Start typing your C/C++ solution below - // DO NOT write int main() function + int threeSumClosest(vector &num, int target) { sort(num.begin(), num.end()); - int n = num.size(); - int closet = INT_MAX; - int result; - for (int i = 0; i < n; i++) { - int lf = i + 1; - int rt = n - 1; - while (lf < rt) { - int sum = num[i] + num[lf] + num[rt]; + int delta = INT_MAX; + int closest = 0; + for (int i = 0; i < num.size(); i++) { + int start = i + 1; + int limit = num.size() - 1; + while (start < limit) { + int sum = num[i] + num[start] + num[limit]; + if (abs(sum - target) < delta) { + delta = abs(sum - target); + closest = sum; + } if (sum == target) { return target; - } - else if (sum < target) { - if (target - sum < closet) { - result = sum; - closet = target - sum; - } - lf += 1; - } - else { - if (sum - target < closet) { - result = sum; - closet = sum - target; - } - rt -= 1; + } else if (sum < target) { + start++; + } else { + limit--; } } } - return result; + return closest; } -}; \ No newline at end of file +}; diff --git a/AddBinary/AddBinary.cpp b/AddBinary/AddBinary.cpp index 833ab4f..6d6a53d 100644 --- a/AddBinary/AddBinary.cpp +++ b/AddBinary/AddBinary.cpp @@ -1,32 +1,28 @@ class Solution { public: string addBinary(string a, string b) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - string c; - int len_a = a.size(); - int len_b = b.size(); + reverse(a.begin(), a.end()); + reverse(b.begin(), b.end()); int carry = 0; - for (int i = 0; i < min(len_a, len_b); i++) { - int x = a[len_a - i - 1] - '0'; - int y = b[len_b - i - 1] - '0'; - c += (x + y + carry) % 2 + '0'; - carry = (x + y + carry) / 2; + int i = 0; + while (i < a.size() && i < b.size()) { + carry += a[i] - '0' + b[i] - '0'; + c += carry % 2 + '0'; + carry /= 2; + i++; } - if (len_a > len_b) { - for (int i = len_b; i < len_a; i++) { - int x = a[len_a - i - 1] - '0'; - c += (x + carry) % 2 + '0'; - carry = (x + carry) / 2; - } + while (i < a.size()) { + carry += a[i] - '0'; + c += carry % 2 + '0'; + carry /= 2; + i++; } - else if (len_a < len_b) { - for (int i = len_a; i < len_b; i++) { - int x = b[len_b - i - 1] - '0'; - c += (x + carry) % 2 + '0'; - carry = (x + carry) / 2; - } + while (i < b.size()) { + carry += b[i] - '0'; + c += carry % 2 + '0'; + carry /= 2; + i++; } while (carry) { c += carry % 2 + '0'; @@ -35,4 +31,4 @@ class Solution { reverse(c.begin(), c.end()); return c; } -}; \ No newline at end of file +}; diff --git a/Anagrams/Anagrams.cpp b/Anagrams/Anagrams.cpp index 45d8ed8..a0fd5e5 100644 --- a/Anagrams/Anagrams.cpp +++ b/Anagrams/Anagrams.cpp @@ -1,25 +1,21 @@ class Solution { public: - vector anagrams(vector& strs) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - map> dict; - + vector anagrams(vector &strs) { + vector result; + map exists; for (int i = 0; i < strs.size(); i++) { - string copy_string(strs[i]); - sort(copy_string.begin(), copy_string.end()); - dict[copy_string].push_back(i); + string u = strs[i]; + sort(u.begin(), u.end()); + if (exists.find(u) == exists.end()) { + exists[u] = i; + } else { + if (exists[u] >= 0) { + result.push_back(strs[exists[u]]); + exists[u] = -1; + } + result.push_back(strs[i]); + } } - - vector anagrams; - for (auto iter = dict.begin(); iter != dict.end(); iter++) { - vector& string_id = iter->second; - if (string_id.size() <= 1) continue; - for (int i = 0; i < string_id.size(); i++) - anagrams.push_back(strs[string_id[i]]); - } - - return move(anagrams); + return result; } -}; \ No newline at end of file +}; diff --git a/BestTimetoBuyandSellStockIII/BestTimetoBuyandSellStockIII.cpp b/BestTimetoBuyandSellStockIII/BestTimetoBuyandSellStockIII.cpp index d896e09..ba9684e 100644 --- a/BestTimetoBuyandSellStockIII/BestTimetoBuyandSellStockIII.cpp +++ b/BestTimetoBuyandSellStockIII/BestTimetoBuyandSellStockIII.cpp @@ -1,30 +1,25 @@ class Solution { public: int maxProfit(vector &prices) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - vector dp(prices.size()); - vector rdp(prices.size()); - int minval = 0x3fffffff; - int maxprofit = 0; - size_t i = 0; - for (auto iter = prices.begin(); iter != prices.end(); iter++) { - minval = min(minval, *iter); - maxprofit = max(maxprofit, *iter - minval); - dp[i++] = maxprofit; + if (prices.size() < 2) { + return 0; } - int maxval = 0; - maxprofit = 0; - i = prices.size() - 1; - for (auto iter = prices.rbegin(); iter != prices.rend(); iter++) { - maxval = max(maxval, *iter); - maxprofit = max(maxprofit, maxval - *iter); - rdp[i--] = maxprofit; + int n = prices.size(); + vector dp1(n, 0); + vector dp2(n, 0); + int minval = prices[0]; + for (int i = 1; i < n; i++) { + minval = min(minval, prices[i]); + dp1[i] = max(dp1[i-1], prices[i] - minval); + } + int maxval = prices[n-1]; + for (int i = n - 2; i >= 0; i--) { + maxval = max(maxval, prices[i]); + dp2[i] = max(dp2[i+1], maxval - prices[i]); } int result = 0; - for (i = 0; i < dp.size(); i++) { - result = max(result, dp[i] + rdp[i]); + for (int i = 0; i < n; i++) { + result = max(result, dp1[i] + dp2[i]); } return result; } diff --git a/BinaryTreeMaximumPathSum/BinaryTreeMaximumPathSum.cpp b/BinaryTreeMaximumPathSum/BinaryTreeMaximumPathSum.cpp index d4df188..fccad97 100644 --- a/BinaryTreeMaximumPathSum/BinaryTreeMaximumPathSum.cpp +++ b/BinaryTreeMaximumPathSum/BinaryTreeMaximumPathSum.cpp @@ -7,41 +7,35 @@ * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ - -const int INFS = 0x3fffffff; - -struct NodeInfo { - int maxval, maxfromroot; - NodeInfo() : maxval(-INFS), maxfromroot(-INFS) {} -}; - class Solution { public: int maxPathSum(TreeNode *root) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - NodeInfo res = dfs(root); - return res.maxval; - + if (root == NULL) { + return 0; + } + int maxsum = INT_MIN; + dfs(root, &maxsum); + return maxsum; } - NodeInfo dfs(TreeNode *node) { - NodeInfo left, root, right; + + int dfs(TreeNode* node, int* maxsum) { if (node == NULL) { - return root; + return 0; + } + int left = dfs(node->left, maxsum); + int right = dfs(node->right, maxsum); + int val = node->val; + if (max(left, right) > 0) { + val += max(left, right); + } + int sum = node->val; + if (left > 0) { + sum += left; + } + if (right > 0) { + sum += right; } - if (node->left) - left = dfs(node->left); - if (node->right) - right = dfs(node->right); - - int l = max(0, left.maxfromroot); - int r = max(0, right.maxfromroot); - - root.maxfromroot = node->val + max(0, max(l, r)); - root.maxval = max(left.maxval, right.maxval); - root.maxval = max(root.maxval, l + r + node->val); - return root; + *maxsum = max(*maxsum, sum); + return val; } -private: - }; diff --git a/BinaryTreePostorderTraversal/BinaryTreePostorderTraversal.cc b/BinaryTreePostorderTraversal/BinaryTreePostorderTraversal.cc new file mode 100644 index 0000000..8b6f986 --- /dev/null +++ b/BinaryTreePostorderTraversal/BinaryTreePostorderTraversal.cc @@ -0,0 +1,51 @@ +/** + * Definition for binary tree + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ +class Solution { +public: + void print(vector& result, TreeNode* from, TreeNode* to) { + vector temp; + while (true) { + temp.push_back(from->val); + if (from == to) { + break; + } + from = from->right; + } + for (int i = temp.size() - 1; i >= 0; i--) { + result.push_back(temp[i]); + } + } + + vector postorderTraversal(TreeNode *root) { + vector result; + TreeNode prev(0); + prev.left = root; + TreeNode* curr = &prev; + while (curr != NULL) { + if (curr->left == NULL) { + curr = curr->right; + } else { + TreeNode* next = curr->left; + while (next->right && next->right != curr) { + next = next->right; + } + if (next->right == NULL) { + next->right = curr; + curr = curr->left; + } else { + print(result, curr->left, next); + next->right = NULL; + curr = curr->right; + } + } + } + return result; + } +}; diff --git a/BinaryTreePreorderTraversal/BinaryTreePreorderTraversal.cpp b/BinaryTreePreorderTraversal/BinaryTreePreorderTraversal.cpp new file mode 100644 index 0000000..2cfea13 --- /dev/null +++ b/BinaryTreePreorderTraversal/BinaryTreePreorderTraversal.cpp @@ -0,0 +1,36 @@ +/** + * Definition for binary tree + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ +class Solution { +public: + vector preorderTraversal(TreeNode *root) { + vector result; + TreeNode* node = root; + while (node) { + if (node->left == NULL) { + result.push_back(node->val); + node = node->right; + } else { + TreeNode* next = node->left; + while (next->right && next->right != node) { + next = next->right; + } + if (next->right == NULL) { + next->right = node; + result.push_back(node->val); + node = node->left; + } else { + next->right = NULL; + node = node->right; + } + } + } + return result; + } +}; diff --git a/CloneGraph/CloneGraph.cc b/CloneGraph/CloneGraph.cc new file mode 100644 index 0000000..df8475f --- /dev/null +++ b/CloneGraph/CloneGraph.cc @@ -0,0 +1,31 @@ +/** + * Definition for undirected graph. + * struct UndirectedGraphNode { + * int label; + * vector neighbors; + * UndirectedGraphNode(int x) : label(x) {}; + * }; + */ +class Solution { +public: + UndirectedGraphNode* clone(UndirectedGraphNode* node, map& graph) { + if (node == NULL) { + return NULL; + } + if (graph.find(node) != graph.end()) { + return graph[node]; + } + UndirectedGraphNode* newnode = new UndirectedGraphNode(node->label); + graph[node] = newnode; + for (int i = 0; i < node->neighbors.size(); i++) { + UndirectedGraphNode* next = clone(node->neighbors[i], graph); + newnode->neighbors.push_back(next); + } + return newnode; + } + + UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) { + map graph; + return clone(node, graph); + } +}; diff --git a/ConstructBinaryTreefromInorderandPostorderTraversal/ConstructBinaryTreefromInorderandPostorderTraversal.cpp b/ConstructBinaryTreefromInorderandPostorderTraversal/ConstructBinaryTreefromInorderandPostorderTraversal.cpp index 98eb3de..5aac4ce 100644 --- a/ConstructBinaryTreefromInorderandPostorderTraversal/ConstructBinaryTreefromInorderandPostorderTraversal.cpp +++ b/ConstructBinaryTreefromInorderandPostorderTraversal/ConstructBinaryTreefromInorderandPostorderTraversal.cpp @@ -9,41 +9,27 @@ */ class Solution { public: - TreeNode *buildTree(vector& inorder, vector& postorder) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - int size = inorder.size(); - if (size == 0) return NULL; - - TreeNode *root = new TreeNode(0); - build(root, size, inorder, 0, postorder, 0); - return root; + TreeNode *buildTree(vector &inorder, vector &postorder) { + if (inorder.empty()) { + return NULL; + } + return dfs(inorder, 0, inorder.size() - 1, postorder, 0, postorder.size() - 1); } - - void build(TreeNode *root, int size, vector& inorder, int inLeft, vector& postorder, int postLeft) { - assert(size > 0); - - int pivot = postorder[postLeft+size-1]; - root->val = pivot; - - if (size == 1) return; - - int sizeleft = 0; - for (int i = 0; i < size; i++) { - if (inorder[inLeft+i] == pivot) - break; - sizeleft += 1; + TreeNode* dfs(vector& inorder, int l1, int r1, vector& postorder, int l2, int r2) { + if (l1 > r1) { + return NULL; } - - if (sizeleft > 0) { - root->left = new TreeNode(0); - build(root->left, sizeleft, inorder, inLeft, postorder, postLeft); + if (l1 == r1) { + return new TreeNode(inorder[l1]); } - int sizeright = size - sizeleft - 1; - if (sizeright > 0) { - root->right = new TreeNode(0); - build(root->right, sizeright, inorder, inLeft + sizeleft + 1, postorder, postLeft + sizeleft); + TreeNode* root = new TreeNode(postorder[r2]); + for (int i = l1; i <= r1; i++) { + if (inorder[i] == postorder[r2]) { + root->left = dfs(inorder, l1, i - 1, postorder, l2, l2 + i - l1 - 1); + root->right = dfs(inorder, i + 1, r1, postorder, l2 + i - l1, r2 - 1); + return root; + } } + return NULL; } -}; \ No newline at end of file +}; diff --git a/ConstructBinaryTreefromPreorderandInorderTraversal/ConstructBinaryTreefromPreorderandInorderTraversal.cpp b/ConstructBinaryTreefromPreorderandInorderTraversal/ConstructBinaryTreefromPreorderandInorderTraversal.cpp index e9fb0d6..85be477 100644 --- a/ConstructBinaryTreefromPreorderandInorderTraversal/ConstructBinaryTreefromPreorderandInorderTraversal.cpp +++ b/ConstructBinaryTreefromPreorderandInorderTraversal/ConstructBinaryTreefromPreorderandInorderTraversal.cpp @@ -9,37 +9,28 @@ */ class Solution { public: - TreeNode *buildTree(vector& preorder, vector& inorder) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - if (preorder.empty()) return NULL; - - TreeNode *root = new TreeNode(0); - build(root, preorder.size(), preorder, 0, inorder, 0); - return root; + TreeNode *buildTree(vector &preorder, vector &inorder) { + if (preorder.size() == 0) { + return NULL; + } + return dfs(preorder, 0, preorder.size() - 1, inorder, 0, inorder.size() - 1); } - void build(TreeNode *root, int size, vector& preorder, int preLeft, vector& inorder, int inLeft) { - if (size == 1) { - root->val = preorder[preLeft]; - return ; - } - int sizeLeft = 0; - for (int i = 0; i < size; i++) { - if (preorder[preLeft] == inorder[i+inLeft]) - break; - sizeLeft += 1; + TreeNode* dfs(vector& preorder, int l1, int r1, vector& inorder, int l2, int r2) { + if (l1 > r1) { + return NULL; } - root->val = preorder[preLeft]; - if (sizeLeft > 0) { - root->left = new TreeNode(0); - build(root->left, sizeLeft, preorder, preLeft + 1, inorder, inLeft); + if (l1 == r1) { + return new TreeNode(preorder[l1]); } - int sizeRight = size - sizeLeft - 1; - if (sizeRight > 0) { - root->right = new TreeNode(0); - build(root->right, sizeRight, preorder, preLeft + sizeLeft + 1, inorder, inLeft + sizeLeft + 1); + TreeNode* root = new TreeNode(preorder[l1]); + for (int i = l2; i <= r2; i++) { + if (inorder[i] == preorder[l1]) { + root->left = dfs(preorder, l1 + 1, l1 + i - l2, inorder, l2, i - 1); + root->right = dfs(preorder, l1 + i - l2 + 1, r1, inorder, i + 1, r2); + return root; + } } + return NULL; } -}; \ No newline at end of file +}; diff --git a/ConvertSortedArraytoBinarySearchTree/ConvertSortedArraytoBinarySearchTree.cpp b/ConvertSortedArraytoBinarySearchTree/ConvertSortedArraytoBinarySearchTree.cpp index 848e81b..1f57d1a 100644 --- a/ConvertSortedArraytoBinarySearchTree/ConvertSortedArraytoBinarySearchTree.cpp +++ b/ConvertSortedArraytoBinarySearchTree/ConvertSortedArraytoBinarySearchTree.cpp @@ -10,27 +10,19 @@ class Solution { public: TreeNode *sortedArrayToBST(vector &num) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - if (num.empty()) return NULL; - TreeNode *root = new TreeNode(0); - dfs(root, 0, num.size() - 1, num); - return root; - + return dfs(num, 0, num.size() - 1); } - void dfs(TreeNode *root, int left, int right, vector& num) { - if (left == right) { - root->val = num[left]; - root->left = root->right = NULL; - return; + TreeNode* dfs(vector& num, int start, int limit) { + if (start > limit) { + return NULL; } - int mid = (left + right) / 2; - root->val = num[mid]; - root->right = new TreeNode(0); - dfs(root->right, mid + 1, right, num); - if (mid != left) { - root->left = new TreeNode(0); - dfs(root->left, left, mid - 1, num); + if (start == limit) { + return new TreeNode(num[start]); } + int middle = (start + limit) / 2; + TreeNode* root = new TreeNode(num[middle]); + root->left = dfs(num, start, middle - 1); + root->right = dfs(num, middle + 1, limit); + return root; } -}; \ No newline at end of file +}; diff --git a/ConvertSortedListtoBinarySearchTree/ConvertSortedListtoBinarySearchTree.cpp b/ConvertSortedListtoBinarySearchTree/ConvertSortedListtoBinarySearchTree.cpp index 6c2aa14..bb37415 100644 --- a/ConvertSortedListtoBinarySearchTree/ConvertSortedListtoBinarySearchTree.cpp +++ b/ConvertSortedListtoBinarySearchTree/ConvertSortedListtoBinarySearchTree.cpp @@ -18,38 +18,29 @@ class Solution { public: TreeNode *sortedListToBST(ListNode *head) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - if (head == NULL) + if (head == NULL) { return NULL; - TreeNode *root = new TreeNode(0); - dfs(root, head); - return root; - - } - void dfs(TreeNode *root, ListNode *node) { - if (node->next == NULL) { - root->val = node->val; - root->left = root->right = NULL; - return; } - ListNode *prev = node; - ListNode *slow = node->next; - ListNode *fast = node->next->next; - while (fast != NULL && fast->next != NULL) { + if (head->next == NULL) { + return new TreeNode(head->val); + } + ListNode prevhead(0); + prevhead.next = head; + ListNode* prev = &prevhead; + ListNode* one = head; + ListNode* two = head; + while (two && two->next) { prev = prev->next; - slow = slow->next; - fast = fast->next->next; + one = one->next; + two = two->next->next; } - root->val = slow->val; - root->left = new TreeNode(0); + TreeNode* root = new TreeNode(one->val); + ListNode* temp = one->next; prev->next = NULL; - dfs(root->left, node); - - if (slow->next != NULL) { - root->right = new TreeNode(0); - dfs(root->right, slow->next); - } + one->next = NULL; + root->left = sortedListToBST(head); + root->right = sortedListToBST(temp); + return root; } }; @@ -61,6 +52,3 @@ class Solution { - - - diff --git a/DivideTwoIntegers/DivideTwoIntegers.cpp b/DivideTwoIntegers/DivideTwoIntegers.cpp index 061d4f6..2ab4777 100644 --- a/DivideTwoIntegers/DivideTwoIntegers.cpp +++ b/DivideTwoIntegers/DivideTwoIntegers.cpp @@ -1,42 +1,31 @@ class Solution { public: int divide(int dividend, int divisor) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - bool signed_flag = false; - unsigned unsigned_dividend, unsigned_divisor; - - if (dividend < 0) { - unsigned_dividend = -dividend; - signed_flag ^= true; + long long int divid = dividend; + long long int divis = divisor; + bool neg = false; + if (divid < 0) { + neg = neg ? false : true; + divid = -divid; } - else - unsigned_dividend = dividend; - - if (divisor < 0) { - unsigned_divisor = -divisor; - signed_flag ^= true; + if (divis < 0) { + neg = neg ? false : true; + divis = -divis; } - else - unsigned_divisor = divisor; - - unsigned result = unsignedDivide(unsigned_dividend, unsigned_divisor); - return signed_flag ? -result : result; - } - - unsigned unsignedDivide(unsigned dividend, unsigned divisor) { - unsigned result = 0; - while (dividend >= divisor) { - unsigned num = divisor; - unsigned shift = 0; - while (((unsigned long long)num << 1) <= dividend) { - num <<= 1; + long long int result = 0; + while (divid >= divis) { + long long int x = divis; + int shift = 0; + while ((x << 1) <= divid) { + x <<= 1; shift += 1; } - dividend -= num; - result |= 1 << shift; + result += 1 << shift; + divid -= x; + } + if (neg) { + result = -result; } return result; } -}; \ No newline at end of file +}; diff --git a/EditDistance/EditDistance.cpp b/EditDistance/EditDistance.cpp index 476ef9d..8c96237 100644 --- a/EditDistance/EditDistance.cpp +++ b/EditDistance/EditDistance.cpp @@ -1,26 +1,23 @@ class Solution { public: int minDistance(string word1, string word2) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - int len1 = word1.size(); - int len2 = word2.size(); - - for (int i = 0; i <= max(len1, len2); i++) - F[i][0] = F[0][i] = i; - - for (int i = 1; i <= len1; i++) { - for (int j = 1; j <= len2; j++) { - if (word1[i-1] == word2[j-1]) - F[i][j] = F[i-1][j-1]; - else - F[i][j] = min(F[i-1][j-1], min(F[i-1][j], F[i][j-1])) + 1; + vector> dp(word1.size() + 1, vector(word2.size() + 1, 0)); + for (int i = 1; i <= word1.size(); i++) { + dp[i][0] = i; + } + for (int j = 1; j <= word2.size(); j++) { + dp[0][j] = j; + } + for (int i = 1; i <= word1.size(); i++) { + for (int j = 1; j <= word2.size(); j++) { + if (word1[i-1] == word2[j-1]) { + dp[i][j] = dp[i-1][j-1]; + } else { + dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + 1; + dp[i][j] = min(dp[i][j], dp[i-1][j-1] + 1); + } } } - return F[len1][len2]; + return dp[word1.size()][word2.size()]; } -private: - static const int MAXN = 1010; - int F[MAXN][MAXN]; -}; \ No newline at end of file +}; diff --git a/EvaluateReversePolishNotation/EvaluateReversePolishNotation.cpp b/EvaluateReversePolishNotation/EvaluateReversePolishNotation.cpp new file mode 100644 index 0000000..3d35760 --- /dev/null +++ b/EvaluateReversePolishNotation/EvaluateReversePolishNotation.cpp @@ -0,0 +1,39 @@ +class Solution { +public: + int evalRPN(vector &tokens) { + stack nums; + stack ops; + + for (int i = 0; i < tokens.size(); i++) { + if (tokens[i][0] >= '0' && tokens[i][0] <= '9') { + int value = atoi(tokens[i].c_str()); + nums.push(value); + } else if (tokens[i].size() >= 2) { + int value = atoi(tokens[i].c_str()); + nums.push(value); + } else { + int b = nums.top(); + nums.pop(); + int a = nums.top(); + nums.pop(); + int c; + switch (tokens[i][0]) { + case '+': + c = a + b; + break; + case '-': + c = a - b; + break; + case '*': + c = a * b; + break; + case '/': + c = a / b; + break; + } + nums.push(c); + } + } + return nums.top(); + } +}; diff --git a/FirstMissingPositive/FirstMissingPositive.cpp b/FirstMissingPositive/FirstMissingPositive.cpp index d2c380a..fc527c5 100644 --- a/FirstMissingPositive/FirstMissingPositive.cpp +++ b/FirstMissingPositive/FirstMissingPositive.cpp @@ -1,62 +1,19 @@ class Solution { public: int firstMissingPositive(int A[], int n) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - int i = 0; while (i < n) { - if (A[i] != i + 1 && 0 < A[i] && A[i] <= n && A[A[i]-1] != A[i]) + if (0 < A[i] && A[i] <= n && A[i] != A[A[i]-1]) { swap(A[i], A[A[i]-1]); - else - i += 1; + } else { + i++; + } } - int first_positive = 0; for (int i = 0; i < n; i++) { if (A[i] != i + 1) { - first_positive = i + 1; - break; + return i + 1; } } - if (first_positive == 0) - first_positive = n + 1; - return first_positive; + return n + 1; } }; - -// -// solution 2 -// -class Solution { -public: - int firstMissingPositive(int A[], int n) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - bool find_1 = false; - for (int i = 0; i < n; i++) { - if (A[i] == 1) - find_1 = true; - else if (A[i] <= 0) - A[i] = 1; - } - if (!find_1) return 1; - for (int i = 0; i < n; i++) { - if (A[i] > 0 && A[i] <= n && A[A[i]-1] > 0) { - A[A[i]-1] = -A[A[i]-1]; - } - else if (A[i] <= -1 && -A[i] <= n && A[-A[i]-1] > 0) - A[-A[i]-1] = -A[-A[i]-1]; - } - int first_positive = 0; - for (int i = 0; i < n; i++) { - if (A[i] > 0) { - first_positive = i + 1; - break; - } - } - if (first_positive == 0) - first_positive = n + 1; - return first_positive; - } -}; \ No newline at end of file diff --git a/FlattenBinaryTreetoLinkedList/FlattenBinaryTreetoLinkedList.cpp b/FlattenBinaryTreetoLinkedList/FlattenBinaryTreetoLinkedList.cpp index 4be87c3..3cf078c 100644 --- a/FlattenBinaryTreetoLinkedList/FlattenBinaryTreetoLinkedList.cpp +++ b/FlattenBinaryTreetoLinkedList/FlattenBinaryTreetoLinkedList.cpp @@ -30,12 +30,42 @@ class Solution { tree_stack.push(node->left); node->left = NULL; } - if (flatten_node == NULL) + if (flatten_node == NULL) { flatten_node = node; - else { + } else { flatten_node->right = node; flatten_node = flatten_node->right; } } } -}; \ No newline at end of file +}; + +// recursion +class Solution { +public: + void flatten(TreeNode *root) { + dfs(root); + } + + pair dfs(TreeNode* root) { + if (root == NULL) { + return make_pair((TreeNode*)NULL, (TreeNode*)NULL); + } + pair left = dfs(root->left); + pair right = dfs(root->right); + root->left = NULL; + root->right = NULL; + if (left.first && right.first) { + root->right = left.first; + left.second->right = right.first; + return make_pair(root, right.second); + } else if (left.first) { + root->right = left.first; + return make_pair(root, left.second); + } else if (right.first) { + root->right = right.first; + return make_pair(root, right.second); + } + return make_pair(root, root); + } +}; diff --git a/GenerateParentheses/GenerateParentheses.cpp b/GenerateParentheses/GenerateParentheses.cpp index 91c445e..c559125 100644 --- a/GenerateParentheses/GenerateParentheses.cpp +++ b/GenerateParentheses/GenerateParentheses.cpp @@ -1,47 +1,31 @@ class Solution { public: vector generateParenthesis(int n) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - vector result; - if (n == 0) return result; - - string parenthesis; - DFS(parenthesis, 0, 0, n, result); - - return move(result); + string s; + if (n == 0) { + return result; + } + dfs(result, s, n, n); + return result; } - - void DFS(string& parenthesis, int left, int right, int n, vector& result) { - if (right > left) return; - - if (left == right && left == n) { - result.push_back(parenthesis); + void dfs(vector& result, string& s, int left, int right) { + if (left > right) { return; } - - if (left == right && left < n) { - parenthesis += '('; - DFS(parenthesis, left + 1, right, n, result); - parenthesis.erase(parenthesis.size() - 1, 1); + if (left == 0 && right == 0) { + result.push_back(s); return; } - if (left > right && left < n) { - parenthesis += '('; - DFS(parenthesis, left + 1, right, n, result); - parenthesis.erase(parenthesis.size() - 1, 1); - - parenthesis += ')'; - DFS(parenthesis, left, right + 1, n, result); - parenthesis.erase(parenthesis.size() - 1, 1); + if (left >= 1) { + s.push_back('('); + dfs(result, s, left - 1, right); + s.pop_back(); } - if (left == n && right < n) { - parenthesis += ')'; - DFS(parenthesis, left, right + 1, n, result); - parenthesis.erase(parenthesis.size() - 1, 1); + if (right >= 1) { + s.push_back(')'); + dfs(result, s, left, right - 1); + s.pop_back(); } - } }; - diff --git a/GrayCode/GrayCode.cpp b/GrayCode/GrayCode.cpp index 51b3bcf..1f69fd0 100644 --- a/GrayCode/GrayCode.cpp +++ b/GrayCode/GrayCode.cpp @@ -9,4 +9,21 @@ class Solution { gray_code.push_back((i >> 1) ^ i); return gray_code; } -}; \ No newline at end of file +}; + +// More comprehensible solution +class Solution { +public: + vector grayCode(int n) { + vector result(1, 0); + for (int i = 0; i < n; i++) { + int curr = result.size(); + while (curr) { + curr--; + int x = result[curr]; + result.push_back((1 << i) + x); + } + } + return result; + } +}; diff --git a/ImplementstrStr/ImplementstrStr.cpp b/ImplementstrStr/ImplementstrStr.cpp index c2fc8a1..9cafef9 100644 --- a/ImplementstrStr/ImplementstrStr.cpp +++ b/ImplementstrStr/ImplementstrStr.cpp @@ -1,48 +1,32 @@ class Solution { public: char *strStr(char *haystack, char *needle) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - int hays_length = strlen(haystack); - int needle_length = strlen(needle); - - if (hays_length == 0 && needle_length != 0) - return NULL; - if (hays_length == 0 || needle_length == 0) + int n = strlen(haystack); + int m = strlen(needle); + if (m == 0) { return haystack; - - int needle_array[needle_length]; - - getPattern(needle, needle_array, needle_length); - int pos = KMP(haystack, hays_length, needle, needle_array, needle_length); - if (pos != -2) - return haystack + pos + 1; - else - return NULL; - } - - int KMP(const char *source, int lens, const char *pattern, const int p[], int lenp) { - int i, j = -1; - for (i = 0; i < lens; i++) { - while (j != -1 && source[i] != pattern[j+1]) - j = p[j]; - if (source[i] == pattern[j+1]) - j += 1; - if (j == lenp - 1) return i - lenp; } - return -2; - } - - void getPattern(const char *pattern, int p[], int len) { - p[0] = -1; - int i, j = -1; - for (i = 1; i < len; i++) { - while (j != -1 && pattern[i] != pattern[j+1]) - j = p[j]; - if (pattern[i] == pattern[j+1]) - j += 1; - p[i] = j; + vector next(m, -1); + for (int i = 1, j = -1; i < m; i++) { + while (j != -1 && needle[j+1] != needle[i]) { + j = next[j]; + } + if (needle[j+1] == needle[i]) { + j++; + } + next[i] = j; + } + for (int i = 0, j = -1; i < n; i++) { + while (j != -1 && needle[j+1] != haystack[i]) { + j = next[j]; + } + if (needle[j+1] == haystack[i]) { + j++; + } + if (j == m - 1) { + return haystack + i - m + 1; + } } + return NULL; } -}; \ No newline at end of file +}; diff --git a/LRUCache/LRUCache.cc b/LRUCache/LRUCache.cc new file mode 100644 index 0000000..bac7cb1 --- /dev/null +++ b/LRUCache/LRUCache.cc @@ -0,0 +1,60 @@ +class LRUCache{ +public: + LRUCache(int capacity) { + cap_ = capacity; + dummy_.prev = &dummy_; + dummy_.next = &dummy_; + } + + int get(int key) { + if (cache_.find(key) == cache_.end()) { + return -1; + } + entry* e = cache_[key]; + e->prev = &dummy_; + e->next = dummy_.next; + dummy_.next->prev = e; + dummy_.next = e; + + return e->val; + } + + void set(int key, int value) { + while (cache_.size() >= cap_) { + entry* e = dummy_.prev; + e->prev->next = &dummy_; + dummy_.prev = e->prev; + + cache_.erase(e->key); + delete(e); + } + + entry* e; + if (cache_.find(key) == cache_.end()) { + e = new(entry); + cache_[key] = e; + } else { + e = cache_[key]; + e->prev->next = e->next; + e->next->prev = e->prev; + } + e->prev = &dummy_; + e->next = dummy_.next; + dummy_.next->prev = e; + dummy_.next = e; + + e->val = value; + } + +private: + struct entry { + int key; + int val; + entry* prev; + entry* next; + }; + + int cap_; + map cache_; + struct entry dummy_; +}; diff --git a/LengthofLastWord/LengthofLastWord.cpp b/LengthofLastWord/LengthofLastWord.cpp index 5a48b92..1d0f77e 100644 --- a/LengthofLastWord/LengthofLastWord.cpp +++ b/LengthofLastWord/LengthofLastWord.cpp @@ -1,23 +1,19 @@ class Solution { public: int lengthOfLastWord(const char *s) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - int last_word_length = 0; - int word_length = 0; - while (*s != '\0') { - while (*s == ' ') - s++; - - int word_length = 0; - while (*s != ' ' && *s != '\0') { - s++; - word_length += 1; + int curr = 0; + const char* p = s; + while (*p != '\0') { + if (*p == ' ') { + p++; + } else { + curr = 0; + while (*p != '\0' && *p != ' ') { + p++; + curr++; + } } - if (word_length) - last_word_length = word_length; } - return last_word_length; + return curr; } -}; \ No newline at end of file +}; diff --git a/LetterCombinationsofaPhoneNumber/LetterCombinationsofaPhoneNumber.cpp b/LetterCombinationsofaPhoneNumber/LetterCombinationsofaPhoneNumber.cpp index 0b6cfde..ff2d01c 100644 --- a/LetterCombinationsofaPhoneNumber/LetterCombinationsofaPhoneNumber.cpp +++ b/LetterCombinationsofaPhoneNumber/LetterCombinationsofaPhoneNumber.cpp @@ -1,34 +1,32 @@ - class Solution { -private: - static const string keypad[8]; public: vector letterCombinations(string digits) { - // Start typing your C/C++ solution below - // DO NOT write int main() function + map keypad; + keypad[2] = string("abc"); + keypad[3] = string("def"); + keypad[4] = string("ghi"); + keypad[5] = string("jkl"); + keypad[6] = string("mno"); + keypad[7] = string("pqrs"); + keypad[8] = string("tuv"); + keypad[9] = string("wxyz"); - vector all_letters; + vector result; string letter; - - if (digits.empty()) { - all_letters.push_back(letter); - return all_letters; - } - - letterCombinationsHelper(digits, 0, letter, all_letters); + dfs(result, letter, digits, 0, keypad); + return result; } - void letterCombinationsHelper(string& digits, int step, string& letter, vector& all_letters) { - if (step == digits.size()) { - all_letters.push_back(letter); + void dfs(vector& result, string& letter, string& digits, int pos, map& keypad) { + if (pos == digits.size()) { + result.push_back(letter); return; } - int x = digits[step] - '2'; - for (int i = 0; i < keypad[x].size(); i++) { - letter += keypad[x][i]; - letterCombinationsHelper(digits, step + 1, letter, all_letters); - letter.erase(letter.size() - 1, 1); + int x = digits[pos] - '0'; + string s = keypad[x]; + for (int i = 0; i < s.size(); i++) { + letter.push_back(s[i]); + dfs(result, letter, digits, pos + 1, keypad); + letter.pop_back(); } } }; - -const string Solution::keypad[8] = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; diff --git a/LongestCommonPrefix/LongestCommonPrefix.cpp b/LongestCommonPrefix/LongestCommonPrefix.cpp index e5cf5ff..9a51864 100644 --- a/LongestCommonPrefix/LongestCommonPrefix.cpp +++ b/LongestCommonPrefix/LongestCommonPrefix.cpp @@ -1,23 +1,18 @@ class Solution { public: - string longestCommonPrefix(vector& strs) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - string common; - if (strs.size() == 0) - return common; - common = strs[0]; - for (size_t i = 1; i < strs.size(); i++) { - size_t j; - for (j = 0; j < common.size(); j++) { - if (common[j] != strs[i][j]) break; - } - if (j == 0) { - common = ""; - return common; + string longestCommonPrefix(vector &strs) { + if (strs.empty()) { + return string(); + } + for (int i = 0; i < strs[0].size(); i++) { + for (int j = 1; j < strs.size(); j++) { + if (i == strs[j].size()) { + return strs[j]; + } else if (i < strs[j].size() && strs[0][i] != strs[j][i]) { + return strs[j].substr(0, i); + } } - else common = common.substr(0, j); } - return common; + return strs[0]; } -}; \ No newline at end of file +}; diff --git a/LongestConsecutiveSequence/LongestConsecutiveSequence.cpp b/LongestConsecutiveSequence/LongestConsecutiveSequence.cpp index 15d8e3e..b51fc95 100644 --- a/LongestConsecutiveSequence/LongestConsecutiveSequence.cpp +++ b/LongestConsecutiveSequence/LongestConsecutiveSequence.cpp @@ -26,3 +26,32 @@ class Solution { return ret; } }; + +// O(n) solution + +class Solution { +public: + int longestConsecutive(vector &num) { + unordered_map longest; + int result = 0; + + for (int i = 0; i < num.size(); i++) { + if (longest[num[i]] != 0) { + continue; + } + + int leftbound = longest[num[i]-1]; + int rightbound = longest[num[i]+1]; + int bound = leftbound + rightbound + 1; + + longest[num[i]] = bound; + longest[num[i]-leftbound] = bound; + longest[num[i]+rightbound] = bound; + + if (result < bound) { + result = bound; + } + } + return result; + } +}; diff --git a/LongestSubstringWithoutRepeatingCharacters/LongestSubstringWithoutRepeatingCharacters.cpp b/LongestSubstringWithoutRepeatingCharacters/LongestSubstringWithoutRepeatingCharacters.cpp index 58fd496..716bf9b 100644 --- a/LongestSubstringWithoutRepeatingCharacters/LongestSubstringWithoutRepeatingCharacters.cpp +++ b/LongestSubstringWithoutRepeatingCharacters/LongestSubstringWithoutRepeatingCharacters.cpp @@ -1,23 +1,18 @@ class Solution { public: int lengthOfLongestSubstring(string s) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - int hash[256]; - memset(hash, -1, sizeof(hash)); - int maxlen = 0, count = 0; - for (int i = 0, j = 0; j < s.size(); j++) { - if (hash[s[j]] == -1) { - hash[s[j]] = j; - maxlen = max(maxlen, j - i + 1); - } else { - while (i <= hash[s[j]]) { - hash[s[i]] = -1; - i += 1; - } - hash[s[j]] = j; + for (int i = 0; i < 256; i++) { + hash[i] = -1; + } + int maxlen = 0; + int start = 0; + for (int limit = 0; limit < s.size(); limit++) { + if (hash[s[limit]] != -1) { + start = max(start, hash[s[limit]] + 1); } + maxlen = max(maxlen, limit - start + 1); + hash[s[limit]] = limit; } return maxlen; } diff --git a/LongestValidParentheses/LongestValidParentheses.cpp b/LongestValidParentheses/LongestValidParentheses.cpp index 38d804a..e667a41 100644 --- a/LongestValidParentheses/LongestValidParentheses.cpp +++ b/LongestValidParentheses/LongestValidParentheses.cpp @@ -12,16 +12,14 @@ class Solution { if (s[i] == '(') { count_left += 1; valid_count += 1; - } - else { + } else { valid_count -= 1; } if (valid_count < 0) { valid_count = 0; count_left = 0; - } - else if (valid_count == 0) { + } else if (valid_count == 0) { max_valid = max(max_valid, count_left); } } @@ -32,19 +30,17 @@ class Solution { if (s[i] == ')') { count_right += 1; valid_count += 1; - } - else { + } else { valid_count -= 1; } if (valid_count < 0) { valid_count = 0; count_right = 0; - } - else if (valid_count == 0) { + } else if (valid_count == 0) { max_valid = max(max_valid, count_right); } } return 2 * max_valid; } -}; \ No newline at end of file +}; diff --git a/MaxPointsOnALine/MaxPointsOnALine.cpp b/MaxPointsOnALine/MaxPointsOnALine.cpp new file mode 100644 index 0000000..c96b9b7 --- /dev/null +++ b/MaxPointsOnALine/MaxPointsOnALine.cpp @@ -0,0 +1,77 @@ +/** + * Definition for a point. + * struct Point { + * int x; + * int y; + * Point() : x(0), y(0) {} + * Point(int a, int b) : x(a), y(b) {} + * }; + */ + +bool operator<(const Point& x, const Point& y) { + if (x.x == y.x) { + return x.y < y.y; + } + return x.x < y.x; +} + +bool operator==(const Point& x, const Point& y) { + if (x.x == y.x && x.y == y.y) { + return true; + } + return false; +} + +class Solution { +public: + int maxPoints(vector &points) { + int n = points.size(); + if (n <= 2) { + return n; + } + int result = 2; + sort(points.begin(), points.end()); + for (int i = 0; i < n; i++) { + vector> slopes; + int count = 0; + for (int j = i + 1; j < n; j++) { + int x = points[i].x - points[j].x; + int y = points[i].y - points[j].y; + int z = gcd(x, y); + if (z != 0) { + x /= z, y /= z; + } + if (x == 0 && y == 0) { + count++; + } else { + slopes.push_back(make_pair(x, y)); + } + } + if (slopes.empty()) { + result = max(result, count + 1); + continue; + } + sort(slopes.begin(), slopes.end()); + int curr = 2 + count; + result = max(result, curr); + for (int j = 1; j < slopes.size(); j++) { + if (slopes[j] == slopes[j-1]) { + curr++; + } else { + curr = 2 + count; + } + result = max(result, curr); + } + } + return result; + } + + int gcd(int a, int b) { + while (b != 0) { + int t = b; + b = a % b; + a = t; + } + return a; + } +}; diff --git a/MaximumProductSubarray/MaximumProductSubarray.cpp b/MaximumProductSubarray/MaximumProductSubarray.cpp new file mode 100644 index 0000000..2aae327 --- /dev/null +++ b/MaximumProductSubarray/MaximumProductSubarray.cpp @@ -0,0 +1,19 @@ +class Solution { +public: + int maxProduct(int A[], int n) { + if (n == 0) { + return 0; + } + int result = A[0]; + int premax = A[0]; + int premin = A[0]; + for (int i = 1; i < n; i++) { + int heremax = max(A[i], max(A[i] * premax, A[i] * premin)); + int heremin = min(A[i], min(A[i] * premax, A[i] * premin)); + result = max(result, heremax); + premax = heremax; + premin = heremin; + } + return result; + } +}; diff --git a/MedianofTwoSortedArrays/MedianofTwoSortedArrays.cpp b/MedianofTwoSortedArrays/MedianofTwoSortedArrays.cpp index 60c43a5..6386fc2 100644 --- a/MedianofTwoSortedArrays/MedianofTwoSortedArrays.cpp +++ b/MedianofTwoSortedArrays/MedianofTwoSortedArrays.cpp @@ -1,34 +1,35 @@ class Solution { public: double findMedianSortedArrays(int A[], int m, int B[], int n) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - if ((m + n) & 1) - return (double)findKth(A, m, B, n, (m+n+1)/2); - else - return (findKth(A, m, B, n, (m+n)/2) + findKth(A, m, B, n, (m+n)/2+1)) / 2.0; - + if ((m + n) & 1) { + return findKth((m + n - 1) / 2, A, 0, m - 1, B, 0, n - 1); + } else { + int x = findKth((m + n) / 2 - 1, A, 0, m - 1, B, 0, n - 1); + int y = findKth((m + n) / 2, A, 0, m - 1, B, 0, n - 1); + return (x + y) / 2.0; + } } - - int findKth(int A[], int m, int B[], int n, int k) { - if (m <= 0) return B[k-1]; - if (n <= 0) return A[k-1]; - if (k <= 1) return min(A[0], B[0]); - - int ans; - if (m/2 + n/2 + 1 >= k) { - if (A[m/2] >= B[n/2]) - ans = findKth(A, m/2, B, n, k); - else - ans = findKth(A, m, B, n/2, k); - } - else { - if (A[m/2] >= B[n/2]) - ans = findKth(A, m, B + n/2 + 1, n - n/2 - 1, k - n/2 - 1); - else - ans = findKth(A + m/2 + 1, m - m/2 - 1, B, n, k - m/2 - 1); + int findKth(int k, int A[], int l1, int r1, int B[], int l2, int r2) { + if (l1 > r1) { + return B[l2 + k]; + } + if (l2 > r2) { + return A[l1 + k]; + } + int m1 = (l1 + r1) / 2; + int m2 = (l2 + r2) / 2; + if (A[m1] > B[m2]) { + if (k + 1 < m1 - l1 + 1 + m2 - l2 + 1) { + return findKth(k, A, l1, m1 - 1, B, l2, r2); + } else { + return findKth(k - (m2 - l2 + 1), A, l1, r1, B, m2 + 1, r2); + } + } else { + if (k + 1 < m1 - l1 + 1 + m2 - l2 + 1) { + return findKth(k, A, l1, r1, B, l2, m2 - 1); + } else { + return findKth(k - (m1 - l1 + 1), A, m1 + 1, r1, B, l2, r2); + } } - return ans; } }; diff --git a/MergeIntervals/MergeIntervals.cpp b/MergeIntervals/MergeIntervals.cpp index ab4748c..698ed8b 100644 --- a/MergeIntervals/MergeIntervals.cpp +++ b/MergeIntervals/MergeIntervals.cpp @@ -7,38 +7,31 @@ * Interval(int s, int e) : start(s), end(e) {} * }; */ - -bool compare(const Interval& lhs, const Interval& rhs) { - if (lhs.start == rhs.start) - return lhs.end < rhs.end; - return lhs.start < rhs.start; + +inline bool operator < (const Interval& x, const Interval& y) { + if (x.start == y.start) { + return x.end < y.end; + } + return x.start < y.start; } class Solution { public: - vector merge(vector& intervals) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - if (intervals.empty()) return vector(); - - sort(intervals.begin(), intervals.end(), compare); - - vector merged_interval; - merged_interval.push_back(intervals[0]); - + vector merge(vector &intervals) { + vector result; + if (intervals.empty()) { + return result; + } + sort(intervals.begin(), intervals.end()); + result.push_back(intervals[0]); for (int i = 1; i < intervals.size(); i++) { - int start = merged_interval[merged_interval.size()-1].start; - int end = merged_interval[merged_interval.size()-1].end; - if (intervals[i].start <= end) { - end = max(end, intervals[i].end); - merged_interval.pop_back(); - merged_interval.push_back(Interval(start, end)); - } - else { - merged_interval.push_back(intervals[i]); + Interval& back = result.back(); + if (back.end >= intervals[i].start) { + back.end = max(back.end, intervals[i].end); + } else { + result.push_back(intervals[i]); } } - return merged_interval; + return result; } -}; \ No newline at end of file +}; diff --git a/MergekSortedLists/MergekSortedLists.cpp b/MergekSortedLists/MergekSortedLists.cpp index 86c41a1..cca30e8 100644 --- a/MergekSortedLists/MergekSortedLists.cpp +++ b/MergekSortedLists/MergekSortedLists.cpp @@ -9,31 +9,41 @@ class Solution { public: ListNode *mergeKLists(vector &lists) { - // Start typing your C/C++ solution below - // DO NOT write int main() function + return merge(lists, 0, lists.size() - 1); + } + ListNode* merge(vector& lists, int left, int right) { + if (left > right) { + return NULL; + } + if (left == right) { + return lists[left]; + } + int mid = (left + right) / 2; + ListNode* l1 = merge(lists, left, mid); + ListNode* l2 = merge(lists, mid + 1, right); - int n = lists.size(); ListNode head(0); - ListNode *node = &head; - - // - // Time complexity O(n*K) - // n stands for the max length of the list in lists - // - while (true) { - int minValue = INT_MAX; - int pos = -1; - for (int i = 0; i < n; i++) { - if (lists[i] != NULL && minValue > lists[i]->val) { - pos = i; - minValue = lists[i]->val; - } + ListNode* curr = &head; + while (l1 && l2) { + if (l1->val < l2->val) { + curr->next = l1; + l1 = l1->next; + } else { + curr->next = l2; + l2 = l2->next; } - if (pos == -1) break; - node->next = lists[pos]; - node = node->next; - lists[pos] = lists[pos]->next; + curr = curr->next; + } + while (l1) { + curr->next = l1; + l1 = l1->next; + curr = curr->next; + } + while (l2) { + curr->next = l2; + l2 = l2->next; + curr = curr->next; } return head.next; } -}; \ No newline at end of file +}; diff --git a/MinimumPathSum/MinimumPathSum.cpp b/MinimumPathSum/MinimumPathSum.cpp index fe67c04..6e2318b 100644 --- a/MinimumPathSum/MinimumPathSum.cpp +++ b/MinimumPathSum/MinimumPathSum.cpp @@ -22,4 +22,32 @@ class Solution { } return dp[m-1][n-1]; } -}; \ No newline at end of file +}; + +// O(n) space +class Solution { +public: + int minPathSum(vector > &grid) { + if (grid.empty()) { + return 0; + } + int m = grid.size(); + int n = grid[0].size(); + vector> dp(2, vector(n, 0)); + int T1 = 1; + int T2 = 0; + for (int i = 0; i < m; i++) { + T1 ^= 1; + T2 ^= 1; + dp[T2][0] = dp[T1][0] + grid[i][0]; + for (int j = 1; j < n; j++) { + if (i == 0) { + dp[T2][j] = dp[T2][j-1] + grid[i][j]; + } else { + dp[T2][j] = grid[i][j] + min(dp[T1][j], dp[T2][j-1]); + } + } + } + return dp[T2][n-1]; + } +}; diff --git a/MinimumWindowSubstring/MinimumWindowSubstring.cpp b/MinimumWindowSubstring/MinimumWindowSubstring.cpp index 445d97f..fe4b8b6 100644 --- a/MinimumWindowSubstring/MinimumWindowSubstring.cpp +++ b/MinimumWindowSubstring/MinimumWindowSubstring.cpp @@ -1,43 +1,39 @@ class Solution { public: string minWindow(string S, string T) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - int needFind[256] = {0}; - int hasFound[256] = {0}; - int count = 0, minLen = INT_MAX; - string result = ""; - - for (int i = 0; i < T.size(); i++) - needFind[T[i]] += 1; - - for (int low = 0, high = 0; high < S.size(); high++) { - if (needFind[S[high]] == 0) + string result(""); + map needed; + map found; + for (int i = 0; i < T.size(); i++) { + needed[T[i]]++; + } + int count = 0; + int minlen = S.size() + 1; + for (int i = 0, j = 0; j < S.size(); j++) { + if (needed[S[j]] == 0) { continue; - - hasFound[S[high]] += 1; - if (hasFound[S[high]] <= needFind[S[high]]) - count += 1; - + } + found[S[j]]++; + if (found[S[j]] <= needed[S[j]]) { + count++; + } if (count == T.size()) { - while (low < high) { - if (needFind[S[low]] == 0) { - low += 1; - continue; - } - if (hasFound[S[low]] > needFind[S[low]]) - hasFound[S[low]] -= 1; - else + while (i <= j) { + if (found[S[i]] == 0) { + i++; + } else if (found[S[i]] > needed[S[i]]) { + found[S[i]]--; + i++; + } else { break; - low += 1; + } } - if (minLen > high - low + 1) { - minLen = high - low + 1; - result = S.substr(low, minLen); + if (minlen > j - i + 1) { + minlen = j - i + 1; + result = S.substr(i, minlen); } } } return result; } -}; \ No newline at end of file +}; diff --git a/N-Queens/N-Queens.cpp b/N-Queens/N-Queens.cpp index a5dde37..ba3d72e 100644 --- a/N-Queens/N-Queens.cpp +++ b/N-Queens/N-Queens.cpp @@ -1,51 +1,35 @@ class Solution { public: - vector> solveNQueens(int n) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - string row(n, '.'); - vector queens(n, row); - - vector visited_col(n, false); - vector visited_slope1(2*n-1, false); - vector visited_slope2(2*n-1, false); - vector> visited; - visited.push_back(visited_col); - visited.push_back(visited_slope1); - visited.push_back(visited_slope2); - + vector > solveNQueens(int n) { vector> result; - - generateNQueens(queens, visited, 0, n, result); + if (n == 0) { + return result; + } + vector sol(n, string(n, '.')); + vector> visited(3, vector(2*n, false)); + dfs(result, sol, visited, 0); return result; } - void generateNQueens(vector& queens, vector>& visited, - int row, int n, vector>& result) { - + void dfs(vector>& result, vector& sol, vector>& visited, int row) { + int n = sol.size(); if (row == n) { - result.push_back(queens); + result.push_back(sol); return; } - for (int col = 0; col < n; col++) { - if (visited[0][col] == false && - visited[1][row+col] == false && - visited[2][n-1-col+row] == false) { - - queens[row][col] = 'Q'; - visited[0][col] = true; - visited[1][row+col] = true; - visited[2][n-1-col+row] = true; - - generateNQueens(queens, visited, row + 1, n, result); - - queens[row][col] = '.'; - visited[0][col] = false; - visited[1][row+col] = false; - visited[2][n-1-col+row] = false; + if (visited[0][col] || visited[1][row+col] || visited[2][n-1-row+col]) { + continue; } + visited[0][col] = true; + visited[1][row+col] = true; + visited[2][n-1-row+col] = true; + sol[row][col] = 'Q'; + dfs(result, sol, visited, row + 1); + sol[row][col] = '.'; + visited[0][col] = false; + visited[1][row+col] = false; + visited[2][n-1-row+col] = false; } } -}; \ No newline at end of file +}; diff --git a/N-QueensII/N-QueensII.cpp b/N-QueensII/N-QueensII.cpp index 20a1c9d..04a5040 100644 --- a/N-QueensII/N-QueensII.cpp +++ b/N-QueensII/N-QueensII.cpp @@ -1,27 +1,22 @@ class Solution { public: - int queens; - int mask; int totalNQueens(int n) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - mask = (1 << n) - 1; - queens = 0; - totalNQueensHelper(0, 0, 0); - return queens; + int result = 0; + dfs(result, n, 0, 0, 0); + return result; } - void totalNQueensHelper(int col, int ld, int rd) { - if (col != mask) { - int valid_pos = mask & (~(col | ld | rd)); - while (valid_pos) { - int p = valid_pos & (-valid_pos); - valid_pos -= p; - totalNQueensHelper(col + p, (ld + p) << 1, (rd + p) >> 1); + void dfs(int& result, int n, int col, int l, int r) { + int mask = (1 << n) - 1; + if (col == mask) { + result++; + } else { + int valid = mask & (~(col | l | r)); + while (valid) { + int p = valid & (-valid); + valid -= p; + dfs(result, n, col + p, (l + p) << 1, (r + p) >> 1); } } - else - queens += 1; } -}; \ No newline at end of file +}; diff --git a/NextPermutation/NextPermutation.cpp b/NextPermutation/NextPermutation.cpp index 03837e9..5c162e5 100644 --- a/NextPermutation/NextPermutation.cpp +++ b/NextPermutation/NextPermutation.cpp @@ -1,34 +1,20 @@ class Solution { public: - void nextPermutation(vector& num) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - int n = num.size(); - if (n <= 1) return; - - bool found = false; - int i, p, maxval = INT_MIN; - for (i = n - 1; i >= 1; i--) { - if (maxval < num[i]) { - maxval = num[i]; - } - if (num[i-1] < maxval) { - int delta = INT_MAX; - for (int j = i; j < n; j++) { - if (num[j] > num[i-1] && num[j] - num[i-1] < delta) - p = j; - } - found = true; - break; - } + void nextPermutation(vector &num) { + int i = num.size() - 1; + while (i >= 1 && num[i-1] >= num[i]) { + i--; } - if (!found) { + if (i == 0) { reverse(num.begin(), num.end()); + return; } - else { - swap(num[p], num[i-1]); - sort(num.begin() + i, num.end()); + for (int j = num.size() - 1; j >= i; j--) { + if (num[j] > num[i-1]) { + swap(num[j], num[i-1]); + break; + } } + reverse(num.begin() + i, num.end()); } -}; \ No newline at end of file +}; diff --git a/Pascal'sTriangle/Pascal'sTriangle.cpp b/Pascal'sTriangle/Pascal'sTriangle.cpp index 9707d30..7dfef2c 100644 --- a/Pascal'sTriangle/Pascal'sTriangle.cpp +++ b/Pascal'sTriangle/Pascal'sTriangle.cpp @@ -1,23 +1,20 @@ class Solution { public: vector > generate(int numRows) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - vector> triangle(numRows); - - if (numRows == 0) + vector> triangle; + if (numRows == 0) { return triangle; - - triangle[0].push_back(1); - + } + triangle.push_back(vector(1, 1)); for (int i = 1; i < numRows; i++) { - triangle[i].push_back(1); - for (int j = 1; j < i; j++) { - triangle[i].push_back(triangle[i-1][j-1] + triangle[i-1][j]); + vector& prev = triangle.back(); + vector row(i + 1, 0); + row[0] = row[i] = 1; + for (int j = 0; j < i - 1; j++) { + row[j+1] = prev[j] + prev[j+1]; } - triangle[i].push_back(1); + triangle.push_back(row); } - return move(triangle); + return triangle; } }; diff --git a/PermutationsII/PermutationsII.cpp b/PermutationsII/PermutationsII.cpp index 65f512e..468dd6b 100644 --- a/PermutationsII/PermutationsII.cpp +++ b/PermutationsII/PermutationsII.cpp @@ -1,40 +1,61 @@ class Solution { public: - vector> permuteUnique(vector& num) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - + vector > permuteUnique(vector &num) { vector> result; - + sort(num.begin(), num.end()); do { result.push_back(num); - nextPermutation(num); - } while (!isEqual(result[0], num)); - - return move(result); + } while (getNext(num)); + return result; } - bool isEqual(vector& n1, vector& n2) { - if (n1.size() != n2.size()) + bool getNext(vector& num) { + int i = num.size() - 1; + while (i >= 1 && num[i-1] >= num[i]) { + i--; + } + if (i == 0) { return false; - for (int i = 0; i < n1.size(); i++) { - if (n1[i] != n2[i]) return false; } + int j = num.size() - 1; + while (j >= i) { + if (num[j] > num[i-1]) { + break; + } + j--; + } + swap(num[i-1], num[j]); + reverse(num.begin() + i, num.end()); return true; } - - void nextPermutation(vector& num) { - int lf = num.size() - 2; - while (lf >= 0 && num[lf] >= num[lf+1]) - lf -= 1; - if (lf == -1) { - reverse(num.begin(), num.end()); +}; + +// recursive solution +class Solution { +public: + void helper(vector>& result, vector& num, int x) { + if (x == num.size()) { + result.push_back(num); return; } - int rt = num.size() - 1; - while (rt > lf && num[rt] <= num[lf]) - rt -= 1; - swap(num[lf], num[rt]); - reverse(num.begin() + lf + 1, num.end()); + helper(result, num, x + 1); + map hash; + hash[num[x]] = true; + for (int i = x + 1; i < num.size(); i++) { + if (hash[num[i]]) { + continue; + } + hash[num[i]] = true; + swap(num[x], num[i]); + helper(result, num, x + 1); + swap(num[x], num[i]); + } + } + + vector > permuteUnique(vector &num) { + sort(num.begin(), num.end()); + vector> result; + helper(result, num, 0); + return move(result); } -}; \ No newline at end of file +}; diff --git a/PopulatingNextRightPointersinEachNode/PopulatingNextRightPointersinEachNode.cpp b/PopulatingNextRightPointersinEachNode/PopulatingNextRightPointersinEachNode.cpp index a6628a5..fc155bf 100644 --- a/PopulatingNextRightPointersinEachNode/PopulatingNextRightPointersinEachNode.cpp +++ b/PopulatingNextRightPointersinEachNode/PopulatingNextRightPointersinEachNode.cpp @@ -9,26 +9,19 @@ class Solution { public: void connect(TreeLinkNode *root) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - TreeLinkNode *link_head = root; - TreeLinkNode *next_link_head = NULL; - - while (link_head) { - if (link_head->left == NULL) - break; - next_link_head = link_head->left; - next_link_head->next = link_head->right; - TreeLinkNode *link_node = link_head; - TreeLinkNode *next_link_node = link_head->right; - while (link_node->next) { - next_link_node->next = link_node->next->left; - next_link_node->next->next = link_node->next->right; - next_link_node = link_node->next->right; - link_node = link_node->next; + if (root == NULL) { + return; + } + while (root->left) { + TreeLinkNode* node = root; + while (node) { + node->left->next = node->right; + if (node->next) { + node->right->next = node->next->left; + } + node = node->next; } - link_head = next_link_head; + root = root->left; } } -}; \ No newline at end of file +}; diff --git a/PopulatingNextRightPointersinEachNodeII/PopulatingNextRightPointersinEachNodeII.cpp b/PopulatingNextRightPointersinEachNodeII/PopulatingNextRightPointersinEachNodeII.cpp index fd2de8e..55e6f51 100644 --- a/PopulatingNextRightPointersinEachNodeII/PopulatingNextRightPointersinEachNodeII.cpp +++ b/PopulatingNextRightPointersinEachNodeII/PopulatingNextRightPointersinEachNodeII.cpp @@ -9,48 +9,39 @@ class Solution { public: void connect(TreeLinkNode *root) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - TreeLinkNode *link_head = root; - - while (link_head) { - TreeLinkNode *next_link_head = NULL; - TreeLinkNode *next_link_node = NULL; - - while (link_head) { - if (link_head->left) { - next_link_head = link_head->left; - next_link_node = next_link_head; - } - if (link_head->right) { - if (next_link_node) { - next_link_node->next = link_head->right; - next_link_node = next_link_node->next; + if (root == NULL) { + return; + } + TreeLinkNode* leftmost = root; + while (leftmost) { + TreeLinkNode* node = leftmost; + TreeLinkNode* prev = NULL; + leftmost = NULL; + while (node) { + if (node->left) { + if (leftmost == NULL) { + leftmost = node->left; } - else { - next_link_head = link_head->right; - next_link_node = next_link_head; + if (prev == NULL) { + prev = node->left; + } else { + prev->next = node->left; + prev = node->left; } } - if (next_link_head) break; - link_head = link_head->next; - } - if (next_link_head == NULL) break; - - while (link_head->next) { - if (link_head->next->left) { - next_link_node->next = link_head->next->left; - next_link_node = next_link_node->next; - } - if (link_head->next->right) { - next_link_node->next = link_head->next->right; - next_link_node = next_link_node->next; + if (node->right) { + if (leftmost == NULL) { + leftmost = node->right; + } + if (prev == NULL) { + prev = node->right; + } else { + prev->next = node->right; + prev = node->right; + } } - link_head = link_head->next; + node = node->next; } - link_head = next_link_head; } } }; - diff --git a/README.md b/README.md index ff3686f..8983ad5 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,19 @@ -leetcode +leetcode [![Total views](https://sourcegraph.com/api/repos/github.com/kedebug/leetcode/counters/views.png)](https://sourcegraph.com/github.com/kedebug/leetcode) ============ Solution set for LeetCode. + + The commit message of each problem stands for it's difficulty index, which means: - 1 Easy - 2 Normal - 3 Medium - 4 Hard -- 5 More Harder +- 5 Much Harder + +If you have found any method to optimize those solutions, please feel free to get in touch via kedebug0@gmail.com. -If you have found any method to optimize those solutions, please feel free to get in touch via sunweiqq@gmail.com. +LICENSE +============= +No LICENSE, you can use it for any purpose. diff --git a/RecoverBinarySearchTree/RecoverBinarySearchTree.cpp b/RecoverBinarySearchTree/RecoverBinarySearchTree.cpp index ea6a0fb..a1e0736 100644 --- a/RecoverBinarySearchTree/RecoverBinarySearchTree.cpp +++ b/RecoverBinarySearchTree/RecoverBinarySearchTree.cpp @@ -1,56 +1,44 @@ -/** - * Definition for binary tree - * struct TreeNode { - * int val; - * TreeNode *left; - * TreeNode *right; - * TreeNode(int x) : val(x), left(NULL), right(NULL) {} - * }; - */ +// O(n) time, O(1) space class Solution { public: void recoverTree(TreeNode *root) { - // Start typing your C/C++ solution below - // DO NOT write int main() function + TreeNode* node = root; + TreeNode* prev = NULL; + TreeNode* prev1 = NULL; + TreeNode* curr1 = NULL; + TreeNode* prev2 = NULL; + TreeNode* curr2 = NULL; - TreeNode *parent = NULL; - TreeNode *current = root; - TreeNode *mistake_node1 = NULL; - TreeNode *mistake_node2 = NULL; - - while (current != NULL) { - if (current->left == NULL) { - if (parent && parent->val > current->val) { - if (mistake_node1 == NULL) - mistake_node1 = parent; - mistake_node2 = current; + while (node != NULL) { + if (node->left == NULL) { + prev = node; + node = node->right; + } else { + TreeNode* next = node->left; + while (next->right && next->right != node) { + next = next->right; } - parent = current; - current = current->right; - } - else { - TreeNode *prev = current->left; - while (prev->right && prev->right != current) - prev = prev->right; - - if (prev->right == NULL) { - prev->right = current; - current = current->left; + if (next->right == NULL) { + next->right = node; + node = node->left; + } else { + prev = node; + node = node->right; + next->right = NULL; } - else { - if (parent->val > current->val) { - if (mistake_node1 == NULL) - mistake_node1 = parent; - mistake_node2 = current; - } - prev->right = NULL; - parent = current; - current = current->right; + } + if (prev && node && prev->val > node->val) { + if (prev1 == NULL) { + prev1 = prev, curr1 = node; + } else { + prev2 = prev, curr2 = node; } } } - if (mistake_node1 && mistake_node2) - swap(mistake_node1->val, mistake_node2->val); + if (prev1 && curr2) { + swap(prev1->val, curr2->val); + } else { + swap(prev1->val, curr1->val); + } } }; -// http://fisherlei.blogspot.com/2012/12/leetcode-recover-binary-search-tree.html \ No newline at end of file diff --git a/RemoveDuplicatesfromSortedList/RemoveDuplicatesfromSortedList.cpp b/RemoveDuplicatesfromSortedList/RemoveDuplicatesfromSortedList.cpp index d19d311..e720efe 100644 --- a/RemoveDuplicatesfromSortedList/RemoveDuplicatesfromSortedList.cpp +++ b/RemoveDuplicatesfromSortedList/RemoveDuplicatesfromSortedList.cpp @@ -9,28 +9,19 @@ class Solution { public: ListNode *deleteDuplicates(ListNode *head) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - if (head == NULL) + if (head == NULL) { return NULL; - - ListNode *prev = head; - ListNode *node = head->next; - - while (node != NULL) { - if (node->val == prev->val) { - ListNode *dele = node; - prev->next = NULL; - node = node->next; - delete dele; - } - else { - prev->next = node; + } + ListNode* prev = head; + ListNode* curr = head->next; + while (curr) { + if (prev->val != curr->val) { + prev->next = curr; prev = prev->next; - node = node->next; } + curr = curr->next; } + prev->next = NULL; return head; } -}; \ No newline at end of file +}; diff --git a/RemoveDuplicatesfromSortedListII/RemoveDuplicatesfromSortedListII.cpp b/RemoveDuplicatesfromSortedListII/RemoveDuplicatesfromSortedListII.cpp index d6a0409..3b6df22 100644 --- a/RemoveDuplicatesfromSortedListII/RemoveDuplicatesfromSortedListII.cpp +++ b/RemoveDuplicatesfromSortedListII/RemoveDuplicatesfromSortedListII.cpp @@ -9,48 +9,23 @@ class Solution { public: ListNode *deleteDuplicates(ListNode *head) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - if (head == NULL) - return head; - - ListNode preHead(0); - preHead.next = head; - - ListNode *preprev = &preHead; - ListNode *prev = head; - ListNode *node = head->next; - bool flag = false; - - while (node != NULL) { - if (prev->val == node->val) { - ListNode *del = node; - node = node->next; - flag = true; - delete del; - } - else { - if (flag) { - flag = false; - preprev->next = node; - prev = node; - node = node->next; - } - else { - preprev = prev; - prev = node; - node = node->next; + ListNode prevhead(0); + ListNode* prev = &prevhead; + ListNode* curr = head; + while (curr) { + if (curr->next && curr->val == curr->next->val) { + ListNode* next = curr->next; + while (next && next->val == curr->val) { + next = next->next; } + curr = next; + } else { + prev->next = curr; + prev = prev->next; + curr = curr->next; } } - if (flag) { - preprev->next = NULL; - delete prev; - } - - return preHead.next; + prev->next = NULL; + return prevhead.next; } }; - -// Accepted after my first commit, yeah. \ No newline at end of file diff --git a/RestoreIPAddresses/RestoreIPAddresses.cpp b/RestoreIPAddresses/RestoreIPAddresses.cpp index e4cadce..979c383 100644 --- a/RestoreIPAddresses/RestoreIPAddresses.cpp +++ b/RestoreIPAddresses/RestoreIPAddresses.cpp @@ -1,44 +1,40 @@ class Solution { public: vector restoreIpAddresses(string s) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - vector addresses; - string ip_address; - restoreIpAddressesHelper(s, 0, 0, ip_address, addresses); - return addresses; + vector result; + vector sk; + dfs(result, sk, s, 0, 0); + return result; } - void restoreIpAddressesHelper(string& s, int position, - int blocks, string& ip_address, vector& addresses) { - - if (position == s.size() && blocks == 4) { - addresses.push_back(ip_address); + void dfs(vector& result, vector& sk, const string& s, int val, int pos) { + if (sk.size() > 4) { return; } - - // some pruning skills; - if (blocks >= 4) return; - if ((4-blocks) * 3 < s.size() - position) return; - if ((4-blocks) * 3 == s.size() - position) { - for (int i = 0; i < 4 - blocks; i += 3) - if (s[position + i] > '2') return; + + if (pos == s.size()) { + if (sk.size() < 4 || val != 0) { + return; + } + string ip; + ip += to_string(sk[0]); + for (int i = 1; i < 4; i++) { + ip += "."; + ip += to_string(sk[i]); + } + result.push_back(ip); + return; } - int ip = 0; - int ip_length = ip_address.size(); - for (int i = position; i < s.size(); i++) { - ip *= 10; - ip += s[i] - '0'; - if (ip > 255) break; - if (blocks != 0 && i == position) - ip_address += '.'; - ip_address += s[i]; - restoreIpAddressesHelper(s, i + 1, blocks + 1, ip_address, addresses); - if (ip == 0) break; + val = val * 10 + s[pos] - '0'; + if (val > 255) { + return; + } + if (val != 0) { + dfs(result, sk, s, val, pos + 1); } - // pass-by-reference is more effective than pass-by-value - ip_address.erase(ip_length, ip_address.size() - ip_length); + sk.push_back(val); + dfs(result, sk, s, 0, pos + 1); + sk.pop_back(); } -}; \ No newline at end of file +}; diff --git a/ReverseNodesink-Group/ReverseNodesink-Group.cpp b/ReverseNodesink-Group/ReverseNodesink-Group.cpp index 3b82908..dfa4eb3 100644 --- a/ReverseNodesink-Group/ReverseNodesink-Group.cpp +++ b/ReverseNodesink-Group/ReverseNodesink-Group.cpp @@ -9,53 +9,52 @@ class Solution { public: ListNode *reverseKGroup(ListNode *head, int k) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - // - // only travel the list for one time - // - - ListNode node(0); - node.next = head; - ListNode *slow = head; - ListNode *fast = &node; - - for (int i = 0; i < k; i++) { - if (fast && fast->next) fast = fast->next; - else return head; + ListNode* node = head; + int len = 0; + while (node) { + len++; + node = node->next; + } + if (k > len) { + return head; } - bool kRemaind = true; - bool getHead = false; - ListNode *newHead = NULL; + ListNode prevhead(0); + prevhead.next = head; - while (kRemaind) { - ListNode *tail = slow; - ListNode *prev = NULL; - ListNode *next = NULL; - - for (int i = 0; i < k; i++) { - next = slow->next; - slow->next = prev; - prev = slow; - slow = next; - - if (fast && fast->next) - fast = fast->next; - else - kRemaind = false; + ListNode* curr = head; + ListNode* prev = &prevhead; + + while (curr) { + int count = k - 1; + ListNode* last = curr; + while (count && last) { + count--; + last = last->next; } - if (kRemaind) - tail->next = fast; - else - tail->next = slow; - - if (!getHead) { - newHead = prev; - getHead = true; + if (count == 0 && last) { + ListNode* next = last->next; + last->next = NULL; + ListNode* l = reverse(curr); + curr->next = next; + prev->next = l; + prev = curr; + curr = next; + } else { + break; } } - return newHead; + return prevhead.next; + } + + ListNode* reverse(ListNode* head) { + ListNode prevhead(0); + while (head) { + ListNode* next = head->next; + head->next = prevhead.next; + prevhead.next = head; + head = next; + } + return prevhead.next; } -}; \ No newline at end of file +}; diff --git a/ReverseWordsInAString/ReverseWordsInAString.cpp b/ReverseWordsInAString/ReverseWordsInAString.cpp new file mode 100644 index 0000000..3a0135f --- /dev/null +++ b/ReverseWordsInAString/ReverseWordsInAString.cpp @@ -0,0 +1,66 @@ +class Solution { +public: + void reverseWords(string &s) { + int i = 0; + int j = s.size() - 1; + + while (i < s.size() && s[i] == ' ') { + i++; + } + while (j >= 0 && s[j] == ' ') { + j--; + } + + s = s.substr(i, j - i + 1); + reverse(s, 0, s.size() - 1); + + for (i = 0, j = 0; j < s.size(); j++) { + if (s[j] == ' ') { + s[i++] = ' '; + while (j+1 < s.size() && s[j+1] == ' ') { + j++; + } + } else { + s[i++] = s[j]; + } + } + s = s.substr(0, i); + for (i = 0, j = 0; j < s.size(); j++) { + if (s[j] == ' ') { + reverse(s, i, j - 1); + i = j + 1; + } + } + + if (i < s.size()) { + reverse(s, i, s.size() - 1); + } + } + + void reverse(string& s, int i, int j) { + while (i < j) { + swap(s[i], s[j]); + i++; + j--; + } + } +}; + +// solution 2 +class Solution { +public: + void reverseWords(string &s) { + string result; + for (int i = 0, start = 0; i < s.size(); i++) { + if (s[i] == ' ') { + if (i > start) { + result = s.substr(start, i - start) + " " + result; + } + start = i + 1; + } else if (i == s.size() - 1) { + result = s.substr(start, i + 1 - start) + " " + result; + } + } + s = result.substr(0, result.size() - 1); + } +}; diff --git a/SortColors/SortColors.cpp b/SortColors/SortColors.cpp index 0eac31f..d2c3e9a 100644 --- a/SortColors/SortColors.cpp +++ b/SortColors/SortColors.cpp @@ -1,24 +1,19 @@ - class Solution { public: void sortColors(int A[], int n) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - int low = 0, high = n - 1; - int mid = 0; - - while (mid <= high) { - if (A[mid] == 0) { - A[mid++] = A[low]; - A[low++] = 0; - } - else if (A[mid] == 1) { - mid += 1; - } - else if (A[mid] == 2) { - A[mid] = A[high]; - A[high--] = 2; + int p0 = -1; + int p1 = 0; + int p2 = n; + while (p1 < p2) { + if (A[p1] == 1) { + p1++; + } else if (A[p1] == 0) { + swap(A[p0+1], A[p1]); + p0++; + p1++; + } else { + swap(A[p1], A[p2-1]); + p2--; } } } @@ -46,4 +41,4 @@ class Solution2 { } return i; } -}; \ No newline at end of file +}; diff --git a/SortList/SortList.cc b/SortList/SortList.cc new file mode 100644 index 0000000..e892e8d --- /dev/null +++ b/SortList/SortList.cc @@ -0,0 +1,70 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode(int x) : val(x), next(NULL) {} + * }; + */ +class Solution { +public: + ListNode *sortList(ListNode *head) { + if (head == NULL || head->next == NULL) { + return head; + } + + ListNode new_head(0); + new_head.next = head; + + ListNode* one = &new_head; + ListNode* two = &new_head; + + while (two && two->next) { + one = one->next; + two = two->next->next; + } + + ListNode* node = one->next; + one->next = NULL; + ListNode* left = sortList(new_head.next); + ListNode* right = sortList(node); + + + ListNode* sorted_head = NULL; + ListNode* sorted_curr = NULL; + + if (left->val < right->val) { + sorted_head = sorted_curr = left; + left = left->next; + } else { + sorted_head = sorted_curr = right; + right = right->next; + } + + while (left && right) { + if (left->val < right->val) { + sorted_curr->next = left; + sorted_curr = left; + left = left->next; + } else { + sorted_curr->next = right; + sorted_curr = right; + right = right->next; + } + } + + while (left) { + sorted_curr->next = left; + sorted_curr = left; + left = left->next; + } + while (right) { + sorted_curr->next = right; + sorted_curr = right; + right = right->next; + } + + sorted_curr->next = NULL; + return sorted_head; + } +}; diff --git a/SpiralMatrix/SpiralMatrix.cpp b/SpiralMatrix/SpiralMatrix.cpp index ff840ca..c1e9f95 100644 --- a/SpiralMatrix/SpiralMatrix.cpp +++ b/SpiralMatrix/SpiralMatrix.cpp @@ -1,46 +1,41 @@ - -const int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; // right, down, left, up - class Solution { public: - vector spiralOrder(vector > &matrix) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - int M = matrix.size(); - if (M == 0) return vector(); - int N = matrix[0].size(); - if (N == 0) return vector(); - - vector result(M * N, 0); - int x = 0, y = -1; - int row = M, col = N + 1; - bool go_horizon = true; - int i = 0, k = 0; - while (i < M * N) { + vector spiralOrder(vector > &matrix) { + vector result; + if (matrix.empty()) { + return result; + } + int row = matrix.size(); + int col = matrix[0].size() + 1; + int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; + int x = 0; + int y = -1; + int k = 0; + int count = 0; + bool horizon = true; + while (count < matrix.size() * matrix[0].size()) { int dx = dir[k%4][0]; int dy = dir[k%4][1]; - k += 1; + k++; - if (go_horizon) { - go_horizon = false; - col -= 1; - for (int j = 0; j < col; j++, i++) { + if (horizon) { + horizon = false; + col--; + for (int i = 0; i < col; i++, count++) { x += dx; y += dy; - result[i] = matrix[x][y]; + result.push_back(matrix[x][y]); } - } - else { - go_horizon = true; - row -= 1; - for (int j = 0; j < row; j++, i++) { + } else { + horizon = true; + row--; + for (int i = 0; i < row; i++, count++) { x += dx; y += dy; - result[i] = matrix[x][y]; + result.push_back(matrix[x][y]); } } } return result; - } -}; \ No newline at end of file + } +}; diff --git a/SpiralMatrixII/SpiralMatrixII.cpp b/SpiralMatrixII/SpiralMatrixII.cpp index 375181e..2439774 100644 --- a/SpiralMatrixII/SpiralMatrixII.cpp +++ b/SpiralMatrixII/SpiralMatrixII.cpp @@ -1,44 +1,39 @@ - -const int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; // right, down, left, up - class Solution { public: vector > generateMatrix(int n) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - if (n == 0) return vector>(); - vector> matrix(n, vector(n, 0)); - - int x = 0, y = -1; - int row = n, col = n + 1; - bool go_horizon = true; - int i = 1, k = 0; - while (i <= n * n) { + int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; + int x = 0; + int y = -1; + int k = 0; + int count = 0; + int horizon = true; + int row = n; + int col = n + 1; + while (count < n * n) { int dx = dir[k%4][0]; int dy = dir[k%4][1]; - k += 1; - - if (go_horizon) { - go_horizon = false; - col -= 1; - for (int j = 0; j < col; j++, i++) { + k++; + if (horizon) { + horizon = false; + col--; + for (int i = 0; i < col; i++) { x += dx; y += dy; - matrix[x][y] = i; + count++; + matrix[x][y] = count; } - } - else { - go_horizon = true; - row -= 1; - for (int j = 0; j < row; j++, i++) { + } else { + horizon = true; + row--; + for (int i = 0; i < row; i++) { x += dx; y += dy; - matrix[x][y] = i; + count++; + matrix[x][y] = count; } } } - return move(matrix); + return matrix; } -}; \ No newline at end of file +}; diff --git a/SubstringwithConcatenationofAllWords/SubstringwithConcatenationofAllWords.cpp b/SubstringwithConcatenationofAllWords/SubstringwithConcatenationofAllWords.cpp index 7296ec5..2285e83 100644 --- a/SubstringwithConcatenationofAllWords/SubstringwithConcatenationofAllWords.cpp +++ b/SubstringwithConcatenationofAllWords/SubstringwithConcatenationofAllWords.cpp @@ -1,77 +1,34 @@ class Solution { public: - // 1612ms vector findSubstring(string S, vector &L) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - int M = L.size(); - int N = L[0].size(); - - vector indices; - if (S.size() < M * N) return indices; - - map words_dict; - for (int i = 0; i < M; i++) - words_dict[L[i]] += 1; - - for (int i = 0; i <= S.size() - M*N; i++) { - map has_found; - bool flag = true; - for (int j = 0; j < M; j++) { - string sub_string = S.substr(i + j * N, N); - if (words_dict.find(sub_string) == words_dict.end()) { - flag = false; break; - } - has_found[sub_string] += 1; - if (has_found[sub_string] > words_dict[sub_string]) { - flag = false; break; - } - } - if (flag) indices.push_back(i); + vector result; + if (L.empty()) { + return result; } - return indices; - } -}; - -// -// Solution2 : 1356ms -// -class Solution { -public: - vector findSubstring(string S, vector &L) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - int M = L.size(); - int N = L[0].size(); - - vector indices; - if (S.size() < M * N) return indices; - - map words_dict; - for (int i = 0; i < M; i++) - words_dict[L[i]] += 1; - - for (int i = 0; i < N; i++) { - vector substrings; - for (int j = i; j + N <= S.size(); j += N) - substrings.push_back(S.substr(j, N)); - for (int j = 0; j + M <= substrings.size(); j++) { - map has_found; - bool flag = true; - for (int k = 0; k < M; k++) { - if (words_dict.find(substrings[j+k]) == words_dict.end()) { - flag = false; break; + int n = L.size(); + int len = L[0].size(); + map hash; + for (int i = 0; i < n; i++) { + hash[L[i]] += 1; + } + for (int i = 0; i < len; i++) { + vector slices; + for (int j = i; j + len <= S.size(); j += len) { + slices.push_back(S.substr(j, len)); + } + for (int j = 0; j + n <= slices.size(); j++) { + map found; + for (int k = 0; k < n; k++) { + found[slices[j+k]] += 1; + if (found[slices[j+k]] > hash[slices[j+k]]) { + break; } - has_found[substrings[j+k]] += 1; - if (has_found[substrings[j+k]] > words_dict[substrings[j+k]]) { - flag = false; break; + if (k == n - 1) { + result.push_back(i + j * len); } } - if (flag) indices.push_back(i + j * N); } } - return indices; + return result; } -}; \ No newline at end of file +}; diff --git a/TrappingRainWater/TrappingRainWater.cpp b/TrappingRainWater/TrappingRainWater.cpp index 45b941c..b7486dd 100644 --- a/TrappingRainWater/TrappingRainWater.cpp +++ b/TrappingRainWater/TrappingRainWater.cpp @@ -1,3 +1,4 @@ +// O(n) time, O(n) space class Solution { public: int trap(int A[], int n) { @@ -23,4 +24,35 @@ class Solution { } return water; } -}; \ No newline at end of file +}; + +// O(n) time, O(1) space +class Solution { +public: + int trap(int A[], int n) { + int maxh = 0; + int water = 0; + int temp = 0; + for (int i = 0; i < n; i++) { + if (A[i] <= maxh) { + temp += maxh - A[i]; + } else { + maxh = A[i]; + water += temp; + temp = 0; + } + } + maxh = 0; + temp = 0; + for (int i = n - 1; i >= 0; i--) { + if (A[i] < maxh) { + temp += maxh - A[i]; + } else { + maxh = A[i]; + water += temp; + temp = 0; + } + } + return water; + } +}; diff --git a/Triangle/Triangle.cpp b/Triangle/Triangle.cpp index f35c9a1..3764a85 100644 --- a/Triangle/Triangle.cpp +++ b/Triangle/Triangle.cpp @@ -1,31 +1,13 @@ class Solution { public: int minimumTotal(vector > &triangle) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - if (triangle.empty()) return 0; - - vector dp[2]; - - dp[0].resize(triangle.size()); - dp[1].resize(triangle.size()); - dp[0][0] = triangle[0][0]; - - int T1 = 1, T2 = 0; - for (size_t i = 1; i < triangle.size(); i++) { - T1 ^= 1, T2 ^= 1; - dp[T2][0] = dp[T1][0] + triangle[i][0]; - for (size_t j = 1; j <= i-1; j++) { - dp[T2][j] = min(dp[T1][j-1], dp[T1][j]) + triangle[i][j]; + int level = triangle.size(); + vector dp(level + 1, 0); + for (int i = level - 1; i >= 0; i--) { + for (int j = 0; j <= i; j++) { + dp[j] = triangle[i][j] + min(dp[j], dp[j+1]); } - dp[T2][i] = dp[T1][i-1] + triangle[i][i]; } - - int result = 0x3FFFFFFF; - for (size_t i = 0; i < dp[T2].size(); i++) { - result = min(result, dp[T2][i]); - } - return result; + return dp[0]; } }; diff --git a/ValidNumber/ValidNumber.cpp b/ValidNumber/ValidNumber.cpp index f97c5ad..2e8ffd6 100644 --- a/ValidNumber/ValidNumber.cpp +++ b/ValidNumber/ValidNumber.cpp @@ -1,43 +1,74 @@ +// NFA class Solution { public: + bool accept(const char* s, int& i, string expected) { + for (int j = 0; j < expected.size(); j++) { + if (s[i] == expected[j]) { + i += 1; + return true; + } + } + return false; + } + + bool acceptRun(const char* s, int& i, string expected) { + bool found = false; + int count = 0; + while (s[i] != '\0') { + found = false; + for (int j = 0; j < expected.size(); j++) { + if (s[i] == expected[j]) { + i++; + count++; + found = true; + } + } + if (!found) { + break; + } + } + if (count > 0) { + return true; + } + return false; + } + bool isNumber(const char *s) { - // Start typing your C/C++ solution below - // DO NOT write int main() function + string digits("0123456789"); - while (*s != '\0' && *s == ' ') s += 1; - if (*s == '\0') return false; + int i = 0; - const char *e = s + strlen(s) - 1; - while (s <= e && *e == ' ') e -= 1; + acceptRun(s, i, " "); - bool is_digit = false; - bool has_dot = false; - bool has_exp = false; + bool beforedot = false; + bool afterdot = false; - if (*s == '+' || *s == '-') s += 1; + accept(s, i, "+-"); + beforedot = acceptRun(s, i, digits); - while (s <= e) { - if ('0' <= *s && *s <= '9') { - is_digit = true; - } - else if (*s == '.') { - if (has_dot || has_exp) - return false; - has_dot = true; + if (accept(s, i, ".")) { + if (acceptRun(s, i, digits)) { + afterdot = true; } - else if (*s == 'e') { - if (!is_digit || has_exp) - return false; - has_exp = true; - is_digit = false; + } + + if (!beforedot && !afterdot) { + return false; + } + + if (accept(s, i, "eE")) { + accept(s, i, "+-"); + if (!acceptRun(s, i, digits)) { + return false; } - else if (*s == '+' || *s == '-') { - if (*(s-1) != 'e') - return false; + } + + while (s[i] != '\0') { + if (s[i] != ' ') { + return false; } - else return false; - s += 1; + i++; } - return is_digit; + return true; } -}; \ No newline at end of file +}; diff --git a/ValidSudoku/ValidSudoku.cpp b/ValidSudoku/ValidSudoku.cpp index 562419b..0cdbf31 100644 --- a/ValidSudoku/ValidSudoku.cpp +++ b/ValidSudoku/ValidSudoku.cpp @@ -1,29 +1,23 @@ class Solution { public: - bool visited_cells[20][20]; - bool visited_row[20][20]; - bool visited_col[20][20]; - - bool isValidSudoku(vector>& board) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - memset(visited_cells, false, sizeof(visited_cells)); - memset(visited_row, false, sizeof(visited_row)); - memset(visited_col, false, sizeof(visited_col)); + bool isValidSudoku(vector> &board) { + vector> rows(9, vector(9, false)); + vector> cols(9, vector(9, false)); + vector> cells(9, vector(9, false)); for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (board[i][j] != '.') { - int cell = (i / 3) * 3 + j / 3; - int x = board[i][j] - '0'; - if (visited_cells[cell][x] || visited_row[i][x] || visited_col[j][x]) + int x = board[i][j] - '1'; + if (rows[i][x] || cols[j][x] || cells[(j/3)*3+i/3][x]) { return false; - visited_cells[cell][x] = true; - visited_row[i][x] = visited_col[j][x] = true; + } + rows[i][x] = true; + cols[j][x] = true; + cells[(j/3)*3+i/3][x] = true; } } } return true; } -}; \ No newline at end of file +}; diff --git a/ValidateBinarySearchTree/ValidateBinarySearchTree.cpp b/ValidateBinarySearchTree/ValidateBinarySearchTree.cpp index b912454..fd66a3c 100644 --- a/ValidateBinarySearchTree/ValidateBinarySearchTree.cpp +++ b/ValidateBinarySearchTree/ValidateBinarySearchTree.cpp @@ -10,23 +10,22 @@ class Solution { public: bool isValidBST(TreeNode *root) { - // Start typing your C/C++ solution below - // DO NOT write int main() function + if (root == NULL) + return true; - if (root == NULL) return true; - TreeNode *parent = NULL; - return isValidBST(root, parent); + return valid(root->left, INT_MIN, root->val) && + valid(root->right, root->val, INT_MAX); } - bool isValidBST(TreeNode *current, TreeNode *&parent) { - if (current == NULL) return true; - bool valid = true; - valid = isValidBST(current->left, parent); - if (parent && parent->val >= current->val) + bool valid(TreeNode *node, int start, int limit) { + if (node == NULL) + return true; + + if (node->val >= limit || node->val <= start) return false; - parent = current; - valid &= isValidBST(current->right, parent); - return valid; + + return valid(node->left, start, node->val) && + valid(node->right, node->val, limit); } }; @@ -73,4 +72,4 @@ class Solution { return flag; } }; -// http://fisherlei.blogspot.com/2012/12/leetcode-recover-binary-search-tree.html \ No newline at end of file +// http://fisherlei.blogspot.com/2012/12/leetcode-recover-binary-search-tree.html diff --git a/WordLadder/WordLadder.cpp b/WordLadder/WordLadder.cpp index 8c76fb7..18869a5 100644 --- a/WordLadder/WordLadder.cpp +++ b/WordLadder/WordLadder.cpp @@ -1,42 +1,37 @@ class Solution { public: int ladderLength(string start, string end, unordered_set &dict) { - // Start typing your C/C++ solution below - // DO NOT write int main() function - - queue> Q; - unordered_set visited; - Q.push(make_pair(start, 1)); - - while (!Q.empty()) { - pair src = Q.front(); - Q.pop(); - if (src.first == end) { - return src.second; - } - vector neighbor; - getNeighbors(src.first, neighbor, dict); - for (string word : neighbor) { - if (visited.find(word) == visited.end()) { - visited.insert(word); - Q.push(make_pair(word, src.second + 1)); - } - } - } - return 0; - } + queue q; + unordered_map visited; + map steps; - void getNeighbors(const string& word, - vector& neighbor, - const unordered_set& dict) { - for (size_t i = 0; i < word.size(); i++) { - string copyword(word); - for (char ch = 'a'; ch <= 'z'; ch++) { - copyword[i] = ch; - if (dict.find(copyword) != dict.end()) { - neighbor.push_back(copyword); + q.push(start); + visited[start] = true; + while (!q.empty()) { + string u = q.front(); + q.pop(); + if (u == end) { + int count = 1; + while (steps.find(u) != steps.end()) { + u = steps[u]; + count++; + } + return count; + } + string v = u; + for (int i = 0; i < v.size(); i++) { + for (char c = 'a'; c <= 'z'; c++) { + v[i] = c; + if (visited.find(v) == visited.end() + && dict.find(v) != dict.end()) { + visited[v] = true; + steps[v] = u; + q.push(v); } } + v[i] = u[i]; } + } + return 0; } };