├── C++ ├── addBinary.cpp ├── addTwoNumbers.cpp ├── anagrams.cpp ├── atoi.cpp ├── buildTreeWithPostOrder.cpp ├── buildTreeWithPreOrder.cpp ├── canCompleteCircuit.cpp ├── canJump.cpp ├── candy.cpp ├── cloneGraph.cpp ├── combinationSum.cpp ├── combinationSum2.cpp ├── combine.cpp ├── connect.cpp ├── convert.cpp ├── copyRandomList.cpp ├── coundAndSay.cpp ├── deleteDuplicatesII.cpp ├── detectCycle.cpp ├── divide.cpp ├── evalRPN.cpp ├── exist.cpp ├── findMedianSortedArrays.cpp ├── findMinimumInRotatedSortedArray.cpp ├── findSubstring.cpp ├── firstMissingPositive.cpp ├── flatten.cpp ├── fourSum.cpp ├── generateMatrix.cpp ├── generateParenthesis.cpp ├── generateTrees.cpp ├── getPermutation.cpp ├── getRow.cpp ├── hasCycle.cpp ├── hasPathSum.cpp ├── insert.cpp ├── insertionSortList.cpp ├── isInterleave.cpp ├── isMatch.cpp ├── isPalindrome.cpp ├── isPalindromeII.cpp ├── isScramble.cpp ├── isValid.cpp ├── isValidBST.cpp ├── isValidBST2.cpp ├── isValidSudoku.cpp ├── jump.cpp ├── ladderLength.cpp ├── largestRectangleArea.cpp ├── lengthOfLastWord.cpp ├── lengthOfLongestSubstring.cpp ├── letterCombinations.cpp ├── longestCommonLength.cpp ├── longestConsecutive.cpp ├── longestPalindrome.cpp ├── longestValidParentheses.cpp ├── maxArea.cpp ├── maxDepth.cpp ├── maxPathSum.cpp ├── maxProfitI.cpp ├── maxProfitII.cpp ├── maxProfitIII.cpp ├── maximalRectangle.cpp ├── merge.cpp ├── merge2.cpp ├── mergeKLists.cpp ├── minCut.cpp ├── minDepth.cpp ├── minDistance.cpp ├── minPathSum.cpp ├── minWindow.cpp ├── minimumTotal.cpp ├── minimumTotal2.cpp ├── multiply.cpp ├── nextPermutation.cpp ├── numDecodings.cpp ├── numDistinct.cpp ├── palindromePartition.cpp ├── palindromePartition2.cpp ├── partition.cpp ├── pathSum.cpp ├── permuteUnique.cpp ├── plusOne.cpp ├── pow.cpp ├── recoverTree.cpp ├── removeDuplicates.cpp ├── removeNthFromEnd.cpp ├── reorderList.cpp ├── restoreIpAddresses.cpp ├── reverseBetween.cpp ├── reverseKGroup.cpp ├── reverseWords.cpp ├── rotate.cpp ├── rotateRight.cpp ├── search.cpp ├── searchMatrix.cpp ├── searchMatrix2.cpp ├── searchRange.cpp ├── simplifyPath.cpp ├── solveNQueens.cpp ├── solveSudoku.cpp ├── sortColors.cpp ├── sortList.cpp ├── sortedListToBST.cpp ├── spiralOrder.cpp ├── sqrt.cpp ├── strStr.cpp ├── subsets.cpp ├── subsetsWithDup.cpp ├── sumNumbers.cpp ├── surroundedRegions.cpp ├── textJustification.cpp ├── threeSum.cpp ├── threeSum2.cpp ├── threeSumCloset.cpp ├── totalNQueens.cpp ├── trap.cpp ├── uniquePathWithObstacles.cpp ├── uniquePaths.cpp ├── uniquePaths2.cpp ├── wordBreak.cpp ├── wordBreakII.cpp └── zigzagLevelOrder.cpp ├── Java ├── .classpath ├── .gitignore ├── .project └── src │ └── net │ └── kenyang │ └── algorithm │ ├── BestTimeToBuyAndSellStock.java │ ├── LRUCache.java │ ├── LinkedListCycle.java │ ├── MaximumDepthOfBinaryTree.java │ ├── ReverseInteger.java │ ├── SameTree.java │ ├── SingleNumber.java │ ├── SymmetricTree.java │ └── UniqueBinarySearchTrees.java ├── MySQL ├── combine-two-tables.sql ├── consecutive-numbers.sql ├── nth-highest-salary.sql ├── rank-scores.sql └── second-highest-salary.sql ├── Python ├── 3sum-closest.py ├── 3sum.py ├── 4sum.py ├── add-binary.py ├── add-two-numbers.py ├── anagrams.py ├── balanced-binary-tree.py ├── best-time-to-buy-and-sell-stock-ii.py ├── best-time-to-buy-and-sell-stock-iii.py ├── best-time-to-buy-and-sell-stock.py ├── binary-search-tree-iterator.py ├── binary-tree-inorder-traversal.py ├── binary-tree-level-order-traversal-ii.py ├── binary-tree-level-order-traversal.py ├── binary-tree-maximum-path-sum.py ├── binary-tree-postorder-traversal.py ├── binary-tree-preorder-traversal.py ├── binary-tree-upside-down.py ├── binary-tree-zigzag-level-order-traversal.py ├── candy.py ├── climbing-stairs.py ├── clone-graph.py ├── combination-sum-ii.py ├── combination-sum.py ├── combinations.py ├── compare-version-numbers.py ├── construct-binary-tree-from-inorder-and-postorder-traversal.py ├── construct-binary-tree-from-preorder-and-inorder-traversal.py ├── container-with-most-water.py ├── convert-sorted-array-to-binary-search-tree.py ├── convert-sorted-list-to-binary-search-tree.py ├── copy-list-with-random-pointer.py ├── count-and-say.py ├── decode-ways.py ├── distinct-subsequences.py ├── divide-two-integers.py ├── dungeon-game.py ├── edit-distance.py ├── evaluate-reverse-polish-notation.py ├── excel-sheet-column-number.py ├── excel-sheet-column-title.py ├── factorial-trailing-zeroes.py ├── find-minimum-in-rotated-sorted-array-ii.py ├── find-minimum-in-rotated-sorted-array.py ├── find-peak-element.py ├── first-missing-positive.py ├── flatten-binary-tree-to-linked-list.py ├── fraction-to-recurring-decimal.py ├── gas-station.py ├── generate-parentheses.py ├── gray-code.py ├── implement-strstr.py ├── insert-interval.py ├── insertion-sort-list.py ├── integer-to-roman.py ├── interleaving-string.py ├── intersection-of-two-linked-lists.py ├── jump-game-ii.py ├── jump-game.py ├── largest-number.py ├── largest-rectangle-in-histogram.py ├── length-of-last-word.py ├── letter-combinations-of-a-phone-number.py ├── linked-list-cycle-ii.py ├── linked-list-cycle.py ├── longest-common-prefix.py ├── longest-consecutive-sequence.py ├── longest-palindromic-substring.py ├── longest-substring-with-at-most-two-distinct-characters.py ├── longest-substring-without-repeating-characters.py ├── longest-valid-parentheses.py ├── lru-cache.py ├── majority-element.py ├── max-points-on-a-line.py ├── maximal-rectangle.py ├── maximum-depth-of-binary-tree.py ├── maximum-gap.py ├── maximum-product-subarray.py ├── maximum-subarray.py ├── median-of-two-sorted-arrays.py ├── merge-intervals.py ├── merge-k-sorted-lists.py ├── merge-sorted-array.py ├── merge-two-sorted-lists.py ├── min-stack.py ├── minimum-depth-of-binary-tree.py ├── minimum-path-sum.py ├── minimum-window-substring.py ├── missing-ranges.py ├── multiply-strings.py ├── n-queens-ii.py ├── n-queens.py ├── next-permutation.py ├── one-edit-distance.py ├── palindrome-number.py ├── palindrome-partitioning-ii.py ├── palindrome-partitioning.py ├── partition-list.py ├── pascals-triangle-ii.py ├── pascals-triangle.py ├── path-sum-ii.py ├── path-sum.py ├── permutation-sequence.py ├── permutations-ii.py ├── permutations.py ├── plus-one.py ├── populating-next-right-pointers-in-each-node-ii.py ├── populating-next-right-pointers-in-each-node.py ├── powx-n.py ├── read-n-characters-given-read4-ii-call-multiple-times.py ├── read-n-characters-given-read4.py ├── recover-binary-search-tree.py ├── regular-expression-matching.py ├── remove-duplicates-from-sorted-array-ii.py ├── remove-duplicates-from-sorted-array.py ├── remove-duplicates-from-sorted-list-ii.py ├── remove-duplicates-from-sorted-list.py ├── remove-element.py ├── remove-nth-node-from-end-of-list.py ├── reorder-list.py ├── restore-ip-addresses.py ├── reverse-integer.py ├── reverse-linked-list-ii.py ├── reverse-nodes-in-k-group.py ├── reverse-words-in-a-string.py ├── roman-to-integer.py ├── rotate-image.py ├── rotate-list.py ├── same-tree.py ├── scramble-string.py ├── search-a-2d-matrix.py ├── search-for-a-range.py ├── search-in-rotated-sorted-array-ii.py ├── search-in-rotated-sorted-array.py ├── search-insert-position.py ├── set-matrix-zeroes.py ├── simplify-path.py ├── single-number-ii.py ├── single-number.py ├── sort-colors.py ├── sort-list.py ├── spiral-matrix-ii.py ├── spiral-matrix.py ├── sqrtx.py ├── string-to-integer-atoi.py ├── subsets-ii.py ├── subsets.py ├── substring-with-concatenation-of-all-words.py ├── sudoku-solver.py ├── sum-root-to-leaf-numbers.py ├── surrounded-region.py ├── swap-nodes-in-pairs.py ├── symmetric-tree.py ├── text-justification.py ├── trapping-rain-water.py ├── triangle.py ├── two-sum-ii-input-array-is-sorted.py ├── two-sum-iii-data-structure-design.py ├── two-sum.py ├── unique-binary-search-trees-ii.py ├── unique-binary-search-trees.py ├── unique-paths-ii.py ├── unique-paths.py ├── valid-number.py ├── valid-palindrome.py ├── valid-parentheses.py ├── valid-sudoku.py ├── validate-binary-search-tree.py ├── wildcard-matching.py ├── word-break-ii.py ├── word-break.py ├── word-ladder-ii.py ├── word-ladder.py ├── word-search.py └── zigzag-conversion.py └── README.md /C++/addBinary.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | string addBinary(string a, string b) { 7 | size_t carry = 0; 8 | string ans; 9 | 10 | for(auto ai = a.rbegin(), bi = b.rbegin(); ai != a.rend() || bi != b.rend();) { 11 | const size_t av = (ai != a.rend())? *ai - '0' : 0; 12 | const size_t bv = (bi != b.rend())? *bi - '0' : 0; 13 | const size_t val = (av + bv + carry) % 2; 14 | carry = (av + bv + carry) / 2; 15 | ans.push_back( val + '0' ); 16 | 17 | if(ai != a.rend()) 18 | ++ai; 19 | if(bi != b.rend()) 20 | ++bi; 21 | } 22 | if(carry) 23 | ans.push_back('1'); 24 | 25 | reverse(ans.begin(), ans.end()); 26 | 27 | return ans; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /C++/addTwoNumbers.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) { 15 | ListNode dummy(INT_MIN); 16 | ListNode *p = &dummy; 17 | int carry = 0; 18 | 19 | for(; l1 || l2; p = p->next) { 20 | const int v1 = (l1)? l1->val : 0; 21 | const int v2 = (l2)? l2->val : 0; 22 | p->next = new ListNode((v1 + v2 + carry) % 10); 23 | carry = (v1 + v2 + carry) / 10; 24 | if(l1) l1 = l1->next; 25 | if(l2) l2 = l2->next; 26 | } 27 | 28 | if(carry) 29 | p->next = new ListNode(carry); 30 | 31 | return dummy.next; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /C++/anagrams.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(klogk * n) ~= O(n), k is length of string, n is number of strings 2 | // Space Complexity: O(k * n) ~= O(n) 3 | 4 | class Solution { 5 | public: 6 | vector anagrams(vector &strs) { 7 | vector ans; 8 | unordered_map > group; 9 | for(auto s : strs) { 10 | string k = s; 11 | sort(k.begin(), k.end()); 12 | group[k].push_back(s); 13 | } 14 | 15 | for(auto it = group.cbegin(); it != group.cend(); ++it) { 16 | if(it->second.size() > 1) 17 | ans.insert(ans.end(), it->second.begin(), it->second.end()); 18 | } 19 | 20 | return ans; 21 | } 22 | };` 23 | -------------------------------------------------------------------------------- /C++/atoi.cpp: -------------------------------------------------------------------------------- 1 | 2 | // LeetCode, String to Integer (atoi) 3 | // Complexity: 4 | // O(n) time 5 | // O(1) space 6 | 7 | class Solution { 8 | public: 9 | int atoi(const char *str) { 10 | int num = 0; 11 | int sign = 1; 12 | const int n = strlen(str); 13 | int i = 0; 14 | while (str[i] == ' ' && i < n) i++; 15 | // parse sign 16 | if (str[i] == '+') i++; 17 | if (str[i] == '-') { 18 | sign = -1; 19 | i++; 20 | } 21 | 22 | for (; i < n; i++) { 23 | // handle non-digital character 24 | if (str[i] < '0' || str[i] > '9') 25 | break; 26 | // handle overflow 27 | if ( num > INT_MAX / 10 28 | || (num == INT_MAX / 10 && (str[i] - '0') > INT_MAX % 10)) { 29 | return sign == -1 ? INT_MIN : INT_MAX; 30 | } 31 | num = num * 10 + str[i] - '0'; 32 | } 33 | return num * sign; 34 | } 35 | }; -------------------------------------------------------------------------------- /C++/buildTreeWithPostOrder.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(logn) 3 | 4 | /** 5 | * Definition for binary tree 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | TreeNode *buildTree(vector &inorder, vector &postorder) { 16 | return buildTree(begin(inorder), end(inorder), begin(postorder), end(postorder)); 17 | } 18 | private: 19 | template 20 | TreeNode *buildTree(InputIterator in_first, InputIterator in_last, InputIterator post_first, InputIterator post_last) { 21 | if(in_first == in_last) 22 | return NULL; 23 | if(post_first == post_last) 24 | return NULL; 25 | 26 | auto root = new TreeNode(*prev(post_last)); 27 | auto inRootPos = find(in_first, in_last, *prev(post_last)); 28 | auto leftSize = distance(in_first, inRootPos); 29 | root->left = buildTree(in_first, inRootPos, post_first, next(post_first, leftSize)); 30 | root->right = buildTree(next(inRootPos), in_last, next(post_first, leftSize), prev(post_last)); 31 | 32 | return root; 33 | } 34 | 35 | }; 36 | -------------------------------------------------------------------------------- /C++/buildTreeWithPreOrder.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(logn) 3 | 4 | /** 5 | * Definition for binary tree 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | TreeNode* buildTree(vector& preorder, vector& inorder) { 16 | return buildTree(begin(preorder), end(preorder), begin(inorder), end(inorder)); 17 | } 18 | 19 | private: 20 | template 21 | TreeNode* buildTree(InputIterator pre_first, InputIterator pre_last, InputIterator in_first, InputIterator in_last) { 22 | if(pre_first == pre_last) 23 | return NULL; 24 | if(in_first == in_last) 25 | return NULL; 26 | 27 | auto root = new TreeNode(*pre_first); 28 | auto inRootPos = find(in_first, in_last, *pre_first); 29 | auto leftSize = distance(in_first, inRootPos); 30 | root->left = buildTree(next(pre_first), next(pre_first, leftSize + 1), in_first, inRootPos); 31 | root->right = buildTree(next(pre_first, leftSize + 1), pre_last, next(inRootPos), in_last); 32 | 33 | return root; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /C++/canCompleteCircuit.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | int canCompleteCircuit(vector &gas, vector &cost) { 7 | int total = 0; 8 | int sum = 0; 9 | int j = -1; 10 | 11 | for(int i = 0; i < gas.size(); ++i) { 12 | total += gas[i] - cost[i]; 13 | sum += gas[i] - cost[i]; 14 | if(sum < 0) { // find the gas station which should be the last one 15 | sum = 0; 16 | j = i; 17 | } 18 | } 19 | 20 | return (total >= 0) ? j + 1 : -1; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /C++/canJump.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | bool canJump(int A[], int n) { 7 | int reach = 0; 8 | for(int i = 0; i <= reach && i < n; ++i) { 9 | reach = max(reach, i + A[i]); 10 | } 11 | return reach >= n - 1; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /C++/candy.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(n) 3 | 4 | class Solution { 5 | public: 6 | int candy(vector &ratings) { 7 | const int n = ratings.size(); 8 | vector increment(n, 0); 9 | 10 | // left to right 11 | for(int i = 1, inc = 0; i < n; ++i) { 12 | if(ratings[i] > ratings[i - 1]) 13 | increment[i] = max(++inc, increment[i]); 14 | else 15 | inc = 0; 16 | } 17 | 18 | // right to left 19 | for(int i = n - 2, inc = 0; i >= 0; --i) { 20 | if(ratings[i] > ratings[i + 1]) 21 | increment[i] = max(++inc, increment[i]); 22 | else 23 | inc = 0; 24 | } 25 | 26 | return accumulate(increment.begin(), increment.end(), n); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /C++/cloneGraph.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(n) 3 | 4 | /** 5 | * Definition for undirected graph. 6 | * struct UndirectedGraphNode { 7 | * int label; 8 | * vector neighbors; 9 | * UndirectedGraphNode(int x) : label(x) {}; 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) { 15 | if(!node) 16 | return nullptr; 17 | unordered_map copied; 18 | copied[node] = new UndirectedGraphNode(node->label); 19 | queue q; 20 | q.push(node); 21 | while(!q.empty()) { 22 | auto node = q.front(); 23 | q.pop(); 24 | 25 | for(auto n : node->neighbors) { 26 | if(copied.find(n) == copied.end()) { 27 | copied[n] = new UndirectedGraphNode(n->label); 28 | q.push(n); 29 | } 30 | 31 | copied[node]->neighbors.push_back(copied[n]); 32 | } 33 | } 34 | 35 | return copied[node]; 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /C++/combinationSum.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n!) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | vector > combinationSum(vector &candidates, int target) { 7 | sort(candidates.begin(), candidates.end()); 8 | vector > ans; 9 | vector v; 10 | dfs(candidates, target, 0, v, ans); 11 | return ans; 12 | } 13 | 14 | private: 15 | void dfs(vector& candidates, int gap, int begin, vector& v,vector > &ans) { 16 | if (gap == 0) { 17 | ans.push_back(v); 18 | return; 19 | } 20 | 21 | for (size_t i = begin; i < candidates.size(); i++) { 22 | if (gap < candidates[i]) return; 23 | v.push_back(candidates[i]); 24 | dfs(candidates, gap - candidates[i], i, v, ans); 25 | v.pop_back(); 26 | } 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /C++/combinationSum2.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n!) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | vector > combinationSum2(vector &num, int target) { 7 | sort(num.begin(), num.end()); 8 | vector > ans; 9 | vector v; 10 | dfs(num, target, 0, v, ans); 11 | return ans; 12 | } 13 | 14 | private: 15 | void dfs(vector& num, int gap, int begin, vector& v,vector > &ans) { 16 | if (gap == 0) { 17 | ans.push_back(v); 18 | return; 19 | } 20 | 21 | for (size_t i = begin; i < num.size(); i++) { 22 | if (gap < num[i]) return; // pruning 23 | if( i > begin && num[i] == num[i - 1]) // skip duplicates 24 | continue; 25 | v.push_back(num[i]); 26 | dfs(num, gap - num[i], i + 1, v, ans); // each element could be chosen only once 27 | v.pop_back(); 28 | } 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /C++/combine.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n!) 2 | // Space Complexity: O(n) 3 | 4 | class Solution { 5 | public: 6 | void dfs(int n, int k, int start, vector &path, vector > &ans) { 7 | if(k == 0) { 8 | ans.push_back(path); 9 | return; 10 | } 11 | 12 | for(int i = start; i <= n; ++i) { 13 | path.push_back(i); 14 | dfs(n, k - 1, i + 1, path, ans); 15 | path.pop_back(); 16 | } 17 | } 18 | vector > combine(int n, int k) { 19 | vector > ans; 20 | vector path; 21 | dfs(n, k, 1, path, ans); 22 | return ans; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /C++/connect.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | /** 5 | * Definition for binary tree with next pointer. 6 | * struct TreeLinkNode { 7 | * int val; 8 | * TreeLinkNode *left, *right, *next; 9 | * TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | void connect(TreeLinkNode *root) { 15 | for(TreeLinkNode *list, *first; root; root = first) { // enumerate each level of depth 16 | list = first = NULL; 17 | for(; root; root = root->next) { // enumerate nodes at the same level of depth 18 | if(!first) first = (root->left)? root->left:root->right; 19 | if(root->left) { 20 | if(list) list->next = root->left; 21 | list = root->left; 22 | } 23 | if(root->right) { 24 | if(list) list->next = root->right; 25 | list = root->right; 26 | } 27 | } 28 | } 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /C++/convert.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(n) 3 | 4 | class Solution { 5 | public: 6 | string convert(string s, int nRows) { 7 | vector row(nRows); 8 | string ans; 9 | int cnt = 0; 10 | 11 | if(nRows == 1) 12 | return s; 13 | 14 | for(auto c : s) { 15 | if(cnt < nRows) { 16 | row[cnt].push_back(c); 17 | } 18 | else { 19 | row[2 * nRows - 2 - cnt].push_back(c); 20 | } 21 | 22 | cnt = (cnt + 1) % (2 * nRows - 2); 23 | } 24 | 25 | for(auto s : row) { 26 | ans.append(s); 27 | } 28 | 29 | return ans; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /C++/copyRandomList.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list with a random pointer. 6 | * struct RandomListNode { 7 | * int label; 8 | * RandomListNode *next, *random; 9 | * RandomListNode(int x) : label(x), next(NULL), random(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | RandomListNode *copyRandomList(RandomListNode *head) { 15 | // insert the copied node after the original one 16 | for(RandomListNode *cur = head; cur; cur = cur->next->next) { 17 | RandomListNode *node = new RandomListNode(cur->label); 18 | node->next = cur->next; 19 | cur->next = node; 20 | } 21 | 22 | // update random node 23 | for(RandomListNode *cur = head; cur; cur = cur->next->next) { 24 | if(cur->random) { 25 | cur->next->random = cur->random->next; 26 | } 27 | } 28 | 29 | // seperate the copied nodes from original ones 30 | RandomListNode dummy(INT_MIN); 31 | for( RandomListNode *cur = head, *copy_cur = &dummy; 32 | cur; 33 | copy_cur = copy_cur->next, cur = cur->next) { 34 | copy_cur->next = cur->next; 35 | cur->next = cur->next->next; 36 | } 37 | 38 | return dummy.next; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /C++/coundAndSay.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n^2) 2 | // Space Complexity: O(n) 3 | 4 | class Solution { 5 | public: 6 | string countAndSay(int n) { 7 | string s{"1"}; 8 | while(--n) { 9 | s = getNext(s); 10 | } 11 | return s; 12 | } 13 | 14 | private: 15 | string getNext(const string &s) { 16 | stringstream ss; 17 | for(auto i = s.begin(); i != s.end();) { 18 | auto j = find_if(i, s.end(), bind1st(not_equal_to(), *i)); 19 | ss << distance(i, j) << *i; 20 | i = j; 21 | } 22 | return ss.str(); 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /C++/deleteDuplicatesII.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | ListNode *deleteDuplicates(ListNode *head) { 15 | if(!head) 16 | return NULL; 17 | ListNode dummy(INT_MIN); 18 | dummy.next = head; 19 | ListNode *pre2nd = &dummy; 20 | ListNode *pre1st = head; 21 | ListNode *cur = pre1st->next; 22 | bool isDup = false; 23 | 24 | while(pre1st) { 25 | if(cur && pre1st->val == cur->val) { 26 | pre2nd->next = cur; // remove previous first node 27 | delete pre1st; 28 | pre1st = NULL; 29 | isDup = true; 30 | } 31 | else if(isDup){ 32 | pre2nd->next = cur; // remove previous first node 33 | delete pre1st; 34 | pre1st = NULL; 35 | isDup = false; 36 | } 37 | 38 | if(pre1st) pre2nd = pre1st; 39 | pre1st = cur; 40 | if(cur) cur = cur->next; 41 | } 42 | 43 | return dummy.next; 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /C++/detectCycle.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | ListNode *detectCycle(ListNode *head) { 15 | ListNode *slow = head, *fast = head; 16 | 17 | while(fast && fast->next) { 18 | slow = slow->next; 19 | fast = fast->next->next; 20 | 21 | if(slow == fast) { 22 | ListNode *slow2 = head; 23 | while(slow2 != slow) { 24 | slow2 = slow2->next; 25 | slow = slow->next; 26 | } 27 | return slow2; 28 | } 29 | } 30 | 31 | return NULL; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /C++/divide.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(logn) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | int divide(int dividend, int divisor) { 7 | long long a = dividend >= 0 ? dividend : -(long long)dividend; 8 | long long b = divisor >= 0 ? divisor : -(long long)divisor; 9 | 10 | long long result = 0; 11 | while(a >= b) { 12 | long long c = b; 13 | int i = 0; 14 | for(; a >= c; c <<= 1, ++i); 15 | if(i > 0) { 16 | a -= c >> 1; 17 | result += 1 << (i - 1); 18 | } 19 | } 20 | 21 | return ((dividend ^ divisor) >> 31)? -result : result; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /C++/evalRPN.cpp: -------------------------------------------------------------------------------- 1 | // Time Space: O(n) 2 | // Space Space: O(logn) 3 | 4 | class Solution { 5 | public: 6 | int evalRPN(vector &tokens) { 7 | stack s; 8 | for(auto tok : tokens) { 9 | if(!is_operator(tok)) { 10 | s.push(tok); 11 | } 12 | else { 13 | int y = stoi(s.top()); 14 | s.pop(); 15 | int x = stoi(s.top()); 16 | s.pop(); 17 | if(tok[0] == '+') x += y; 18 | else if (tok[0] == '-') x -= y; 19 | else if (tok[0] == '*') x *= y; 20 | else x /= y; 21 | s.push(to_string(x)); 22 | } 23 | } 24 | return stoi(s.top()); 25 | } 26 | private: 27 | bool is_operator(const string &op) { 28 | return op.length() == 1 && string("+-*/").find(op) != string::npos; 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /C++/findMedianSortedArrays.cpp: -------------------------------------------------------------------------------- 1 | // LeetCode, Median of Two Sorted Arrays 2 | // Complexity: 3 | // O(log(m+n)) 4 | // O(log(m+n)) 5 | 6 | class Solution { 7 | public: 8 | double findMedianSortedArrays(int A[], int m, int B[], int n) { 9 | int total = m + n; 10 | if (total & 0x1) 11 | return find_kth(A, m, B, n, total / 2 + 1); 12 | else 13 | return (find_kth(A, m, B, n, total / 2) 14 | + find_kth(A, m, B, n, total / 2 + 1)) / 2.0; 15 | } 16 | 17 | private: 18 | static int find_kth(int A[], int m, int B[], int n, int k) { 19 | //always assume that m is equal or smaller than n 20 | if (m > n) return find_kth(B, n, A, m, k); 21 | if (m == 0) return B[k - 1]; 22 | if (k == 1) return min(A[0], B[0]); 23 | 24 | //divide k into two parts 25 | int ia = min(k / 2, m), ib = k - ia; 26 | if (A[ia - 1] < B[ib - 1]) 27 | return find_kth(A + ia, m - ia, B, n, k - ia); 28 | else if (A[ia - 1] > B[ib - 1]) 29 | return find_kth(A, m, B + ib, n - ib, k - ib); 30 | else 31 | return A[ia - 1]; 32 | } 33 | }; -------------------------------------------------------------------------------- /C++/findMinimumInRotatedSortedArray.cpp: -------------------------------------------------------------------------------- 1 | // LeetCode, SFind Minimum in Rotated Sorted Array 2 | // Complexity: 3 | // O(logn) time 4 | // O(1) space 5 | 6 | class Solution { 7 | public: 8 | int findMin(vector &num) { 9 | int start = 0, end = num.size(); 10 | 11 | while (start < end) { 12 | if (num[start] <= num[end - 1]) 13 | return num[start]; 14 | 15 | int mid = start + (end - start)/2; 16 | 17 | if (num[mid] >= num[start]) { 18 | start = mid + 1; 19 | } else { 20 | if (mid == end - 1) 21 | return num[mid]; 22 | else 23 | end = mid + 1; 24 | } 25 | } 26 | 27 | return num[start]; 28 | } 29 | }; -------------------------------------------------------------------------------- /C++/findSubstring.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O((m - n * k) * n * k) ~ O(m * n * k), where m is string length, n is dict size, k is word length 2 | // Space Complexity: O( n * k) 3 | class Solution { 4 | public: 5 | vector findSubstring(string s, vector &dict) { 6 | const size_t wordLength = dict.front().length(); 7 | const size_t catLength = wordLength * dict.size(); 8 | vector result; 9 | 10 | if(s.length() < catLength) return result; 11 | 12 | unordered_map wordCount; 13 | 14 | for(auto const & word : dict) ++wordCount[word]; 15 | 16 | for(auto i = begin(s); i <= prev(end(s), catLength); ++i) { 17 | unordered_map unused(wordCount); 18 | 19 | for(auto j = i; j != next(i, catLength); j += wordLength) { 20 | auto pos = unused.find(string(j, next(j, wordLength))); 21 | 22 | if(pos == unused.end()) break; 23 | 24 | if(--pos->second == 0) unused.erase(pos); 25 | } 26 | 27 | if(unused.size() == 0) result.push_back(distance(begin(s), i)); 28 | } 29 | 30 | return result; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /C++/firstMissingPositive.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | int firstMissingPositive(int A[], int n) { 7 | int i; 8 | bucketSort(A, n); 9 | for(i = 0; i < n && A[i] == i + 1; ++i); 10 | return i + 1; 11 | } 12 | 13 | private: 14 | void bucketSort(int A[], int n) { 15 | for(int i = 0; i < n; ++i) { 16 | for (; A[i] != i + 1 && A[i] > 0 && A[i] <= n && A[i] != A[A[i] - 1];) { 17 | swap(A[i], A[A[i] - 1]); 18 | } 19 | } 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /C++/flatten.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(logn) 3 | 4 | /** 5 | * Definition for binary tree 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | void flatten(TreeNode *root) { 16 | if(!root) 17 | return; 18 | 19 | p = root; 20 | flatten(root->left); 21 | p->right = root->right; 22 | flatten(root->right); 23 | if(root->left) { 24 | root->right = root->left; 25 | root->left = NULL; 26 | } 27 | } 28 | private: 29 | TreeNode *p; 30 | }; 31 | -------------------------------------------------------------------------------- /C++/fourSum.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n^2) 2 | // Space Complexity: O(n^2) 3 | 4 | class Solution { 5 | public: 6 | vector > fourSum(vector &num, int target) { 7 | vector> ans; 8 | if (num.size() < 4) 9 | return ans; 10 | sort(num.begin(), num.end()); 11 | unordered_multimap> cache; 12 | 13 | for (int i = 0; i + 1 < num.size(); ++i) 14 | for (int j = i + 1; j < num.size(); ++j) 15 | cache.insert(make_pair(num[i] + num[j], make_pair(i, j))); 16 | 17 | for (auto i = cache.begin(); i != cache.end(); ++i) { 18 | int x = target - i->first; 19 | auto range = cache.equal_range(x); 20 | for (auto j = range.first; j != range.second; ++j) { 21 | auto a = i->second.first; 22 | auto b = i->second.second; 23 | auto c = j->second.first; 24 | auto d = j->second.second; 25 | if (b < c) { 26 | ans.push_back({ num[a], num[b], num[c], num[d] }); 27 | } 28 | } 29 | } 30 | sort(ans.begin(), ans.end()); 31 | ans.erase(unique(ans.begin(), ans.end()), ans.end()); 32 | return ans; 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /C++/generateMatrix.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n^2) 2 | // Space Complexity: O(n^2) 3 | 4 | class Solution { 5 | public: 6 | vector > generateMatrix(int n) { 7 | vector > v(n, vector(n, 0)); 8 | enum Action {RIGHT, DOWN, LEFT, UP}; 9 | Action action = RIGHT; 10 | for(int i = 0, j = 0, cnt = 0, total = n * n; cnt < total;) { 11 | v[i][j] = ++cnt; 12 | 13 | switch(action) { 14 | case RIGHT: 15 | if(j + 1 < n && v[i][j + 1] == 0) ++j; 16 | else action = DOWN, ++i; 17 | break; 18 | case DOWN: 19 | if(i + 1 < n && v[i + 1][j] == 0) ++i; 20 | else action = LEFT, --j; 21 | break; 22 | case LEFT: 23 | if(j - 1 >= 0 && v[i][j - 1] == 0) --j; 24 | else action = UP, --i; 25 | break; 26 | case UP: 27 | if(i - 1 >= 0 && v[i - 1][j] == 0) --i; 28 | else action = RIGHT, ++j; 29 | break; 30 | default: 31 | break; 32 | } 33 | } 34 | return v; 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /C++/generateParenthesis.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(2^n/n)?? 2 | // Space Complexity: O(n) 3 | 4 | class Solution { 5 | public: 6 | void generator(vector &ans, string s, int l, int r, int n) { 7 | if(l==n) { 8 | ans.push_back(s.append(n-r, ')')); 9 | return; 10 | } 11 | generator(ans, s+"(", l+1, r, n); 12 | if(l>r) generator(ans, s+")", l, r+1, n); 13 | 14 | } 15 | vector generateParenthesis(int n) { 16 | vector ans; 17 | generator(ans, "", 0, 0, n); 18 | return ans; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /C++/generateTrees.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O( (2n, n) / n ) ~= O( 4^n / n^(3/2) ) 2 | // Space Complexity: O( (2n, n) ) ~= O( 4^n / n^(1/2) ) 3 | 4 | /** 5 | * Definition for binary tree 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | vector generateTrees(int n) { 16 | return generate(1, n); 17 | } 18 | private: 19 | vector generate(int begin, int end) { 20 | vector subTree; 21 | if(begin > end) { 22 | subTree.push_back(NULL); 23 | } 24 | 25 | for(int k = begin; k <= end; ++k) { 26 | vector leftSubTree = generate(begin, k - 1); 27 | vector rightSubTree = generate(k + 1, end); 28 | 29 | for(auto i : leftSubTree) { 30 | for(auto j : rightSubTree) { 31 | TreeNode *node = new TreeNode(k); 32 | node->left = i; 33 | node->right = j; 34 | subTree.push_back(node); 35 | } 36 | } 37 | } 38 | 39 | return subTree; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /C++/getPermutation.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n^2) 2 | // Space Complexity: O(n) 3 | 4 | class Solution { 5 | public: 6 | string getPermutation(int n, int k) { 7 | string s(n, '0'); 8 | 9 | for(int i = 0; i < n; ++i) { 10 | s[i] += i + 1; 11 | } 12 | 13 | return kth_permutation(s, k); 14 | } 15 | 16 | private: 17 | int factorial(int n) { 18 | int sum = 1; 19 | for(int i = n; i >= 1; --i) { 20 | sum *= i; 21 | } 22 | return sum; 23 | } 24 | 25 | // Cantor Encoding 26 | template 27 | Sequence kth_permutation(const Sequence &seq, int k) { 28 | const int n = seq.size(); 29 | Sequence ans; 30 | Sequence S(seq); 31 | int base = factorial(n - 1); 32 | --k; 33 | 34 | for(int i = n - 1; i > 0; k %= base, base /= i, --i) { 35 | auto a = next(S.begin(), k / base); 36 | ans.push_back(*a); 37 | S.erase(a); 38 | } 39 | 40 | ans.push_back(S[0]); 41 | 42 | return ans; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /C++/getRow.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | vector getRow(int rowIndex) { 7 | vector ans(rowIndex + 1, 1); 8 | 9 | for(int i = 2; i <= rowIndex; ++i) { 10 | for(int j = i - 1; j > 0; --j) { 11 | ans[j] += ans[j - 1]; 12 | } 13 | } 14 | 15 | return ans; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /C++/hasCycle.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | bool hasCycle(ListNode *head) { 15 | ListNode *slow = head, *fast = head; 16 | 17 | while(fast && fast->next) { 18 | slow = slow->next; 19 | fast = fast->next->next; 20 | 21 | if(slow == fast) 22 | return true; 23 | } 24 | 25 | return false; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /C++/hasPathSum.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(n) 3 | 4 | /** 5 | * Definition for binary tree 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | 16 | bool hasPathSum(TreeNode *root, int sum) { 17 | if(!root) 18 | return false; 19 | 20 | if(!root->left && !root->right) 21 | return sum == root->val; 22 | 23 | return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val); 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /C++/insert.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | /** 5 | * Definition for an interval. 6 | * struct Interval { 7 | * int start; 8 | * int end; 9 | * Interval() : start(0), end(0) {} 10 | * Interval(int s, int e) : start(s), end(e) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | vector insert(vector &intervals, Interval newInterval) { 16 | vector ans; 17 | auto n = intervals.size(); 18 | for(int i = 0; i < n; ++i) { 19 | if (newInterval.end < intervals[i].start) { // not overlapped 20 | ans.push_back(newInterval); 21 | for(; i < n; ++i) 22 | ans.push_back(intervals[i]); 23 | return ans; 24 | } 25 | else if (newInterval.start > intervals[i].end) { // not overlapped 26 | ans.push_back(intervals[i]); 27 | } 28 | else { // merge 29 | newInterval.start = min(newInterval.start, intervals[i].start); 30 | newInterval.end = max(newInterval.end, intervals[i].end); 31 | } 32 | } 33 | 34 | ans.push_back(newInterval); 35 | return ans; 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /C++/insertionSortList.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n^2) 2 | // Space Complexity: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | ListNode *insertionSortList(ListNode *head) { 15 | ListNode dummy(INT_MIN); 16 | 17 | ListNode *cur = head; 18 | ListNode *prev = NULL; 19 | ListNode *pos = head; 20 | 21 | while(cur) { 22 | pos = findInsertPos(&dummy, cur->val); 23 | ListNode *tmp = cur->next; 24 | cur->next = pos->next; 25 | pos->next = cur; 26 | cur = tmp; 27 | } 28 | 29 | return dummy.next; 30 | } 31 | 32 | ListNode* findInsertPos(ListNode *head, int x) { 33 | ListNode *pre = NULL; 34 | for (ListNode *cur = head; cur && cur->val <= x; 35 | pre = cur, cur = cur->next); 36 | return pre; 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /C++/isInterleave.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(m * n) 2 | // Space Complexity: O(m + n) 3 | 4 | class Solution { 5 | public: 6 | bool isInterleave(string s1, string s2, string s3) { 7 | if(s1.length() + s2.length() != s3.length()) return false; 8 | 9 | if(s1.length() < s2.length()) return isInterleave(s2, s1, s3); 10 | 11 | vector f(s2.length() + 1, true); 12 | 13 | for(auto j = 1; j <= s2.length(); ++j) { 14 | f[j] = f[j - 1] && s2[j - 1] == s3[j - 1]; 15 | } 16 | 17 | for(auto i = 1; i <= s1.length(); ++i) { 18 | f[0] = f[0] && s1[i - 1] == s3[i - 1]; 19 | for(auto j = 1; j <= s2.length(); ++j) { 20 | f[j] = (f[j] && s1[i - 1] == s3[i + j - 1]) 21 | || (f[j - 1] && s2[j - 1] == s3[i + j - 1]); 22 | } 23 | } 24 | 25 | return f[s2.length()]; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /C++/isMatch.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(m * n) ? 2 | // Space Complexity: O(m * n) ? 3 | 4 | class Solution { 5 | public: 6 | bool isMatch(const char *s, const char *p) { 7 | if(*p == 0) return *s == 0; 8 | 9 | if(*(p + 1) != '*') { 10 | if(*s != 0 && (*p == *s || *p == '.')) { 11 | return isMatch(s + 1, p + 1); 12 | } 13 | else 14 | return false; 15 | } 16 | else { 17 | while(*s != 0 && (*p == *s || *p == '.')) { // spanning the char 18 | if(isMatch(s, p + 2)) 19 | return true; 20 | ++s; 21 | } 22 | return isMatch(s, p + 2); 23 | } 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /C++/isPalindrome.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | bool isPalindrome(int x) { 7 | if(x < 0) 8 | return false; 9 | 10 | int d = 1; 11 | for(; x / d >= 10 ; d *= 10); 12 | 13 | for(; x > 0; x = (x % d) / 10, d /= 100) { 14 | int q = x / d; 15 | int r = x % 10; 16 | if(q != r) 17 | return false; 18 | } 19 | 20 | return true; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /C++/isPalindromeII.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | bool isPalindrome(string s) { 7 | transform(s.begin(), s.end(), s.begin(), ::tolower); 8 | auto left = s.begin(); 9 | auto right = prev(s.end()); 10 | for(; left < right;) { 11 | if(!isalnum(*left)) 12 | ++left; 13 | else if(!isalnum(*right)) 14 | --right; 15 | else if(*left != *right) 16 | return false; 17 | else { 18 | ++left; 19 | --right; 20 | } 21 | } 22 | return true; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /C++/isValid.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | bool isValid(string s) { 7 | const string left = "([{"; 8 | const string right = ")]}"; 9 | stack stack; 10 | for(auto c : s) { 11 | if(left.find(c) != string::npos) { 12 | stack.push(c); 13 | } 14 | else if (right.find(c) != string::npos){ 15 | if(!stack.empty() && stack.top() == left[right.find(c)]) { 16 | stack.pop(); 17 | } 18 | else 19 | return false; 20 | } 21 | } 22 | 23 | return stack.empty(); 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /C++/isValidBST.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(logn) 3 | 4 | /** 5 | * Definition for binary tree 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | bool isValidBST(TreeNode *root) { 16 | if(!root) 17 | return true; 18 | 19 | if(!isValidBST(root->left)) 20 | return false; 21 | 22 | if(last && last != root && last->val >= root->val) 23 | return false; 24 | 25 | last = root; 26 | 27 | if(!isValidBST(root->right)) 28 | return false; 29 | 30 | return true; 31 | } 32 | 33 | private: 34 | TreeNode *last; 35 | }; 36 | -------------------------------------------------------------------------------- /C++/isValidBST2.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(logn) 3 | 4 | /** 5 | * Definition for binary tree 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | bool isValidBST(TreeNode *root) { 16 | return isValidBST(root, INT_MIN, INT_MAX); 17 | } 18 | 19 | private: 20 | bool isValidBST(TreeNode *root, int lower, int upper) { 21 | if(!root) 22 | return true; 23 | return root->val > lower && root->val < upper 24 | && isValidBST(root->left, lower, root->val) 25 | && isValidBST(root->right, root->val, upper); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /C++/jump.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | int jump(int A[], int n) { 7 | int ans = 0; 8 | int last = 0; 9 | int cur = 0; // at most position by further jump 10 | for(int i = 0, next; i < n; ++i) { 11 | if(i > last) { // he cannot reach "i" by current jumps 12 | ++ans; // so he should jump one more time 13 | last = cur; // to reach at most position 14 | } 15 | cur = max(cur, i + A[i]); // update at most position by further jump 16 | } 17 | return ans; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /C++/largestRectangleArea.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(n) 3 | 4 | Solution { 5 | public: 6 | int largestRectangleArea(vector &height) { 7 | const int n = height.size(); 8 | stack s; 9 | int ans = 0; 10 | if(n == 0) return 0; 11 | 12 | height.push_back(0); 13 | 14 | for(int i = 0; i < n + 1;) { 15 | if(s.empty() || height[s.top()] < height[i]) 16 | s.push(i++); 17 | else { 18 | int tmp = s.top(); 19 | s.pop(); 20 | ans = max(ans, height[tmp] * (s.empty()? i : i - s.top() - 1)); 21 | } 22 | } 23 | return ans; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /C++/lengthOfLastWord.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | int lengthOfLastWord(const char *s) { 7 | int len = 0; 8 | for(; *s; ++s) { 9 | if (*s != ' ') 10 | ++len; 11 | else if (*(s+1) && *(s+1) != ' ') 12 | len = 0; 13 | } 14 | return len; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /C++/lengthOfLongestSubstring.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | int lengthOfLongestSubstring(string s) { 7 | vector last(26, -1); 8 | int start = 0; 9 | int ans = 0; 10 | 11 | for(int i = 0; i < s.size(); ++i) { 12 | if(last[s[i] - 'a'] >= start) { // meet a repeated character 13 | ans = max(i - start, ans); // recount max length of substring 14 | start = last[s[i] - 'a'] + 1; // update start index next to the repeated one 15 | } 16 | last[s[i] - 'a'] = i; // update last index 17 | } 18 | 19 | return max(static_cast(s.size()) - start, ans); // recount max length of substring due to end 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /C++/letterCombinations.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(3^n) 2 | // Space Complexity: O(n) 3 | 4 | class Solution { 5 | public: 6 | const vector keyboard { " ", "", "abc", "def", // '0','1','2',... 7 | "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; 8 | 9 | vector letterCombinations(string digits) { 10 | vector ans; 11 | string path; 12 | dfs(digits, 0, path, ans); 13 | return ans; 14 | } 15 | 16 | private: 17 | void dfs(const string &digits, size_t cur, string &path, vector &ans) { 18 | if(cur == digits.size()) { 19 | ans.push_back(path); 20 | return; 21 | } 22 | 23 | for(auto c: keyboard[digits[cur] - '0']) { 24 | path.push_back(c); 25 | dfs(digits, cur + 1, path, ans); 26 | path.pop_back(); 27 | } 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /C++/longestCommonLength.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n1 + n2 + ...) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | string longestCommonPrefix(vector &strs) { 7 | if(strs.empty()) 8 | return ""; 9 | for(int idx = 0; idx < strs[0].size(); ++idx) { 10 | for(int i = 1; i < strs.size(); ++i) { 11 | if(strs[0][idx] != strs[i][idx]) 12 | return strs[0].substr(0, idx); 13 | } 14 | } 15 | 16 | return strs[0]; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /C++/longestConsecutive.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(n) 3 | 4 | class Solution { 5 | public: 6 | int longestConsecutive(vector &num) { 7 | if (num.size() == 0) 8 | return 0; 9 | unordered_map hash; 10 | int ans{1}; 11 | for (auto &i: num) { 12 | if (hash[i] != 0) { 13 | continue; 14 | } 15 | hash[i] = 1; 16 | int leftbound{hash[i - 1]}, rightbound{hash[i + 1]}; // get neighbor info 17 | hash[i - leftbound] = hash[i + rightbound] = 1 + leftbound + rightbound; // update left and right bound info 18 | ans = max(ans, 1 + leftbound + rightbound); 19 | } 20 | return ans; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /C++/maxArea.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | int maxArea(vector &height) { 7 | int start = 0, end = height.size() - 1, ans = 0; 8 | 9 | while(start < end) { 10 | if(height[start] <= height[end]) { 11 | ans = max(ans, height[start] * (end - start)); 12 | start++; 13 | } 14 | if(height[start] > height[end]) { 15 | ans = max(ans, height[end] * (end - start)); 16 | end--; 17 | } 18 | } 19 | return ans; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /C++/maxDepth.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for binary tree 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 | * }; 9 | */ 10 | class Solution { 11 | public: 12 | int maxDepth(TreeNode *root) { 13 | if(!root) 14 | return 0; 15 | return max(maxDepth(root->left), maxDepth(root->right))+1; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /C++/maxPathSum.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(logn) 3 | 4 | /** 5 | * Definition for binary tree 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | int maxPathSum(TreeNode *root) { 16 | max_sum = INT_MIN; 17 | dfs(root); 18 | return max_sum; 19 | 20 | } 21 | private: 22 | int max_sum; 23 | int dfs(const TreeNode *root) { 24 | if(!root) return 0; 25 | int l = dfs(root->left); 26 | int r = dfs(root->right); 27 | int sum = root->val; 28 | if(l > 0) sum += l; 29 | if(r > 0) sum += r; 30 | max_sum = max(max_sum, sum); 31 | return max(r, l) > 0? max(r, l) + root->val : root->val; 32 | } 33 | 34 | }; 35 | -------------------------------------------------------------------------------- /C++/maxProfitI.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | int maxProfit(vector &prices) { 7 | const int n = prices.size(); 8 | 9 | if(n < 2) 10 | return 0; 11 | 12 | // Greedy Algorithm 13 | int ans = 0; 14 | for(int i = 1, valley = prices[0]; i < n; ++i) { 15 | ans = max(ans, prices[i] - valley); 16 | valley = min(valley, prices[i]); 17 | } 18 | 19 | return ans; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /C++/maxProfitII.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | int maxProfit(vector &prices) { 7 | const int n = prices.size(); 8 | int ans = 0; 9 | 10 | for(int i = 1; i < n; ++i) { 11 | int diff = prices[i] - prices[i - 1]; 12 | if(diff > 0) 13 | ans += diff; 14 | } 15 | 16 | return ans; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /C++/maxProfitIII.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(n) 3 | 4 | class Solution { 5 | public: 6 | int maxProfit(vector &prices) { 7 | const int n = prices.size(); 8 | 9 | if(n < 2) 10 | return 0; 11 | 12 | vector f(n, 0); 13 | vector g(n, 0); 14 | 15 | for(int i = 1, valley = prices[0]; i < n; ++i) { 16 | f[i] = max(f[i - 1], prices[i] - valley); 17 | valley = min(valley, prices[i]); 18 | } 19 | 20 | for(int i = n - 2, peak = prices[n - 1]; i >= 0; --i) { 21 | g[i] = max(g[i + 1], peak - prices[i]); 22 | peak = max(peak, prices[i]); 23 | } 24 | 25 | int ans = 0; 26 | for(int i = 0; i < n; ++i) { 27 | ans = max(ans, f[i] + g[i]); 28 | } 29 | 30 | return ans; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /C++/merge2.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(nlogn) 2 | // Space Complexity: O(1) 3 | 4 | /** 5 | * Definition for an interval. 6 | * struct Interval { 7 | * int start; 8 | * int end; 9 | * Interval() : start(0), end(0) {} 10 | * Interval(int s, int e) : start(s), end(e) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | vector merge(vector &intervals) { 16 | vector ans; 17 | sort(intervals.begin(), intervals.end(), 18 | [](const Interval &v1, const Interval &v2) { return v1.start < v2.start; } 19 | ); 20 | const int n = intervals.size(); 21 | for(int i = 0; i < n;) { 22 | ans.push_back(intervals[i++]); 23 | while(i < n && intervals[i].start <= ans.back().end) 24 | ans.back().end = max(ans.back().end, intervals[i++].end); 25 | } 26 | return ans; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /C++/minCut.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n^2) 2 | // Space Complexity: O(n^2) 3 | 4 | class Solution { 5 | public: 6 | int minCut(string s) { 7 | const int n = s.size(); 8 | vector > p(n, vector(n, false)); // p[i][j]: range [i, j] is a palindrome paritioning of s 9 | vector f(n + 1, 0); // f[i]: minimum cuts in range [i, n - 1] 10 | 11 | for(int i = 0; i <= n; ++i) { 12 | f[i] = n - 1 - i; // initialize f[i] to the max cuts 13 | } 14 | 15 | for (int i = n - 1; i >= 0; --i) { 16 | for (int j = i; j < n; ++j) { 17 | // [i, j] is palindrome if only if s[i] equals to s[j] and [i + 1, j - 1] is palindrome too 18 | if(s[i] == s[j] && ((j - i < 2) || p[i + 1][j - 1])) { 19 | p[i][j] = true; 20 | f[i] = min(f[i], f[j + 1] + 1); // f[i] = min(f[j + 1] + 1) for each i <= j <= n - 1 21 | } 22 | } 23 | } 24 | 25 | return f[0]; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /C++/minDepth.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(n) 3 | 4 | /** 5 | * Definition for binary tree 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | int minDepth(TreeNode *root) { 16 | if(!root) 17 | return 0; 18 | 19 | queue q; 20 | int d = 1; 21 | q.push(root); 22 | int cnt = q.size(); 23 | 24 | // BFS 25 | while(!q.empty()) { 26 | TreeNode *n = q.front(); 27 | q.pop(); 28 | 29 | if(!n->left && !n->right) 30 | return d; 31 | if(n->left) 32 | q.push(n->left); 33 | if(n->right) 34 | q.push(n->right); 35 | 36 | cnt--; 37 | if(!cnt) { 38 | cnt = q.size(); 39 | d++; 40 | } 41 | } 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /C++/minDistance.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(m * n) 2 | // Space Complexity: O(m + n) 3 | 4 | class Solution { 5 | public: 6 | int minDistance(string word1, string word2) { 7 | const size_t m = word1.size(); 8 | const size_t n = word2.size(); 9 | 10 | if(m < n) 11 | return minDistance(word2, word1); 12 | 13 | vector f(n + 1, 0); 14 | size_t upper_left; 15 | 16 | for(size_t i = 0; i < n + 1; ++i) 17 | f[i] = i; 18 | 19 | for(size_t i = 1; i < m + 1; ++i) { 20 | upper_left = f[0]; 21 | f[0] = i; 22 | for(size_t j = 1; j < n + 1; ++j) { 23 | size_t upper = f[j]; 24 | if(word1[i - 1] == word2[j - 1]) 25 | f[j] = upper_left; 26 | else { 27 | f[j] = 1 + min(upper_left, min(f[j - 1], f[j])); 28 | } 29 | upper_left = upper; 30 | } 31 | } 32 | 33 | return f[n]; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /C++/minPathSum.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(mn) 2 | // Space Complexity: O(mn) 3 | 4 | class Solution { 5 | public: 6 | unordered_map > hash; 7 | int minPathSumeImpl(vector > &grid, int i, int j) { 8 | if(hash.find(i) != hash.end() && hash[i].find(j) != hash[j].end()) 9 | return hash[i][j]; 10 | if(i == 0 && j == 0) 11 | return grid[i][j]; 12 | if(i < 0 || j < 0) 13 | return INT_MAX; 14 | return hash[i][j] = grid[i][j] + min(minPathSumeImpl(grid, i-1, j), minPathSumeImpl(grid, i, j-1)); 15 | } 16 | 17 | int minPathSum(vector > &grid) { 18 | return minPathSumeImpl(grid, grid.size()-1, grid[0].size()-1); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /C++/minimumTotal.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n^2) 2 | // Space Complexity: O(n) 3 | 4 | class Solution { 5 | public: 6 | int minimumTotal(vector > &triangle) { 7 | const int N = triangle.size(); 8 | vector f(N, INT_MAX); 9 | int ans = INT_MAX; 10 | 11 | f[0] = triangle[0][0]; 12 | for(int i = 1; i < N; ++i) { 13 | for(int j = i; j > 0; --j) { 14 | f[j] = min(f[j], f[j - 1]) + triangle[i][j]; 15 | } 16 | f[0] += triangle[i][0]; 17 | } 18 | 19 | for(int i = 0; i < N; ++i) { 20 | ans = min(ans, f[i]); 21 | } 22 | 23 | return ans; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /C++/minimumTotal2.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n^2) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | int minimumTotal(vector > &triangle) { 7 | const int N = triangle.size(); 8 | 9 | for(int i = N - 2; i >= 0; --i) { 10 | for(int j = 0; j < i + 1; ++j) { 11 | triangle[i][j] += min(triangle[i + 1][j], triangle[i + 1][j + 1]); 12 | } 13 | } 14 | 15 | return triangle[0][0]; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /C++/nextPermutation.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | void nextPermutation(vector &num) { 7 | nextPermutation(begin(num), end(num)); 8 | } 9 | 10 | private: 11 | template 12 | bool nextPermutation(BidiIt begin, BidiIt end) { 13 | const auto rbegin = reverse_iterator(end); 14 | const auto rend = reverse_iterator(begin); 15 | 16 | // find the firt element (pivot) which is less than its successor 17 | auto pivot = next(rbegin); 18 | while(pivot != rend && *pivot >= *prev(pivot)) { 19 | ++pivot; 20 | } 21 | 22 | // no next permutation, just reverse the whole sequence 23 | if(pivot == rend) { 24 | reverse(rbegin, rend); 25 | return false; 26 | } 27 | 28 | // find the number which is greater than pivot, and swap it with pivot 29 | auto change = find_if(rbegin, pivot, bind1st(less(), *pivot)); 30 | swap(*change, *pivot); 31 | 32 | // make the sequence after pivot non-descending 33 | reverse(rbegin, pivot); 34 | 35 | return true; // return next permutation 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /C++/numDecodings.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | int numDecodings(string s) { 7 | if(s.empty()) return 0; 8 | 9 | int prev = 0; // f[n - 2] 10 | int cur = 1; // f[n - 1] 11 | 12 | for(int i = 1; i <= s.length(); ++i) { 13 | if(s[i - 1] == '0') 14 | cur = 0; // f[n - 1] = 0 15 | if(i < 2 || !(s[i - 2] == '1' || (s[i - 2] == '2' && s[i - 1] <= '6'))) 16 | prev = 0; // f[n - 2] = 0; 17 | 18 | int tmp = cur; 19 | cur += prev; // f[n] = f[n - 1] + f[n - 2] 20 | prev = tmp; 21 | } 22 | 23 | return cur; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /C++/numDistinct.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(m * n) 2 | // Space Complexity: O(n) 3 | 4 | class Solution { 5 | public: 6 | int numDistinct(const string &S, const string &T) { 7 | vector f(T.size() + 1); 8 | f[0] = 1; // f(0, 0) = 1, means S = "" and T = "", there is only one distinct subsequence, i.e. "" 9 | for (int i = 1; i <= S.size(); ++i) { 10 | for (int j = T.size(); j > 0; --j) { 11 | // f(i, j) is composed of: 12 | // f(i−1,j): not using S[i - 1] 13 | // f(i−1,j−1): using S[i - 1] if S[i - 1] == S[j - 1] 14 | f[j] += (S[i - 1] == T[j - 1]) ? f[j - 1] : 0; 15 | } 16 | } 17 | return f[T.size()]; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /C++/palindromePartition.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: average: O(n^2), worst: O(n^2 * 2^n) 2 | // Space Complexity: average: O(1), worst: O(2^n) 3 | 4 | class Solution { 5 | public: 6 | vector > partition(string s) { 7 | const int n = s.size(); 8 | bool p[n][n]; 9 | 10 | fill_n(&p[0][0], n * n, false); 11 | 12 | for (int i = n - 1; i >= 0; --i) 13 | for (int j = i; j < n; ++j) 14 | p[i][j] = s[i] == s[j] && ((j - i < 2) || p[i + 1][j - 1]); 15 | 16 | vector > sub_palins[n]; 17 | for (int i = n - 1; i >= 0; --i) { 18 | for (int j = i; j < n; ++j) 19 | if (p[i][j]) { 20 | const string palindrome = s.substr(i, j - i + 1); 21 | if (j + 1 < n) { 22 | for (auto v : sub_palins[j + 1]) { 23 | v.insert(v.begin(), palindrome); 24 | sub_palins[i].push_back(v); 25 | } 26 | } 27 | else { 28 | sub_palins[i].push_back(vector { palindrome }); 29 | } 30 | } 31 | } 32 | 33 | return sub_palins[0]; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /C++/palindromePartition2.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(2^n) 2 | // Space Complexity: O(n^2) 3 | 4 | class Solution { 5 | public: 6 | vector > partition(string s) { 7 | const int n = s.size(); 8 | vector > p(n, vector(n, false)); 9 | vector path; 10 | vector > ans; 11 | buildPalindromeMap(s, p); 12 | dfs(s, p, 0, path, ans); 13 | return ans; 14 | } 15 | private: 16 | void buildPalindromeMap(const string &s, vector > &p) { 17 | for (int i = s.size() - 1; i >= 0; --i) 18 | for (int j = i; j < s.size(); ++j) 19 | p[i][j] = s[i] == s[j] && ((j - i < 2) || p[i + 1][j - 1]); 20 | } 21 | void dfs(const string &s, const vector > &p, int start, 22 | vector &path, vector > &ans) { 23 | if(start == s.size()) { 24 | ans.push_back(path); 25 | return; 26 | } 27 | for(size_t i = start; i < s.size(); ++i) { 28 | if(p[start][i]) { 29 | path.push_back(s.substr(start, i - start + 1)); 30 | dfs(s, p, i + 1, path, ans); 31 | path.pop_back(); 32 | } 33 | } 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /C++/partition.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | ListNode *partition(ListNode *head, int x) { 15 | ListNode left_dummy(-1); 16 | ListNode right_dummy(-1); 17 | auto left_cur = &left_dummy; 18 | auto right_cur = &right_dummy; 19 | 20 | for(auto cur = head; cur; cur = cur->next) { 21 | if(cur->val < x) { 22 | left_cur->next = cur; 23 | left_cur = cur; 24 | } 25 | else { 26 | right_cur->next = cur; 27 | right_cur = cur; 28 | } 29 | } 30 | 31 | left_cur->next = right_dummy.next; 32 | right_cur->next = nullptr; 33 | return left_dummy.next; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /C++/pathSum.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(logn) 3 | 4 | /** 5 | * Definition for binary tree 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | vector > pathSum(TreeNode *root, int sum) { 16 | pathSumImpl(root, sum); 17 | return ans; 18 | } 19 | private: 20 | vector v; 21 | vector > ans; 22 | 23 | void pathSumImpl(TreeNode *root, int sum) { 24 | if(!root) { 25 | return; 26 | } 27 | 28 | v.push_back(root->val); 29 | 30 | if(!root->left && !root->right && root->val == sum) { 31 | ans.push_back(v); 32 | } 33 | 34 | pathSumImpl(root->left, sum - root->val); 35 | pathSumImpl(root->right, sum - root->val); 36 | 37 | v.pop_back(); // restore 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /C++/permuteUnique.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n!) 2 | // Space Complexity: O(n) 3 | 4 | class Solution { 5 | public: 6 | vector > permuteUnique(vector& num) { 7 | sort(num.begin(), num.end()); 8 | unordered_map count_map; 9 | for(auto e : num) { 10 | if (count_map.find(e) != count_map.end()) 11 | count_map[e]++; 12 | else 13 | count_map[e] = 1; 14 | } 15 | 16 | vector > ans; 17 | vector path; 18 | n = num.size(); 19 | permute(count_map, path, ans); 20 | 21 | return ans; 22 | } 23 | 24 | private: 25 | size_t n; 26 | void permute(unordered_map &count_map, vector &path, vector > &ans) { 27 | if (n == path.size()) { 28 | ans.push_back(path); 29 | } 30 | 31 | for (auto i = count_map.begin(); i != count_map.end(); ++i) { 32 | if (i->second) { 33 | path.push_back(i->first); 34 | i->second--; 35 | permute(count_map, path, ans); 36 | path.pop_back(); 37 | i->second++; 38 | } 39 | } 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /C++/plusOne.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | vector plusOne(vector &digits) { 7 | int c = 1; 8 | 9 | for(auto it = digits.rbegin(); it != digits.rend(); ++it) { 10 | *it += c; 11 | c = *it / 10; 12 | *it %= 10; 13 | } 14 | 15 | if(c > 0) { 16 | digits.insert(digits.begin(), 1); 17 | } 18 | 19 | return digits; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /C++/pow.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(logn) 2 | // Space Complexity: O(logn) 3 | 4 | class Solution { 5 | public: 6 | double pow(double x, int n) { 7 | if(n < 0) 8 | return 1.0 / power(x, -n); // be careful: -1 * -2147483648 is still -2147483648 9 | else 10 | return power(x, n); 11 | } 12 | 13 | private: 14 | double power(double x, int n) { 15 | if(n == 0) 16 | return 1; 17 | double v = power(x, n / 2); 18 | 19 | if(n % 2 != 0) 20 | return v * v * x; 21 | else 22 | return v * v; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /C++/removeDuplicates.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | int removeDuplicates(int A[], int n) { 7 | const int occur = 2; 8 | if(n <= occur) return n; 9 | 10 | int cnt = occur; 11 | 12 | for(int i = occur; i < n; ++i) { 13 | if(A[i] != A[cnt - occur]) 14 | A[cnt++] = A[i]; 15 | } 16 | 17 | return cnt; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /C++/removeNthFromEnd.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | ListNode *removeNthFromEnd(ListNode *head, int n) { 15 | ListNode *slow = head, *fast = head, *pre = NULL; 16 | 17 | while(n > 0) { 18 | fast = fast->next; 19 | --n; 20 | } 21 | 22 | while(fast) { 23 | pre = slow; 24 | slow = slow->next; 25 | fast = fast->next; 26 | } 27 | 28 | if(!pre && !slow->next) 29 | return NULL; 30 | 31 | if(!pre && slow->next) 32 | return slow->next; 33 | 34 | pre->next = slow->next; 35 | delete slow; 36 | 37 | return head; 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /C++/restoreIpAddresses.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n^m), where n is max length of number, m is count of segment 2 | // Space Complexity: O(nm) 3 | 4 | class Solution { 5 | public: 6 | vector restoreIpAddresses(string s) { 7 | vector ans; 8 | dfs(s, 0, 4, "", ans); 9 | return ans; 10 | } 11 | 12 | private: 13 | void dfs(const string &s, int start, int step, string ip, vector &ans) { 14 | if(start == s.size() && step == 0) { 15 | ip.pop_back(); 16 | ans.push_back(ip); 17 | return; 18 | } 19 | 20 | if(s.size() - start < step || s.size() - start > step * 3) // pruing 21 | return; 22 | 23 | int num = 0; 24 | for(int i = start; i < start + 3; ++i) { 25 | num = num * 10 + s[i] - '0'; 26 | if(num > 255) break; 27 | ip += s[i]; 28 | dfs(s, i + 1, step - 1, ip + '.', ans); 29 | if(num == 0) break; // only one 0 30 | } 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /C++/reverseBetween.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | ListNode *reverseBetween(ListNode *head, int m, int n) { 15 | ListNode dummy(-1); 16 | dummy.next = head; 17 | 18 | ListNode *prev = &dummy; 19 | 20 | for(int i = 0; i < m - 1; ++i) { 21 | prev = prev->next; 22 | } 23 | 24 | ListNode *const head2 = prev; 25 | 26 | prev = prev->next; 27 | ListNode *cur = prev->next; 28 | 29 | for(int i = m; i < n; ++i) { 30 | prev->next = cur->next; // remove cur from the list 31 | cur->next = head2->next; // add cur to the head 32 | head2->next = cur; // add cur to the head 33 | cur = prev->next; // get next cur 34 | } 35 | 36 | return dummy.next; 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /C++/reverseWords.cpp: -------------------------------------------------------------------------------- 1 | // Complexity: 2 | // O(n) time 3 | // O(n) space 4 | 5 | class Solution { 6 | public: 7 | void reverseWords(string &s) 8 | { 9 | string rs; 10 | for (int i = s.length()-1; i >= 0; ) 11 | { 12 | while (i >= 0 && s[i] == ' ') i--; 13 | if (i < 0) break; 14 | if (!rs.empty()) rs.push_back(' '); 15 | string t; 16 | while (i >= 0 && s[i] != ' ') t.push_back(s[i--]); 17 | reverse(t.begin(), t.end()); 18 | rs.append(t); 19 | } 20 | s = rs; 21 | } 22 | }; -------------------------------------------------------------------------------- /C++/rotate.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n^2) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | void rotate(vector > &matrix) { 7 | int n = matrix.size(); 8 | for(int i = 0; i < n / 2; i++) { 9 | for(int j = i; j < n - 1 - i; j++) { 10 | int tmp = matrix[i][j]; 11 | matrix[i][j] = matrix[n-1-j][i]; 12 | matrix[n-1-j][i] = matrix[n-1-i][n-1-j]; 13 | matrix[n-1-i][n-1-j]= matrix[j][n-1-i]; 14 | matrix[j][n-1-i] = tmp; 15 | } 16 | } 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /C++/rotateRight.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | ListNode *rotateRight(ListNode *head, int k) { 15 | ListNode dummy(INT_MIN); 16 | dummy.next = head; 17 | ListNode *p = &dummy; 18 | for(int i = 0; p && i < k; ++i) { 19 | p = p->next; 20 | if(!p) 21 | p = dummy.next; 22 | } 23 | 24 | if(!p || !p->next) 25 | return dummy.next; 26 | 27 | ListNode *cur = &dummy; 28 | for(; p->next; cur = cur->next, p = p->next); // find new head 29 | p->next = dummy.next; // connect tail to the head 30 | dummy.next = cur->next; // update new head 31 | cur->next = NULL; // update new tail 32 | 33 | return dummy.next; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /C++/search.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(logn) 2 | // O(n) if duplicates are allowed 3 | // Space Complexity: O(1) 4 | 5 | class Solution { 6 | public: 7 | bool search(int A[], int n, int target) { 8 | for(int start = 0, end = n; start < end; ) { 9 | const int mid = (start + end) / 2; 10 | if(A[mid] == target) 11 | return true; 12 | if(A[start] < A[mid]) { 13 | if(A[start] <= target && target < A[mid]) 14 | end = mid; 15 | else 16 | start = mid + 1; 17 | } 18 | else if(A[start] > A[mid]) { 19 | if(A[mid] < target && target <= A[end - 1]) 20 | start = mid + 1; 21 | else 22 | end = mid; 23 | } 24 | else 25 | ++start; 26 | } 27 | return false; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /C++/searchMatrix.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(m+n) (Akra-Bazzi theorem) 2 | // Space Complexity: O(log(mn)) 3 | 4 | class Solution { 5 | public: 6 | bool partitionAndSearch(vector > &matrix, int target, int i, int j, int m, int n) { 7 | if(m < 1 || n < 1) 8 | return false; 9 | int start, end; 10 | for(start = 0, end = min(m, n); start < end;) { 11 | int tmp = (start+end)/2; 12 | if(target < matrix[i+tmp][j+tmp]) 13 | end = tmp; 14 | else if (target > matrix[i+tmp][j+tmp]) 15 | start = tmp+1; 16 | else 17 | return true; 18 | } 19 | if(start < 1) 20 | return false; 21 | return partitionAndSearch(matrix, target, i, j+start, m, n - start) 22 | || partitionAndSearch(matrix, target, i+start, j, m - start, n); 23 | } 24 | bool searchMatrix(vector > &matrix, int target) { 25 | return partitionAndSearch(matrix, target, 0, 0, matrix.size(), matrix[0].size()); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /C++/searchMatrix2.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(log(mn)) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | bool searchMatrix(vector > &matrix, int target) { 7 | if(matrix.empty()) return false; 8 | 9 | const size_t m = matrix.size(); 10 | const size_t n = matrix.front().size(); 11 | 12 | int start = 0, end = m * n; 13 | 14 | while(start < end) { 15 | int mid = (start + end) / 2; 16 | int value = matrix[mid / n][mid % n]; 17 | if(target == value) 18 | return true; 19 | else if (value < target) 20 | start = mid + 1; 21 | else 22 | end = mid; 23 | } 24 | return false; 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /C++/searchRange.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(logn) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | vector searchRange(int A[], int n, int target) { 7 | int begin = lower_bound(A, n, target); 8 | int end = upper_bound(A, n, target); 9 | 10 | if(begin < n && A[begin] == target) 11 | return {begin, end - 1}; 12 | 13 | return {-1, -1}; 14 | } 15 | 16 | private: 17 | int lower_bound(int A[], int n, int target) { 18 | int begin = 0; 19 | int end = n; 20 | while(begin < end) { 21 | int mid = (begin + end) / 2; 22 | if(A[mid] < target) 23 | begin = mid + 1; 24 | else 25 | end = mid; 26 | } 27 | return begin; 28 | } 29 | 30 | int upper_bound(int A[], int n, int target) { 31 | int begin = 0; 32 | int end = n; 33 | while(begin < end) { 34 | int mid = (begin + end) / 2; 35 | if(A[mid] <= target) 36 | begin = mid + 1; 37 | else 38 | end = mid; 39 | } 40 | return begin; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /C++/simplifyPath.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(n) 3 | 4 | class Solution { 5 | public: 6 | string simplifyPath(string path) { 7 | vector dirs; 8 | 9 | for(auto i = path.cbegin(); i != path.cend();) { 10 | ++i; // write here is to make sure i is not end 11 | 12 | auto j = find(i, path.cend(), '/'); 13 | string dir = string(i, j); 14 | 15 | if(!dir.empty() && dir != ".") { 16 | if(dir == "..") { 17 | if(!dirs.empty()) dirs.pop_back(); 18 | } 19 | else 20 | dirs.push_back(dir); 21 | } 22 | i = j; // i may be end 23 | } 24 | 25 | if(dirs.empty()) return "/"; 26 | 27 | string ans; 28 | for(auto dir : dirs) { 29 | ans.append("/" + dir); 30 | } 31 | 32 | return ans; 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /C++/sortColors.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | // One-Pass Algorithm 4 | class Solution { 5 | public: 6 | void sortColors(int A[], int n) { 7 | int red = 0; 8 | int blue = n-1; 9 | for(int i = 0; i < blue + 1;) { 10 | if(A[i] == 0) { 11 | swap(A[i++], A[red++]); 12 | } 13 | else if(A[i] == 2) { 14 | swap(A[i], A[blue--]); 15 | } 16 | else { 17 | i++; 18 | } 19 | } 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /C++/sortedListToBST.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(logn) 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | /** 13 | * Definition for binary tree 14 | * struct TreeNode { 15 | * int val; 16 | * TreeNode *left; 17 | * TreeNode *right; 18 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 19 | * }; 20 | */ 21 | class Solution { 22 | public: 23 | TreeNode *sortedListToBST(ListNode *head) { 24 | int len = 0; 25 | 26 | ListNode *p = head; 27 | while(p) { 28 | p = p->next; 29 | ++len; 30 | } 31 | 32 | return sortedListToBST(head, len); 33 | } 34 | 35 | private: 36 | TreeNode *sortedListToBST(ListNode *&head, int len) { 37 | if(!len || !head) 38 | return NULL; 39 | TreeNode *left = sortedListToBST(head, len / 2); 40 | TreeNode *parent = new TreeNode(head->val); 41 | parent->left = left; 42 | head = head->next; 43 | parent->right = sortedListToBST(head, (len % 2 != 0)? len / 2: len / 2 - 1); 44 | return parent; 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /C++/sqrt.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | int sqrt(int x) { 7 | int left = 1; 8 | int right = x; 9 | int last_mid = 0; 10 | 11 | while(left <= right) { 12 | int mid = left + (right - left) / 2; 13 | 14 | if(x / mid > mid) { 15 | left = mid + 1; 16 | last_mid = mid; 17 | } 18 | else if (x / mid < mid) { 19 | right = mid - 1; 20 | } 21 | else 22 | return mid; 23 | } 24 | 25 | return last_mid; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /C++/subsets.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(2^n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | vector > subsets(vector &S) { 7 | const int size = S.size(); 8 | const int setSize = 1 << size; 9 | vector > ans; 10 | vector v; 11 | 12 | sort(S.begin(), S.end()); 13 | 14 | for(int i = 0; i < setSize; ++i) { 15 | for(int j = 0; j < size; j++) { 16 | if(i & (1 << j)) 17 | v.push_back(S[j]); 18 | } 19 | ans.push_back(v); 20 | v.clear(); 21 | } 22 | 23 | return ans; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /C++/subsetsWithDup.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(2^n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | vector > subsetsWithDup(vector &S) { 7 | sort(S.begin(), S.end()); 8 | vector > result(1); 9 | size_t previous_size = 0; 10 | for (size_t i = 0; i < S.size(); ++i) { 11 | const size_t size = result.size(); 12 | for (size_t j = 0; j < size; ++j) { 13 | // only union non-duplicate element or new union set 14 | if (i == 0 || S[i] != S[i-1] || j >= previous_size) { 15 | result.push_back(result[j]); 16 | result.back().push_back(S[i]); 17 | } 18 | } 19 | previous_size = size; 20 | } 21 | return result; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /C++/sumNumbers.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(logn) 3 | 4 | /** 5 | * Definition for binary tree 6 | * struct TreeNode { 7 | * int val; 8 | * TreeNode *left; 9 | * TreeNode *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | int dfs(TreeNode *root, int num) { 16 | if(!root) 17 | return 0; 18 | 19 | num = num * 10 + root->val; 20 | 21 | if(!root->left && !root->right) // leaf 22 | return num; 23 | 24 | return dfs(root->left, num) + dfs(root->right, num); 25 | } 26 | 27 | int sumNumbers(TreeNode *root) { 28 | int num = 0; 29 | return dfs(root, 0); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /C++/threeSum2.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n^2) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | vector > threeSum(vector &num) { 7 | vector > ans; 8 | const int target = 0; 9 | 10 | sort(num.begin(), num.end()); 11 | auto last = num.rend(); 12 | for(auto a = num.rbegin(); a < prev(last, 2); ++a) { 13 | if(a > num.rbegin() && *a == *(a - 1)) 14 | continue; 15 | auto b = next(a); 16 | auto c = prev(last); 17 | 18 | while(b < c) { 19 | if(b > next(a) && *b == *(b - 1)) { 20 | ++b; 21 | } 22 | else if(c < prev(last) && *c == *(c + 1)) { 23 | --c; 24 | } 25 | else { 26 | const int sum = *a + *b + *c; 27 | 28 | if(sum < target) 29 | --c; 30 | else if(sum > target) 31 | ++b; 32 | else { 33 | ans.push_back({ *c, *b, *a}); 34 | ++b; 35 | --c; 36 | } 37 | } 38 | } 39 | } 40 | 41 | return ans; 42 | } 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /C++/threeSumCloset.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n^2) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | int threeSumClosest(vector &num, int target) { 7 | int ans = 0; 8 | int gap = INT_MAX; 9 | 10 | sort(num.begin(), num.end()); 11 | auto last = num.end(); 12 | for(auto a = num.begin(); a != prev(last, 2); a++) { 13 | auto b = next(a); 14 | auto c = prev(last); 15 | 16 | while(b != c) { 17 | const int sum = *a + *b + *c; 18 | 19 | if(gap > abs(target - sum)) { 20 | gap = abs(target - sum); 21 | ans = sum; 22 | } 23 | if(sum < target) 24 | ++b; 25 | else 26 | --c; 27 | } 28 | } 29 | 30 | return ans; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /C++/totalNQueens.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n!) 2 | // Space Complexity: O(n) 3 | 4 | class Solution { 5 | public: 6 | void dfs(int row) { 7 | const int N = chess.size(); 8 | if(row == N) { 9 | ans++; 10 | return; 11 | } 12 | 13 | for(int i = 0; i < N; i++) { 14 | if(cols[i] == 0 && main_diag[row + i] == 0 && anti_diag[row - i + N] == 0) { 15 | cols[i] = main_diag[row + i] = anti_diag[row - i + N] = 1; 16 | chess[row] = i; 17 | dfs(row + 1); 18 | cols[i] = main_diag[row + i] = anti_diag[row - i + N] = 0; 19 | } 20 | } 21 | } 22 | 23 | int totalNQueens(int n) { 24 | ans = 0; 25 | cols = vector(n, 0); 26 | main_diag = vector(2 * n, 0); 27 | anti_diag = vector(2 * n, 0); 28 | chess = vector(n, 0); 29 | 30 | dfs(0); 31 | 32 | return ans; 33 | } 34 | 35 | private: 36 | int ans; 37 | vector cols; 38 | vector main_diag; 39 | vector anti_diag; 40 | vector chess; 41 | }; 42 | -------------------------------------------------------------------------------- /C++/trap.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n) 2 | // Space Complexity: O(1) 3 | 4 | class Solution { 5 | public: 6 | int trap(int A[], int n) { 7 | int max = 0; 8 | for(int i = 0; i < n; ++i) { 9 | if(A[i] > A[max]) 10 | max = i; 11 | } 12 | 13 | int water = 0; 14 | for(int i = 0, top = 0; i < max; ++i) { 15 | if(A[i] > top) 16 | top = A[i]; 17 | else 18 | water += top - A[i]; 19 | } 20 | 21 | for(int i = n - 1, top = 0; i > max; --i) { 22 | if(A[i] > top) 23 | top = A[i]; 24 | else 25 | water += top - A[i]; 26 | } 27 | 28 | return water; 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /C++/uniquePathWithObstacles.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(m * n) 2 | // Space Complexity: O(m + n) 3 | 4 | class Solution { 5 | public: 6 | int uniquePathsWithObstacles(vector > &obstacleGrid) { 7 | const int m = obstacleGrid.size(); 8 | const int n = obstacleGrid[0].size(); 9 | vector v(n, 0); 10 | 11 | v[0] = 1; 12 | for(int i = 0; i < m; ++i) { 13 | if(obstacleGrid[i][0] != 0) 14 | v[0] = 0; 15 | for(int j = 1; j < n; ++j) { 16 | if(obstacleGrid[i][j] == 0) 17 | v[j] += v[j - 1]; 18 | else 19 | v[j] = 0; 20 | } 21 | } 22 | 23 | return v[n - 1]; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /C++/uniquePaths.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(mn) 2 | // Space Complexity: O(mn) 3 | 4 | class Solution { 5 | public: 6 | unordered_map > hash; 7 | int uniquePaths(int m, int n) { 8 | if(m == 0 || n == 0) 9 | return 0; 10 | if(m == 1 || n == 1) 11 | return 1; 12 | if(hash.find(m) != hash.end() && hash[m].find(n) != hash[m].end()) 13 | return hash[m][n]; 14 | return hash[m][n] = uniquePaths(m - 1, n) + uniquePaths(m, n - 1); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /C++/uniquePaths2.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(mn) 2 | // Space Complexity: O(n) 3 | 4 | class Solution { 5 | public: 6 | int uniquePaths(int m, int n) { 7 | vector f(n, 1); 8 | for(int i = 1; i < m; ++i) { 9 | for(int j = 1; j < n; ++j) { 10 | f[j] += f[j-1]; 11 | } 12 | } 13 | return f[n-1]; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /C++/wordBreak.cpp: -------------------------------------------------------------------------------- 1 | // Time Complexity: O(n^2) 2 | // Space Complexity: O(n) 3 | 4 | class Solution { 5 | public: 6 | bool wordBreak(string s, unordered_set &dict) { 7 | vector f(s.size() + 1, false); 8 | f[0] = true; // null string 9 | for(int i = 1; i <= s.size(); ++i) { 10 | for(int j = i - 1; j >= 0; --j) { 11 | if(f[j] && dict.find(s.substr(j, i - j)) != dict.end()) { 12 | f[i] = true; 13 | break; 14 | } 15 | } 16 | } 17 | return f[s.size()]; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /Java/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Java/.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Package Files # 4 | *.jar 5 | *.war 6 | *.ear 7 | -------------------------------------------------------------------------------- /Java/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | LeetCode 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Java/src/net/kenyang/algorithm/BestTimeToBuyAndSellStock.java: -------------------------------------------------------------------------------- 1 | package net.kenyang.algorithm; 2 | 3 | /** 4 | * Say you have an array for which the i element is the price of a given stock on day i. 5 | * If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit. 6 | * @author Ken Yang 7 | * 8 | */ 9 | public class BestTimeToBuyAndSellStock { 10 | public int maxProfit(int[] prices) { 11 | int size = prices.length; 12 | 13 | if (size<=1){ 14 | return 0; 15 | } 16 | 17 | int min = prices[0]; 18 | int max = prices[1] - min; 19 | for (int i = 2; i < size; i++) { 20 | 21 | if (min > prices[i-1]) { 22 | min = prices[i-1]; 23 | } 24 | 25 | if (max < (prices[i]-min)) { 26 | max = prices[i]-min; 27 | } 28 | 29 | } 30 | 31 | 32 | return (max<0) ? 0 : max; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Java/src/net/kenyang/algorithm/LinkedListCycle.java: -------------------------------------------------------------------------------- 1 | package net.kenyang.algorithm; 2 | 3 | 4 | public class LinkedListCycle { 5 | class ListNode { 6 | int val; 7 | ListNode next; 8 | 9 | ListNode(int x) { 10 | val = x; 11 | next = null; 12 | } 13 | } 14 | 15 | 16 | public boolean hasCycle(ListNode head) { 17 | 18 | ListNode slowNode = head; 19 | ListNode fastNode = head; 20 | if (head !=null && head.next != null) { 21 | fastNode = head.next; 22 | } else { 23 | return false; 24 | } 25 | 26 | while (slowNode !=null && fastNode!=null){ 27 | if (slowNode.val == fastNode.val ) return true; 28 | 29 | slowNode = slowNode.next; 30 | fastNode = fastNode.next; 31 | if (fastNode!=null){ 32 | fastNode = fastNode.next; 33 | } 34 | } 35 | 36 | return false; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Java/src/net/kenyang/algorithm/MaximumDepthOfBinaryTree.java: -------------------------------------------------------------------------------- 1 | package net.kenyang.algorithm; 2 | 3 | /** 4 | * Given a binary tree, find its maximum depth.
5 | * The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 6 | * @author Ken Yang 7 | * 8 | */ 9 | public class MaximumDepthOfBinaryTree { 10 | public class TreeNode { 11 | int val; 12 | TreeNode left; 13 | TreeNode right; 14 | TreeNode(int x) { 15 | val = x; 16 | } 17 | } 18 | 19 | public int maxDepth(TreeNode root) { 20 | 21 | if (root == null) { 22 | return 0; 23 | } 24 | 25 | int iRightDepth = maxDepth(root.right); 26 | int iLefttDepth = maxDepth(root.left); 27 | return (iRightDepth > iLefttDepth) ? iRightDepth + 1 : iLefttDepth + 1; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Java/src/net/kenyang/algorithm/ReverseInteger.java: -------------------------------------------------------------------------------- 1 | package net.kenyang.algorithm; 2 | 3 | /** 4 | * Reverse digits of an integer. 5 | *

6 | * Example1: x = 123, return 321
7 | * Example2: x = -123, return -321 8 | * @author Ken Yang 9 | * 10 | */ 11 | public class ReverseInteger { 12 | public int reverse(int x){ 13 | int newValue = 0; 14 | while (x!=0) { 15 | int mod = x % 10; 16 | newValue = newValue*10 + mod; 17 | x /=10; 18 | } 19 | return newValue; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Java/src/net/kenyang/algorithm/SameTree.java: -------------------------------------------------------------------------------- 1 | package net.kenyang.algorithm; 2 | 3 | /** 4 | * Given two binary trees, write a function to check if they are equal or not. 5 | * Two binary trees are considered equal if they are structurally identical and the nodes have the same value. 6 | * @author Ken Yang 7 | * 8 | */ 9 | public class SameTree { 10 | public class TreeNode { 11 | int val; 12 | TreeNode left; 13 | TreeNode right; 14 | TreeNode(int x) { 15 | val = x; 16 | } 17 | } 18 | 19 | public boolean isSameTree(TreeNode p, TreeNode q) { 20 | if (p == null && q == null) { 21 | return true; 22 | } 23 | 24 | if ((p != null && q == null) 25 | || (p == null && q != null) 26 | || (p.val != q.val)) { 27 | return false; 28 | } 29 | 30 | return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Java/src/net/kenyang/algorithm/SingleNumber.java: -------------------------------------------------------------------------------- 1 | package net.kenyang.algorithm; 2 | 3 | /** 4 | * 5 | * Given an array of integers, every element appears twice except for one. Find that single one. 6 | *

7 | * Note: 8 | * Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 9 | * @author Ken Yang 10 | * 11 | */ 12 | public class SingleNumber { 13 | public int singleNumber(int[] A) { 14 | int num = 0; 15 | for (int i = 0; i < A.length; i++) { 16 | num ^= A[i]; 17 | } 18 | return num; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Java/src/net/kenyang/algorithm/SymmetricTree.java: -------------------------------------------------------------------------------- 1 | package net.kenyang.algorithm; 2 | 3 | public class SymmetricTree { 4 | 5 | public class TreeNode { 6 | int val; 7 | TreeNode left; 8 | TreeNode right; 9 | 10 | TreeNode(int x) { 11 | val = x; 12 | } 13 | } 14 | 15 | public boolean isSymmetric(TreeNode root) { 16 | if (root == null) { 17 | return true; 18 | } 19 | 20 | return isSymmetric(root.left, root.right); 21 | } 22 | 23 | public boolean isSymmetric(TreeNode leftNode, TreeNode rightNode) { 24 | if (rightNode == null && leftNode == null) 25 | return true; 26 | if (rightNode == null) 27 | return false; 28 | if (leftNode == null) 29 | return false; 30 | 31 | 32 | return leftNode.val == rightNode.val 33 | && isSymmetric(leftNode.left, rightNode.right) 34 | && isSymmetric(leftNode.right, rightNode.left); 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Java/src/net/kenyang/algorithm/UniqueBinarySearchTrees.java: -------------------------------------------------------------------------------- 1 | package net.kenyang.algorithm; 2 | 3 | /** 4 | * Given n, how many structurally unique BST's (binary search trees) that store values 1...n? 5 | * 6 | * For example, 7 | * Given n = 3, there are a total of 5 unique BST's. 8 | * @author Ken Yang 9 | * 10 | */ 11 | public class UniqueBinarySearchTrees { 12 | 13 | 14 | public int numTrees(int n) { 15 | 16 | if (n<2) { 17 | return 1; 18 | } 19 | int ans = 0; 20 | for(int i = 0; i < n; i++) { 21 | ans += numTrees(i) * numTrees(n-i-1); 22 | } 23 | return ans; 24 | 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /MySQL/combine-two-tables.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n), n is size of Person Table 2 | # Space: O(n) 3 | # 4 | # Table: Person 5 | # 6 | # +-------------+---------+ 7 | # | Column Name | Type | 8 | # +-------------+---------+ 9 | # | PersonId | int | 10 | # | FirstName | varchar | 11 | # | LastName | varchar | 12 | # +-------------+---------+ 13 | # PersonId is the primary key column for this table. 14 | # Table: Address 15 | # 16 | # +-------------+---------+ 17 | # | Column Name | Type | 18 | # +-------------+---------+ 19 | # | AddressId | int | 20 | # | PersonId | int | 21 | # | City | varchar | 22 | # | State | varchar | 23 | # +-------------+---------+ 24 | # AddressId is the primary key column for this table. 25 | # 26 | # Write a SQL query for a report that provides the following information for each person in the Person table, regardless if there is an address for each of those people: 27 | # 28 | #FirstName, LastName, City, State 29 | # 30 | # 31 | # Write your MySQL query statement below 32 | SELECT FirstName, LastName, City, State FROM Person LEFT JOIN Address 33 | ON Person.PersonId=Address.PersonId 34 | 35 | -------------------------------------------------------------------------------- /MySQL/consecutive-numbers.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | # 4 | # Write a SQL query to find all numbers that appear at least three times consecutively. 5 | # 6 | # +----+-----+ 7 | # | Id | Num | 8 | # +----+-----+ 9 | # | 1 | 1 | 10 | # | 2 | 1 | 11 | # | 3 | 1 | 12 | # | 4 | 2 | 13 | # | 5 | 1 | 14 | # | 6 | 2 | 15 | # | 7 | 2 | 16 | # +----+-----+ 17 | # For example, given the above Logs table, 1 is the only number that appears consecutively for at least three times. 18 | # 19 | 20 | # Write your MySQL query statement below 21 | SELECT DISTINCT(Num) AS ConsecutiveNums 22 | FROM ( 23 | SELECT 24 | Num, 25 | @counter := IF(@prev = Num, @counter + 1, 1) AS how_many_cnt_in_a_row, 26 | @prev := Num 27 | FROM Logs y, (SELECT @counter:=1, @prev:=NULL) vars 28 | ) sq 29 | WHERE how_many_cnt_in_a_row >= 3 30 | -------------------------------------------------------------------------------- /MySQL/nth-highest-salary.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | # 4 | # Write a SQL query to get the nth highest salary from the Employee table. 5 | # 6 | # +----+--------+ 7 | # | Id | Salary | 8 | # +----+--------+ 9 | # | 1 | 100 | 10 | # | 2 | 200 | 11 | # | 3 | 300 | 12 | # +----+--------+ 13 | # For example, given the above Employee table, the nth highest salary where n = 2 is 200. If there is no nth highest salary, then the query should return null. 14 | # 15 | CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT 16 | BEGIN 17 | RETURN ( 18 | # Write your MySQL query statement below. 19 | SELECT MAX(Salary) /*This is the outer query part */ 20 | FROM Employee Emp1 21 | WHERE (N-1) = ( /* Subquery starts here */ 22 | SELECT COUNT(DISTINCT(Emp2.Salary)) 23 | FROM Employee Emp2 24 | WHERE Emp2.Salary > Emp1.Salary) 25 | ); 26 | END 27 | -------------------------------------------------------------------------------- /MySQL/second-highest-salary.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Write a SQL query to get the second highest salary from the Employee table. 5 | # 6 | # +----+--------+ 7 | # | Id | Salary | 8 | # +----+--------+ 9 | # | 1 | 100 | 10 | # | 2 | 200 | 11 | # | 3 | 300 | 12 | # +----+--------+ 13 | # For example, given the above Employee table, the second highest salary is 200. If there is no second highest salary, then the query should return null. 14 | # 15 | # Write your MySQL query statement below 16 | SELECT MAX(Salary) FROM Employee 17 | WHERE Salary NOT IN (SELECT MAX(Salary) FROM Employee) 18 | -------------------------------------------------------------------------------- /Python/3sum-closest.py: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(1) 3 | # 4 | # Given an array S of n integers, 5 | # find three integers in S such that the sum is closest to a given number, target. 6 | # Return the sum of the three integers. 7 | # You may assume that each input would have exactly one solution. 8 | # 9 | # For example, given array S = {-1 2 1 -4}, and target = 1. 10 | # 11 | # The sum that is closest to the target is 2. (-1 + 2 + 1 = 2). 12 | # 13 | 14 | class Solution: 15 | # @return an integer 16 | def threeSumClosest(self, nums, target): 17 | nums, result, min_diff, i = sorted(nums), float("inf"), float("inf"), 0 18 | while i < len(nums) - 2: 19 | j, k = i + 1, len(nums) - 1 20 | while j < k: 21 | diff = nums[i] + nums[j] + nums[k] - target 22 | if abs(diff) < min_diff: 23 | min_diff = abs(diff) 24 | result = nums[i] + nums[j] + nums[k] 25 | if diff < 0: 26 | j += 1 27 | elif diff > 0: 28 | k -= 1 29 | else: 30 | return target 31 | i += 1 32 | while i < len(nums) - 2 and nums[i] == nums[i - 1]: 33 | i += 1 34 | return result 35 | 36 | if __name__ == '__main__': 37 | result = Solution().threeSumClosest([-1, 2, 1, -4], 1) 38 | print result 39 | -------------------------------------------------------------------------------- /Python/add-binary.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given two binary strings, return their sum (also a binary string). 5 | # 6 | # For example, 7 | # a = "11" 8 | # b = "1" 9 | # Return "100". 10 | # 11 | 12 | class Solution: 13 | # @param a, a string 14 | # @param b, a string 15 | # @return a string 16 | def addBinary(self, a, b): 17 | result, carry, val, len_a, len_b, i = "", 0, 0, len(a), len(b), 0 18 | for i in xrange(max(len_a, len_b)): 19 | val = carry 20 | if i < len_a: 21 | sum += int(a[-(i + 1)]) 22 | if i < len_b: 23 | sum += int(b[-(i + 1)]) 24 | carry, val = val / 2, val % 2 25 | result = "{0}{1}".format(val, result) 26 | if carry == 1: 27 | result = "1" + result 28 | return result 29 | 30 | if __name__ == '__main__': 31 | result = Solution().addBinary('11', '1') 32 | print result 33 | -------------------------------------------------------------------------------- /Python/anagrams.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | # 4 | # Given an array of strings, return all groups of strings that are anagrams. 5 | # 6 | # Note: All inputs will be in lower-case. 7 | # 8 | 9 | class Solution: 10 | # @param strs, a list of strings 11 | # @return a list of strings 12 | def anagrams(self, strs): 13 | anagrams_map, result = {}, [] 14 | for s in strs: 15 | sorted_str = ("").join(sorted(s)) 16 | if sorted_str in anagrams_map: 17 | anagrams_map[sorted_str].append(s) 18 | else: 19 | anagrams_map[sorted_str] = [s] 20 | for anagram in anagrams_map.values(): 21 | if len(anagram) > 1: 22 | result += anagram 23 | return result 24 | 25 | if __name__ == "__main__": 26 | result = Solution().anagrams(["cat", "dog", "act", "mac"]) 27 | print result -------------------------------------------------------------------------------- /Python/balanced-binary-tree.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(logn) 3 | # 4 | # Given a binary tree, determine if it is height-balanced. 5 | # 6 | # For this problem, a height-balanced binary tree is defined as a binary tree 7 | # in which the depth of the two subtrees of every node never differ by more than 1. 8 | # 9 | 10 | # Definition for a binary tree node 11 | class TreeNode: 12 | def __init__(self, x): 13 | self.val = x 14 | self.left = None 15 | self.right = None 16 | 17 | class Solution: 18 | # @param root, a tree node 19 | # @return a boolean 20 | def isBalanced(self, root): 21 | return (self.getHeight(root) >= 0) 22 | 23 | def getHeight(self, root): 24 | if root is None: 25 | return 0 26 | left_height, right_height = self.getHeight(root.left), self.getHeight(root.right) 27 | if left_height < 0 or right_height < 0 or abs(left_height - right_height) > 1: 28 | return -1 29 | return max(left_height, right_height) + 1 30 | 31 | if __name__ == "__main__": 32 | root = TreeNode(0) 33 | root.left = TreeNode(1) 34 | result = Solution().isBalanced(root) 35 | print result 36 | 37 | root.left.left = TreeNode(2) 38 | result = Solution().isBalanced(root) 39 | print result 40 | -------------------------------------------------------------------------------- /Python/best-time-to-buy-and-sell-stock-ii.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Say you have an array for which the ith element is 5 | # the price of a given stock on day i. 6 | # 7 | # Design an algorithm to find the maximum profit. 8 | # You may complete as many transactions as you like 9 | # (ie, buy one and sell one share of the stock multiple times). 10 | # However, you may not engage in multiple transactions at the same time 11 | # (ie, you must sell the stock before you buy again). 12 | # 13 | 14 | class Solution: 15 | # @param prices, a list of integer 16 | # @return an integer 17 | def maxProfit(self, prices): 18 | profit = 0 19 | for i in xrange(len(prices) - 1): 20 | profit += max(0, prices[i + 1] - prices[i]) 21 | return profit 22 | 23 | if __name__ == "__main__": 24 | result = Solution().maxProfit([3, 2, 1, 4, 2, 5, 6]) 25 | print result 26 | 27 | -------------------------------------------------------------------------------- /Python/best-time-to-buy-and-sell-stock.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Say you have an array for which the ith element 5 | # is the price of a given stock on day i. 6 | # 7 | # If you were only permitted to complete at most one transaction 8 | # (ie, buy one and sell one share of the stock), 9 | # design an algorithm to find the maximum profit. 10 | # 11 | 12 | class Solution: 13 | # @param prices, a list of integer 14 | # @return an integer 15 | def maxProfit(self, prices): 16 | max_profit, min_price = 0, float("inf") 17 | for price in prices: 18 | min_price = min(min_price, price) 19 | max_profit = max(max_profit, price - min_price) 20 | return max_profit 21 | 22 | if __name__ == "__main__": 23 | result = Solution().maxProfit([3, 2, 1, 4, 2, 5, 6]) 24 | print result 25 | 26 | -------------------------------------------------------------------------------- /Python/binary-tree-maximum-path-sum.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(logn) 3 | # 4 | # Given a binary tree, find the maximum path sum. 5 | # 6 | # The path may start and end at any node in the tree. 7 | # 8 | # For example: 9 | # Given the below binary tree, 10 | # 11 | # 1 12 | # / \ 13 | # 2 3 14 | # Return 6. 15 | # 16 | # Definition for a binary tree node 17 | class TreeNode: 18 | def __init__(self, x): 19 | self.val = x 20 | self.left = None 21 | self.right = None 22 | 23 | class Solution: 24 | maxSum = float("-inf") 25 | # @param root, a tree node 26 | # @return an integer 27 | def maxPathSum(self, root): 28 | self.maxPathSumRecu(root) 29 | return self.maxSum 30 | 31 | def maxPathSumRecu(self, root): 32 | if root is None: 33 | return 0 34 | left = max(0, self.maxPathSumRecu(root.left)) 35 | right = max(0, self.maxPathSumRecu(root.right)) 36 | self.maxSum = max(self.maxSum, root.val + left + right) 37 | return root.val + max(left, right) 38 | 39 | if __name__ == "__main__": 40 | root = TreeNode(1) 41 | root.left = TreeNode(2) 42 | root.right = TreeNode(3) 43 | result = Solution().maxPathSum(root) 44 | print result 45 | -------------------------------------------------------------------------------- /Python/candy.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | # 4 | # There are N children standing in a line. Each child is assigned a rating value. 5 | # 6 | # You are giving candies to these children subjected to the following requirements: 7 | # 8 | # Each child must have at least one candy. 9 | # Children with a higher rating get more candies than their neighbors. 10 | # What is the minimum candies you must give? 11 | # 12 | 13 | import operator 14 | 15 | class Solution: 16 | # @param ratings, a list of integer 17 | # @return an integer 18 | def candy(self, ratings): 19 | candies = [1 for _ in xrange(len(ratings))] 20 | for i in xrange(1, len(ratings)): 21 | if ratings[i] > ratings[i - 1]: 22 | candies[i] = candies[i - 1] + 1 23 | 24 | for i in reversed(xrange(1, len(ratings))): 25 | if ratings[i - 1] > ratings[i] and candies[i - 1] <= candies[i]: 26 | candies[i - 1] = candies[i] + 1 27 | 28 | return reduce(operator.add, candies) 29 | 30 | if __name__ == "__main__": 31 | result = Solution().candy([1, 2, 3, 2, 3, 5, 2, 5]) 32 | print result 33 | 34 | -------------------------------------------------------------------------------- /Python/climbing-stairs.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # You are climbing a stair case. It takes n steps to reach to the top. 5 | # 6 | # Each time you can either climb 1 or 2 steps. 7 | # In how many distinct ways can you climb to the top? 8 | # 9 | 10 | class Solution: 11 | # @param n, an integer 12 | # @return an integer 13 | def climbStairs(self, n): 14 | prev, current = 0, 1 15 | for i in xrange(n): 16 | prev, current = current, prev + current, 17 | return current 18 | 19 | if __name__ == "__main__": 20 | result = Solution().climbStairs(2) 21 | print result 22 | -------------------------------------------------------------------------------- /Python/combinations.py: -------------------------------------------------------------------------------- 1 | # Time: O(n!) 2 | # Space: O(n) 3 | # 4 | # Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. 5 | # 6 | # For example, 7 | # If n = 4 and k = 2, a solution is: 8 | # 9 | # [ 10 | # [2,4], 11 | # [3,4], 12 | # [2,3], 13 | # [1,2], 14 | # [1,3], 15 | # [1,4], 16 | # ] 17 | # 18 | 19 | class Solution: 20 | # @return a list of lists of integers 21 | def combine(self, n, k): 22 | result = [] 23 | self.combineRecu(n, result, 0, [], k) 24 | return result 25 | 26 | def combineRecu(self, n, result, start, intermediate, k): 27 | if k == 0: 28 | result.append(intermediate[:]) 29 | for i in xrange(start, n): 30 | intermediate.append(i + 1) 31 | self.combineRecu(n, result, i + 1, intermediate, k - 1) 32 | intermediate.pop() 33 | 34 | if __name__ == "__main__": 35 | result = Solution().combine(4, 2) 36 | print result 37 | -------------------------------------------------------------------------------- /Python/container-with-most-water.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given n non-negative integers a1, a2, ..., an, 5 | # where each represents a point at coordinate (i, ai). 6 | # n vertical lines are drawn such that the two endpoints of 7 | # line i is at (i, ai) and (i, 0). Find two lines, 8 | # which together with x-axis forms a container, 9 | # such that the container contains the most water. 10 | # 11 | # Note: You may not slant the container. 12 | # 13 | 14 | class Solution: 15 | # @return an integer 16 | def maxArea(self, height): 17 | max_area, i, j = 0, 0, len(height) - 1 18 | while i < j: 19 | max_area = max(max_area, min(height[i], height[j]) * (j - i)) 20 | if height[i] < height[j]: 21 | i += 1 22 | else: 23 | j -= 1 24 | return max_area 25 | 26 | if __name__ == "__main__": 27 | height = [1, 2, 3, 4, 3, 2, 1, 5] 28 | result = Solution().maxArea(height) 29 | print result -------------------------------------------------------------------------------- /Python/convert-sorted-array-to-binary-search-tree.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(logn) 3 | # 4 | # Given an array where elements are sorted in ascending order, 5 | # convert it to a height balanced BST. 6 | # 7 | # Definition for a binary tree node 8 | class TreeNode: 9 | def __init__(self, x): 10 | self.val = x 11 | self.left = None 12 | self.right = None 13 | 14 | class Solution: 15 | # @param num, a list of integers 16 | # @return a tree node 17 | def sortedArrayToBST(self, num): 18 | return self.sortedArrayToBSTRecu(num, 0, len(num)) 19 | 20 | def sortedArrayToBSTRecu(self, num, start, end): 21 | if start == end: 22 | return None 23 | mid = start + (end - start) / 2 24 | node = TreeNode(num[mid]) 25 | node.left = self.sortedArrayToBSTRecu(num, start, mid) 26 | node.right = self.sortedArrayToBSTRecu(num, mid + 1, end) 27 | return node 28 | 29 | if __name__ == "__main__": 30 | num = [1, 2, 3] 31 | result = Solution().sortedArrayToBST(num) 32 | print result.val 33 | print result.left.val 34 | print result.right.val 35 | -------------------------------------------------------------------------------- /Python/count-and-say.py: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | # 4 | # The count-and-say sequence is the sequence of integers beginning as follows: 5 | # 1, 11, 21, 1211, 111221, ... 6 | # 7 | # 1 is read off as "one 1" or 11. 8 | # 11 is read off as "two 1s" or 21. 9 | # 21 is read off as "one 2, then one 1" or 1211. 10 | # Given an integer n, generate the nth sequence. 11 | # 12 | # Note: The sequence of integers will be represented as a string. 13 | # 14 | 15 | class Solution: 16 | # @return a string 17 | def countAndSay(self, n): 18 | seq = "1" 19 | for i in xrange(n - 1): 20 | seq = self.getNext(seq) 21 | return seq 22 | 23 | def getNext(self, seq): 24 | i, next_seq = 0, "" 25 | while i < len(seq): 26 | cnt = 1 27 | while i < len(seq) - 1 and seq[i] == seq[i + 1]: 28 | cnt += 1 29 | i += 1 30 | next_seq += "{}{}".format(cnt, seq[i]) 31 | i += 1 32 | return next_seq 33 | 34 | if __name__ == "__main__": 35 | for i in xrange(1, 4): 36 | print Solution().countAndSay(i) 37 | 38 | 39 | -------------------------------------------------------------------------------- /Python/decode-ways.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # A message containing letters from A-Z is being encoded to numbers using the following mapping: 5 | # 6 | # 'A' -> 1 7 | # 'B' -> 2 8 | # ... 9 | # 'Z' -> 26 10 | # Given an encoded message containing digits, determine the total number of ways to decode it. 11 | # 12 | # For example, 13 | # Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12). 14 | # 15 | # The number of ways decoding "12" is 2. 16 | # 17 | 18 | class Solution: 19 | # @param s, a string 20 | # @return an integer 21 | def numDecodings(self, s): 22 | if len(s) == 0 or s[0] == '0': 23 | return 0 24 | prev, prev_prev = 1, 0 25 | for i in range(len(s)): 26 | current = 0 27 | if s[i] != '0': 28 | current = prev 29 | if i > 0 and (s[i - 1] == '1' or (s[i - 1] == '2' and s[i] <= '6')): 30 | current += prev_prev 31 | prev, prev_prev = current, prev 32 | return prev 33 | 34 | if __name__ == "__main__": 35 | for i in ["0", "10", "10", "103", "1032", "10323"]: 36 | print Solution().numDecodings(i) -------------------------------------------------------------------------------- /Python/distinct-subsequences.py: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | # 4 | # Given a string S and a string T, count the number of distinct subsequences of T in S. 5 | # 6 | # A subsequence of a string is a new string which is formed from the original string 7 | # by deleting some (can be none) of the characters without disturbing the relative positions 8 | # of the remaining characters. (ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not). 9 | # 10 | # Here is an example: 11 | # S = "rabbbit", T = "rabbit" 12 | # 13 | # Return 3. 14 | # 15 | 16 | class Solution: 17 | # @return an integer 18 | def numDistinct(self, S, T): 19 | ways = [0 for _ in xrange(len(T) + 1)] 20 | ways[0] = 1 21 | for S_char in S: 22 | for j, T_char in reversed(list(enumerate(T))): 23 | if S_char == T_char: 24 | ways[j + 1] += ways[j] 25 | return ways[len(T)] 26 | 27 | if __name__ == "__main__": 28 | S = "rabbbit" 29 | T = "rabbit" 30 | result = Solution().numDistinct(S, T) 31 | print result 32 | 33 | -------------------------------------------------------------------------------- /Python/divide-two-integers.py: -------------------------------------------------------------------------------- 1 | # Time: O(logn) 2 | # Space: O(1) 3 | # 4 | # Divide two integers without using multiplication, division and mod operator. 5 | # 6 | 7 | class Solution: 8 | # @return an integer 9 | def divide(self, dividend, divisor): 10 | result, dvd, dvs = 0, abs(dividend), abs(divisor) 11 | while dvd >= dvs: 12 | inc = dvs 13 | i = 0 14 | while dvd >= inc: 15 | dvd -= inc 16 | result += 1 << i 17 | inc <<= 1 18 | i += 1 19 | if dividend > 0 and divisor < 0 or dividend < 0 and divisor > 0: 20 | return -result 21 | else: 22 | return result 23 | 24 | if __name__ == "__main__": 25 | print Solution().divide(123, 12) 26 | print Solution().divide(123, -12) 27 | print Solution().divide(-123, 12) 28 | print Solution().divide(-123, -12) -------------------------------------------------------------------------------- /Python/evaluate-reverse-polish-notation.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | # 4 | # Evaluate the value of an arithmetic expression in Reverse Polish Notation. 5 | # 6 | # Valid operators are +, -, *, /. Each operand may be an integer or another expression. 7 | # 8 | # Some examples: 9 | # ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9 10 | # ["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6 11 | # 12 | import operator 13 | 14 | class Solution: 15 | # @param tokens, a list of string 16 | # @return an integer 17 | def evalRPN(self, tokens): 18 | numerals, operators = [], {"+": operator.add, "-": operator.sub, "*": operator.mul, "/": operator.div} 19 | for token in tokens: 20 | if token not in operators: 21 | numerals.append(int(token)) 22 | else: 23 | y, x = numerals.pop(), numerals.pop() 24 | numerals.append(int(operators[token](x * 1.0, y))) 25 | return numerals.pop() 26 | 27 | if __name__ == "__main__": 28 | print Solution().evalRPN(["2", "1", "+", "3", "*"]) 29 | print Solution().evalRPN(["4", "13", "5", "/", "+"]) 30 | print Solution().evalRPN(["10","6","9","3","+","-11","*","/","*","17","+","5","+"]) -------------------------------------------------------------------------------- /Python/excel-sheet-column-number.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Related to question Excel Sheet Column Title 5 | # 6 | # Given a column title as appear in an Excel sheet, return its corresponding column number. 7 | # 8 | # For example: 9 | # 10 | # A -> 1 11 | # B -> 2 12 | # C -> 3 13 | # ... 14 | # Z -> 26 15 | # AA -> 27 16 | # AB -> 28 17 | # 18 | 19 | class Solution: 20 | # @param s, a string 21 | # @return an integer 22 | def titleToNumber(self, s): 23 | result = 0 24 | for i in xrange(len(s)): 25 | result *= 26 26 | result += ord(s[i]) - ord('A') + 1 27 | return result 28 | 29 | if __name__ == "__main__": 30 | print Solution().titleToNumber("AAAB") -------------------------------------------------------------------------------- /Python/excel-sheet-column-title.py: -------------------------------------------------------------------------------- 1 | # Time: O(logn) 2 | # Space: O(1) 3 | # 4 | # Given a positive integer, return its corresponding column title as appear in an Excel sheet. 5 | # 6 | # For example: 7 | # 8 | # 1 -> A 9 | # 2 -> B 10 | # 3 -> C 11 | # ... 12 | # 26 -> Z 13 | # 27 -> AA 14 | # 28 -> AB 15 | # 16 | 17 | class Solution: 18 | # @return a string 19 | def convertToTitle(self, num): 20 | result, dvd = "", num 21 | 22 | while dvd: 23 | result += chr((dvd - 1) % 26 + ord('A')) 24 | dvd = (dvd - 1) / 26 25 | 26 | return result[::-1] 27 | 28 | if __name__ == "__main__": 29 | for i in xrange(1, 29): 30 | print Solution().convertToTitle(i) -------------------------------------------------------------------------------- /Python/factorial-trailing-zeroes.py: -------------------------------------------------------------------------------- 1 | # Time: O(logn) 2 | # Space: O(1) 3 | # 4 | # Given an integer n, return the number of trailing zeroes in n!. 5 | # 6 | # Note: Your solution should be in logarithmic time complexity. 7 | # 8 | 9 | class Solution: 10 | # @return an integer 11 | def trailingZeroes(self, n): 12 | result = 0 13 | while n > 0: 14 | result += n / 5 15 | n /= 5 16 | return result 17 | 18 | if __name__ == "__main__": 19 | print Solution().trailingZeroes(100) -------------------------------------------------------------------------------- /Python/find-peak-element.py: -------------------------------------------------------------------------------- 1 | # Time: O(logn) 2 | # Space: O(1) 3 | # 4 | # A peak element is an element that is greater than its neighbors. 5 | # 6 | # Given an input array where num[i] != num[i+1], find a peak element and return its index. 7 | # 8 | # The array may contain multiple peaks, in that case return the index to any one of the peaks is fine. 9 | # 10 | # You may imagine that num[-1] = num[n] = -infinite. 11 | # 12 | # For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2. 13 | # 14 | # Note: 15 | # Your solution should be in logarithmic complexity. 16 | # 17 | 18 | class Solution: 19 | # @param num, a list of integer 20 | # @return an integer 21 | def findPeakElement(self, num): 22 | low, high = 0, len(num) - 1 23 | 24 | while low < high: 25 | mid = low + (high - low) / 2 26 | if (mid == 0 or num[mid - 1] <= num[mid]) and \ 27 | (mid == len(num) - 1 or num[mid + 1] <= num[mid]): 28 | return mid 29 | elif mid > 0 and num[mid - 1] > num[mid]: 30 | high = mid - 1 31 | else: 32 | low = mid + 1 33 | mid = low + (high - low) / 2 34 | 35 | return low 36 | 37 | if __name__ == "__main__": 38 | # print Solution().findPeakElement([1,2,1]) 39 | print Solution().findPeakElement([1,2,3, 1]) -------------------------------------------------------------------------------- /Python/first-missing-positive.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | # 4 | # Given an unsorted integer array, find the first missing positive integer. 5 | # 6 | # For example, 7 | # Given [1,2,0] return 3, 8 | # and [3,4,-1,1] return 2. 9 | # 10 | # Your algorithm should run in O(n) time and uses constant space. 11 | # 12 | 13 | class Solution: 14 | # @param A, a list of integers 15 | # @return an integer 16 | def firstMissingPositive(self, A): 17 | i = 0 18 | while i < len(A): 19 | if A[i] > 0 and A[i] - 1 < len(A) and A[i] != A[A[i]-1]: 20 | A[A[i]-1], A[i] = A[i], A[A[i]-1] 21 | else: 22 | i += 1 23 | 24 | for i, integer in enumerate(A): 25 | if integer != i + 1: 26 | return i + 1 27 | return len(A) + 1 28 | 29 | if __name__ == "__main__": 30 | print Solution().firstMissingPositive([1,2,0]) 31 | print Solution().firstMissingPositive([3,4,-1,1]) -------------------------------------------------------------------------------- /Python/gas-station.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. 5 | # 6 | # You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). 7 | # You begin the journey with an empty tank at one of the gas stations. 8 | # 9 | # Return the starting gas station's index if you can travel around the circuit once, otherwise return -1. 10 | # 11 | # Note: 12 | # The solution is guaranteed to be unique. 13 | # 14 | 15 | class Solution: 16 | # @param gas, a list of integers 17 | # @param cost, a list of integers 18 | # @return an integer 19 | def canCompleteCircuit(self, gas, cost): 20 | start, total_sum, current_sum = 0, 0, 0 21 | for i in xrange(len(gas)): 22 | diff = gas[i] - cost[i] 23 | current_sum += diff 24 | total_sum += diff 25 | if current_sum < 0: 26 | start = i + 1 27 | current_sum = 0 28 | if total_sum >= 0: 29 | return start 30 | 31 | return -1 32 | 33 | if __name__ == "__main__": 34 | print Solution().canCompleteCircuit([1, 2, 3], [3, 2, 1]) 35 | print Solution().canCompleteCircuit([1, 2, 3], [2, 2, 2]) 36 | print Solution().canCompleteCircuit([1, 2, 3], [1, 2, 3]) 37 | print Solution().canCompleteCircuit([1, 2, 3], [1, 2, 4]) 38 | -------------------------------------------------------------------------------- /Python/generate-parentheses.py: -------------------------------------------------------------------------------- 1 | # Time: O(4^n / n^(3/2)) ~= Catalan numbers 2 | # Space: O(n) 3 | # 4 | # Given n pairs of parentheses, write a function to generate 5 | # all combinations of well-formed parentheses. 6 | # 7 | # For example, given n = 3, a solution set is: 8 | # 9 | # "((()))", "(()())", "(())()", "()(())", "()()()" 10 | # 11 | 12 | class Solution: 13 | # @param an integer 14 | # @return a list of string 15 | def generateParenthesis(self, n): 16 | result = [] 17 | self.generateParenthesisRecu(result, "", n, n) 18 | return result 19 | 20 | def generateParenthesisRecu(self, result, current, left, right): 21 | if left == 0 and right == 0: 22 | result.append(current) 23 | if left > 0: 24 | self.generateParenthesisRecu(result, current + "(", left - 1, right) 25 | if left < right: 26 | self.generateParenthesisRecu(result, current + ")", left, right - 1) 27 | 28 | if __name__ == "__main__": 29 | print Solution().generateParenthesis(3) -------------------------------------------------------------------------------- /Python/gray-code.py: -------------------------------------------------------------------------------- 1 | # Time: O(2^n) 2 | # Space: O(1) 3 | # 4 | # The gray code is a binary numeral system where two successive values differ in only one bit. 5 | # 6 | # Given a non-negative integer n representing the total number of bits in the code, 7 | # print the sequence of gray code. A gray code sequence must begin with 0. 8 | # 9 | # For example, given n = 2, return [0,1,3,2]. Its gray code sequence is: 10 | # 11 | # 00 - 0 12 | # 01 - 1 13 | # 11 - 3 14 | # 10 - 2 15 | # Note: 16 | # For a given n, a gray code sequence is not uniquely defined. 17 | # 18 | # For example, [0,2,3,1] is also a valid gray code sequence according to the above definition. 19 | # 20 | # For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that. 21 | 22 | class Solution: 23 | # @return a list of integers 24 | def grayCode(self, n): 25 | result = [0] 26 | for i in xrange(0, n): 27 | for n in reversed(result): 28 | result.append(1 << i | n) 29 | return result 30 | 31 | # proof of closed form formula could be found here: 32 | # http://math.stackexchange.com/questions/425894/proof-of-closed-form-formula-to-convert-a-binary-number-to-its-gray-code 33 | class Solution2: 34 | # @return a list of integers 35 | def grayCode(self, n): 36 | return [i >> 1 ^ i for i in xrange(1 << n)] 37 | 38 | if __name__ == "__main__": 39 | print Solution().grayCode(0) 40 | print Solution().grayCode(2) 41 | -------------------------------------------------------------------------------- /Python/integer-to-roman.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given an integer, convert it to a roman numeral. 5 | # 6 | # Input is guaranteed to be within the range from 1 to 3999. 7 | # 8 | 9 | 10 | class Solution: 11 | # @return a string 12 | def intToRoman(self, num): 13 | numeral_map = {1: "I", 4: "IV", 5: "V", 9: "IX", 10: "X", 40: "XL", 50: "L", 90: "XC", 100: "C", 400: "CD", 500: "D", 900: "CM", 1000: "M"} 14 | keyset, result = sorted(numeral_map.keys()), "" 15 | 16 | while num > 0: 17 | for key in reversed(keyset): 18 | while num / key > 0: 19 | num -= key 20 | result += numeral_map[key] 21 | 22 | return result 23 | 24 | if __name__ == "__main__": 25 | print Solution().intToRoman(999) 26 | print Solution().intToRoman(3999) -------------------------------------------------------------------------------- /Python/jump-game-ii.py: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(1) 3 | # 4 | # Given an array of non-negative integers, you are initially positioned at the first index of the array. 5 | # 6 | # Each element in the array represents your maximum jump length at that position. 7 | # 8 | # Your goal is to reach the last index in the minimum number of jumps. 9 | # 10 | # For example: 11 | # Given array A = [2,3,1,1,4] 12 | # 13 | # The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.) 14 | # 15 | 16 | class Solution: 17 | # @param A, a list of integers 18 | # @return an integer 19 | def jump(self, A): 20 | result, prev_reachable, reachable = 0, -1, 0 21 | while reachable > prev_reachable: 22 | if reachable >= len(A) - 1: 23 | return result 24 | result += 1 25 | prev_reachable = reachable 26 | for i, length in enumerate(A[:reachable + 1]): 27 | reachable = max(reachable, i + length) 28 | return -1 29 | 30 | if __name__ == "__main__": 31 | print Solution().jump([2,3,1,1,4]) 32 | print Solution().jump([3,2,1,0,4]) 33 | -------------------------------------------------------------------------------- /Python/jump-game.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given an array of non-negative integers, you are initially positioned at the first index of the array. 5 | # 6 | # Each element in the array represents your maximum jump length at that position. 7 | # 8 | # Determine if you are able to reach the last index. 9 | # 10 | # For example: 11 | # A = [2,3,1,1,4], return true. 12 | # 13 | # A = [3,2,1,0,4], return false. 14 | 15 | class Solution: 16 | # @param A, a list of integers 17 | # @return a boolean 18 | def canJump(self, A): 19 | reachable = 0 20 | for i, length in enumerate(A): 21 | if i > reachable: 22 | break 23 | reachable = max(reachable, i + length) 24 | return reachable >= len(A) - 1 25 | 26 | if __name__ == "__main__": 27 | print Solution().canJump([2,3,1,1,4]) 28 | print Solution().canJump([3,2,1,0,4]) -------------------------------------------------------------------------------- /Python/largest-number.py: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | # 4 | # Given a list of non negative integers, arrange them such that they form the largest number. 5 | # 6 | # For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330. 7 | # 8 | # Note: The result may be very large, so you need to return a string instead of an integer. 9 | # 10 | 11 | class Solution: 12 | # @param num, a list of integers 13 | # @return a string 14 | def largestNumber(self, num): 15 | num = [str(x) for x in num] 16 | num.sort(cmp=lambda x, y: cmp(y + x, x + y)) 17 | largest = ''.join(num) 18 | return largest.lstrip('0') or '0' 19 | 20 | if __name__ == "__main__": 21 | num = [3, 30, 34, 5, 9] 22 | print Solution().largestNumber(num) 23 | -------------------------------------------------------------------------------- /Python/largest-rectangle-in-histogram.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | # 4 | # Given n non-negative integers representing the histogram's bar 5 | # height where the width of each bar is 1, 6 | # find the area of largest rectangle in the histogram. 7 | # 8 | # For example, 9 | # Given height = [2,1,5,6,2,3], 10 | # return 10. 11 | # 12 | 13 | class Solution: 14 | # @param height, a list of integer 15 | # @return an integer 16 | def largestRectangleArea(self, height): 17 | increasing, area, i = [], 0, 0 18 | while i <= len(height): 19 | if len(increasing) == 0 or (i < len(height) and height[i] > height[increasing[-1]]): 20 | increasing.append(i) 21 | i += 1 22 | else: 23 | last = increasing.pop() 24 | if len(increasing) == 0: 25 | area = max(area, height[last] * i) 26 | else: 27 | area = max(area, height[last] * (i - increasing[-1] - 1 )) 28 | return area 29 | 30 | if __name__ == "__main__": 31 | print Solution().largestRectangleArea([2, 0, 2]) 32 | print Solution().largestRectangleArea([2, 1, 5, 6, 2, 3]) 33 | -------------------------------------------------------------------------------- /Python/length-of-last-word.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string. 5 | # 6 | # If the last word does not exist, return 0. 7 | # 8 | # Note: A word is defined as a character sequence consists of non-space characters only. 9 | # 10 | # For example, 11 | # Given s = "Hello World", 12 | # return 5. 13 | # 14 | 15 | class Solution: 16 | # @param s, a string 17 | # @return an integer 18 | def lengthOfLastWord(self, s): 19 | length = 0 20 | for i in reversed(s): 21 | if i == ' ': 22 | if length: 23 | break 24 | else: 25 | length += 1 26 | return length 27 | 28 | # Time: O(n) 29 | # Space: O(n) 30 | class Solution2: 31 | # @param s, a string 32 | # @return an integer 33 | def lengthOfLastWord(self, s): 34 | return len(s.strip().split(" ")[-1]) 35 | 36 | if __name__ == "__main__": 37 | print Solution().lengthOfLastWord("Hello World") 38 | print Solution2().lengthOfLastWord("") 39 | -------------------------------------------------------------------------------- /Python/linked-list-cycle-ii.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given a linked list, return the node where the cycle begins. If there is no cycle, return null. 5 | # 6 | # Follow up: 7 | # Can you solve it without using extra space? 8 | # 9 | 10 | # Definition for singly-linked list. 11 | class ListNode: 12 | def __init__(self, x): 13 | self.val = x 14 | self.next = None 15 | 16 | def __str__(self): 17 | if self: 18 | return "{}".format(self.val) 19 | else: 20 | return None 21 | 22 | class Solution: 23 | # @param head, a ListNode 24 | # @return a list node 25 | def detectCycle(self, head): 26 | fast, slow = head, head 27 | while fast and fast.next: 28 | fast, slow = fast.next.next, slow.next 29 | if fast is slow: 30 | fast = head 31 | while fast is not slow: 32 | fast, slow = fast.next, slow.next 33 | return fast 34 | return None 35 | 36 | if __name__ == "__main__": 37 | head = ListNode(1) 38 | head.next = ListNode(2) 39 | head.next.next = ListNode(3) 40 | head.next.next.next = head.next 41 | print Solution().detectCycle(head) -------------------------------------------------------------------------------- /Python/linked-list-cycle.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given a linked list, determine if it has a cycle in it. 5 | # 6 | # Follow up: 7 | # Can you solve it without using extra space? 8 | # 9 | 10 | # Definition for singly-linked list. 11 | class ListNode: 12 | def __init__(self, x): 13 | self.val = x 14 | self.next = None 15 | 16 | class Solution: 17 | # @param head, a ListNode 18 | # @return a boolean 19 | def hasCycle(self, head): 20 | fast, slow = head, head 21 | while fast and fast.next: 22 | fast, slow = fast.next.next, slow.next 23 | if fast is slow: 24 | return True 25 | return False 26 | 27 | if __name__ == "__main__": 28 | head = ListNode(1) 29 | head.next = ListNode(2) 30 | head.next.next = ListNode(3) 31 | head.next.next.next = head.next 32 | print Solution().hasCycle(head) -------------------------------------------------------------------------------- /Python/longest-common-prefix.py: -------------------------------------------------------------------------------- 1 | # Time: O(n1 + n2 + ...) 2 | # Space: O(1) 3 | # 4 | # Write a function to find the longest common prefix string amongst an array of strings. 5 | # 6 | 7 | class Solution: 8 | # @return a string 9 | def longestCommonPrefix(self, strs): 10 | if len(strs) == 0: 11 | return "" 12 | longest = strs[0] 13 | for string in strs[1:]: 14 | i = 0 15 | while i < len(string) and i < len(longest) and string[i] == longest[i]: 16 | i += 1 17 | longest = longest[:i] 18 | return longest 19 | 20 | if __name__ == "__main__": 21 | print Solution().longestCommonPrefix(["hello", "heaven", "heavy"]) 22 | -------------------------------------------------------------------------------- /Python/longest-consecutive-sequence.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | # 4 | # Given an unsorted array of integers, find the length of the longest consecutive elements sequence. 5 | # 6 | # For example, 7 | # Given [100, 4, 200, 1, 3, 2], 8 | # The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4. 9 | # 10 | # Your algorithm should run in O(n) complexity. 11 | # 12 | 13 | class Solution: 14 | # @param num, a list of integer 15 | # @return an integer 16 | def longestConsecutive(self, num): 17 | result, lengths = 1, {key: 0 for key in num} 18 | for i in num: 19 | if lengths[i] == 0: 20 | lengths[i] = 1 21 | left, right = lengths.get(i - 1, 0), lengths.get(i + 1, 0) 22 | length = 1 + left + right 23 | result, lengths[i - left], lengths[i + right] = max(result, length), length, length 24 | return result 25 | 26 | if __name__ == "__main__": 27 | print Solution().longestConsecutive([100, 4, 200, 1, 3, 2]) -------------------------------------------------------------------------------- /Python/longest-substring-with-at-most-two-distinct-characters.py: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(1) 3 | # 4 | # Given a string, find the length of the longest substring T 5 | # that contains at most 2 distinct characters. 6 | # 7 | # For example, Given s = "eceba", 8 | # 9 | # T is "ece" which its length is 3. 10 | # 11 | 12 | class Solution: 13 | # @param s, a string 14 | # @return an integer 15 | def lengthOfLongestSubstringTwoDistinct(self, s): 16 | longest, start, distinct_count, visited = 0, 0, 0, [0 for _ in xrange(256)] 17 | for i, char in enumerate(s): 18 | if visited[ord(char)] == 0: 19 | distinct_count += 1 20 | visited[ord(char)] += 1 21 | 22 | while distinct_count > 2: 23 | visited[ord(s[start])] -= 1 24 | if visited[ord(s[start])] == 0: 25 | distinct_count -= 1 26 | start += 1 27 | 28 | longest = max(longest, i - start + 1) 29 | return longest 30 | 31 | if __name__ == "__main__": 32 | print Solution().lengthOfLongestSubstringTwoDistinct("eceba") -------------------------------------------------------------------------------- /Python/longest-substring-without-repeating-characters.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given a string, find the length of the longest substring without repeating characters. 5 | # For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. 6 | # For "bbbbb" the longest substring is "b", with the length of 1. 7 | # 8 | 9 | class Solution: 10 | # @return an integer 11 | def lengthOfLongestSubstring(self, s): 12 | longest, start, visited = 0, 0, [False for _ in xrange(256)] 13 | for i, char in enumerate(s): 14 | if visited[ord(char)]: 15 | while char != s[start]: 16 | visited[ord(s[start])] = False 17 | start += 1 18 | start += 1 19 | else: 20 | visited[ord(char)] = True 21 | longest = max(longest, i - start + 1) 22 | return longest 23 | 24 | if __name__ == "__main__": 25 | print Solution().lengthOfLongestSubstring("abcabcbb") 26 | -------------------------------------------------------------------------------- /Python/majority-element.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given an array of size n, find the majority element. 5 | # The majority element is the element that appears more than [n/2] times. 6 | # 7 | # You may assume that the array is non-empty and the majority element always exist in the array. 8 | # 9 | 10 | class Solution: 11 | # @param num, a list of integers 12 | # @return an integer 13 | def majorityElement(self, num): 14 | idx, cnt = 0, 1 15 | 16 | for i in xrange(1, len(num)): 17 | if num[idx] == num[i]: 18 | cnt += 1 19 | else: 20 | cnt -= 1 21 | if cnt == 0: 22 | idx = i 23 | cnt = 1 24 | 25 | return num[idx] 26 | 27 | if __name__ == "__main__": 28 | print Solution().majorityElement([1, 2, 3, 4, 5, 5, 5, 5, 5, 5, 6]) -------------------------------------------------------------------------------- /Python/maximum-depth-of-binary-tree.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(logn) 3 | # 4 | # Given a binary tree, find its maximum depth. 5 | # 6 | # The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 7 | # 8 | 9 | # Definition for a binary tree node 10 | class TreeNode: 11 | def __init__(self, x): 12 | self.val = x 13 | self.left = None 14 | self.right = None 15 | 16 | class Solution: 17 | # @param root, a tree node 18 | # @return an integer 19 | def maxDepth(self, root): 20 | if root is None: 21 | return 0 22 | else: 23 | return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1 24 | 25 | if __name__ == "__main__": 26 | root = TreeNode(1) 27 | root.left = TreeNode(2) 28 | root.right = TreeNode(3) 29 | root.left.left = TreeNode(4) 30 | print Solution().maxDepth(root) -------------------------------------------------------------------------------- /Python/maximum-product-subarray.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Find the contiguous subarray within an array (containing at least one number) which has the largest product. 5 | # 6 | # For example, given the array [2,3,-2,4], 7 | # the contiguous subarray [2,3] has the largest product = 6. 8 | 9 | class Solution: 10 | # @param A, a list of integers 11 | # @return an integer 12 | def maxProduct(self, A): 13 | global_max, local_max, local_min = float("-inf"), 1, 1 14 | for x in A: 15 | local_max, local_min = max(x, local_max * x, local_min * x), min(x, local_max * x, local_min * x) 16 | global_max = max(global_max, local_max) 17 | return global_max 18 | 19 | class Solution2: 20 | # @param A, a list of integers 21 | # @return an integer 22 | def maxProduct(self, A): 23 | global_max, local_max, local_min = float("-inf"), 1, 1 24 | for x in A: 25 | local_max = max(1, local_max) 26 | if x > 0: 27 | local_max, local_min = local_max * x, local_min * x 28 | else: 29 | local_max, local_min = local_min * x, local_max * x 30 | global_max = max(global_max, local_max) 31 | return global_max 32 | 33 | if __name__ == "__main__": 34 | print Solution().maxProduct([2, 3, -2, 4]) 35 | print Solution().maxProduct([-4,-3]) -------------------------------------------------------------------------------- /Python/maximum-subarray.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Find the contiguous subarray within an array (containing at least one number) which has the largest sum. 5 | # 6 | # For example, given the array [-2,1,-3,4,-1,2,1,-5,4], 7 | # the contiguous subarray [4,-1,2,1] has the largest sum = 6. 8 | # 9 | # click to show more practice. 10 | # 11 | # More practice: 12 | # If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle. 13 | # 14 | 15 | class Solution: 16 | # @param A, a list of integers 17 | # @return an integer 18 | def maxSubArray(self, A): 19 | global_max, local_max = float("-inf"), 0 20 | for x in A: 21 | local_max = max(0, local_max + x) 22 | global_max = max(global_max, local_max) 23 | return global_max 24 | 25 | if __name__ == "__main__": 26 | print Solution().maxSubArray([-2,1,-3,4,-1,2,1,-5,4]) -------------------------------------------------------------------------------- /Python/merge-intervals.py: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(1) 3 | # 4 | # Given a collection of intervals, merge all overlapping intervals. 5 | # 6 | # For example, 7 | # Given [1,3],[2,6],[8,10],[15,18], 8 | # return [1,6],[8,10],[15,18]. 9 | # 10 | 11 | # Definition for an interval. 12 | class Interval: 13 | def __init__(self, s=0, e=0): 14 | self.start = s 15 | self.end = e 16 | 17 | def __repr__(self): 18 | return "[{}, {}]".format(self.start, self.end) 19 | 20 | class Solution: 21 | # @param intervals, a list of Interval 22 | # @return a list of Interval 23 | def merge(self, intervals): 24 | if len(intervals) == 0: 25 | return intervals 26 | intervals.sort(key = lambda x: x.start) 27 | result = [intervals[0]] 28 | for i in range(1, len(intervals)): 29 | prev, current = result[-1], intervals[i] 30 | if current.start <= prev.end: 31 | prev.end = max(prev.end, current.end) 32 | else: 33 | result.append(current) 34 | return result 35 | 36 | if __name__ == "__main__": 37 | print Solution().merge([Interval(1, 3), Interval(2, 6), Interval(8, 10), Interval(15,18)]) 38 | -------------------------------------------------------------------------------- /Python/merge-k-sorted-lists.py: -------------------------------------------------------------------------------- 1 | # Time: O(nlogk) 2 | # Space: O(1) 3 | # 4 | # Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 5 | import heapq 6 | 7 | # Definition for singly-linked list. 8 | class ListNode: 9 | def __init__(self, x): 10 | self.val = x 11 | self.next = None 12 | 13 | def __repr__(self): 14 | if self: 15 | return "{} -> {}".format(self.val, repr(self.next)) 16 | 17 | class Solution: 18 | # @param a list of ListNode 19 | # @return a ListNode 20 | def mergeKLists(self, lists): 21 | dummy = ListNode(0) 22 | current = dummy 23 | 24 | heap = [] 25 | for sorted_list in lists: 26 | if sorted_list: 27 | heapq.heappush(heap, (sorted_list.val, sorted_list)) 28 | 29 | while heap: 30 | smallest = heapq.heappop(heap)[1] 31 | current.next = smallest 32 | current = current.next 33 | if smallest.next: 34 | heapq.heappush(heap, (smallest.next.val, smallest.next)) 35 | 36 | return dummy.next 37 | 38 | if __name__ == "__main__": 39 | list1 = ListNode(1) 40 | list1.next = ListNode(3) 41 | list2 = ListNode(2) 42 | list2.next = ListNode(4) 43 | 44 | print Solution().mergeKLists([list1, list2]) -------------------------------------------------------------------------------- /Python/merge-sorted-array.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given two sorted integer arrays A and B, merge B into A as one sorted array. 5 | # 6 | # Note: 7 | # You may assume that A has enough space (size that is greater or equal to m + n) to hold additional elements from B. 8 | # The number of elements initialized in A and B are m and n respectively. 9 | # 10 | 11 | class Solution: 12 | # @param A a list of integers 13 | # @param m an integer, length of A 14 | # @param B a list of integers 15 | # @param n an integer, length of B 16 | # @return nothing 17 | def merge(self, A, m, B, n): 18 | last, i, j = m + n - 1, m - 1, n - 1 19 | 20 | while i >= 0 and j >= 0: 21 | if A[i] > B[j]: 22 | A[last] = A[i] 23 | last, i = last - 1, i - 1 24 | else: 25 | A[last] = B[j] 26 | last, j = last - 1, j - 1 27 | 28 | while j >= 0: 29 | A[last] = B[j] 30 | last, j = last - 1, j - 1 31 | 32 | if __name__ == "__main__": 33 | A = [1, 3, 5, 0, 0, 0, 0] 34 | B = [2, 4, 6, 7] 35 | Solution().merge(A, 3, B, 4) 36 | print A -------------------------------------------------------------------------------- /Python/merge-two-sorted-lists.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Merge two sorted linked lists and return it as a new list. 5 | # The new list should be made by splicing together the nodes of the first two lists. 6 | # 7 | 8 | # Definition for singly-linked list. 9 | class ListNode: 10 | def __init__(self, x): 11 | self.val = x 12 | self.next = None 13 | 14 | def __repr__(self): 15 | if self: 16 | return "{} -> {}".format(self.val, self.next) 17 | 18 | class Solution: 19 | # @param two ListNodes 20 | # @return a ListNode 21 | def mergeTwoLists(self, l1, l2): 22 | dummy = ListNode(0) 23 | current = dummy 24 | 25 | while l1 and l2: 26 | if l1.val < l2.val: 27 | current.next = l1 28 | l1 = l1.next 29 | else: 30 | current.next = l2 31 | l2 = l2.next 32 | current = current.next 33 | 34 | if l1: 35 | current.next = l1 36 | else: 37 | current.next = l2 38 | 39 | return dummy.next 40 | 41 | if __name__ == "__main__": 42 | l1 = ListNode(0) 43 | l1.next = ListNode(1) 44 | l2 = ListNode (2) 45 | l2.next = ListNode(3) 46 | print Solution().mergeTwoLists(l1, l2) 47 | 48 | -------------------------------------------------------------------------------- /Python/minimum-depth-of-binary-tree.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(logn) 3 | # 4 | # Given a binary tree, find its minimum depth. 5 | # 6 | # The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. 7 | # 8 | 9 | # Definition for a binary tree node 10 | class TreeNode: 11 | def __init__(self, x): 12 | self.val = x 13 | self.left = None 14 | self.right = None 15 | 16 | class Solution: 17 | # @param root, a tree node 18 | # @return an integer 19 | def minDepth(self, root): 20 | if root is None: 21 | return 0 22 | 23 | if root.left and root.right: 24 | return min(self.minDepth(root.left), self.minDepth(root.right)) + 1 25 | else: 26 | return max(self.minDepth(root.left), self.minDepth(root.right)) + 1 27 | 28 | if __name__ == "__main__": 29 | root = TreeNode(1) 30 | root.left = TreeNode(2) 31 | print Solution().minDepth(root) -------------------------------------------------------------------------------- /Python/minimum-path-sum.py: -------------------------------------------------------------------------------- 1 | # Time: O(m * n) 2 | # Space: O(m + n) 3 | # 4 | # Given a m x n grid filled with non-negative numbers, 5 | # find a path from top left to bottom right which minimizes the sum of all numbers along its path. 6 | # 7 | # Note: You can only move either down or right at any point in time. 8 | # 9 | 10 | class Solution: 11 | # @param grid, a list of lists of integers 12 | # @return an integer 13 | def minPathSum(self, grid): 14 | sum = list(grid[0]) 15 | for j in xrange(1, len(grid[0])): 16 | sum[j] = sum[j - 1] + grid[0][j] 17 | 18 | for i in xrange(1, len(grid)): 19 | sum[0] += grid[i][0] 20 | for j in xrange(1, len(grid[0])): 21 | sum[j] = min(sum[j - 1], sum[j]) + grid[i][j] 22 | 23 | return sum[-1] 24 | 25 | if __name__ == "__main__": 26 | print Solution().minPathSum([[0,1] 27 | ,[1,0]]) 28 | print Solution().minPathSum([[1,3,1] 29 | ,[1,5,1] 30 | ,[4,2,1]]) -------------------------------------------------------------------------------- /Python/missing-ranges.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given a sorted integer array where the range of elements are [lower, upper] inclusive, 5 | # return its missing ranges. 6 | # 7 | # For example, given [0, 1, 3, 50, 75], lower = 0 and upper = 99, 8 | # return ["2", "4->49", "51->74", "76->99"]. 9 | # 10 | 11 | class Solution: 12 | # @param A, a list of integers 13 | # @param lower, an integer 14 | # @param upper, an integer 15 | # @return a list of strings 16 | def findMissingRanges(self, A, lower, upper): 17 | ranges = [] 18 | pre = lower - 1 19 | 20 | for i in xrange(len(A) + 1): 21 | if i == len(A): 22 | cur = upper + 1 23 | else: 24 | cur = A[i] 25 | 26 | if cur - pre >= 2: 27 | ranges.append(self.getRange(pre + 1, cur - 1)) 28 | 29 | pre = cur 30 | 31 | return ranges 32 | 33 | def getRange(self, lower, upper): 34 | if lower == upper: 35 | return "{}".format(lower) 36 | else: 37 | return "{}->{}".format(lower, upper) 38 | 39 | if __name__ == "__main__": 40 | print Solution().findMissingRanges([0, 1, 3, 50, 75], 0, 99) -------------------------------------------------------------------------------- /Python/multiply-strings.py: -------------------------------------------------------------------------------- 1 | # Time: O(m * n) 2 | # Space: O(m + n) 3 | # 4 | # Given two numbers represented as strings, return multiplication of the numbers as a string. 5 | # 6 | # Note: The numbers can be arbitrarily large and are non-negative. 7 | # 8 | 9 | class Solution: 10 | # @param num1, a string 11 | # @param num2, a string 12 | # @return a string 13 | def multiply(self, num1, num2): 14 | num1, num2 = num1[::-1], num2[::-1] 15 | result = [0 for i in xrange(len(num1) + len(num2))] 16 | for i in xrange(len(num1)): 17 | for j in xrange(len(num2)): 18 | result[i + j] += int(num1[i]) * int(num2[j]) 19 | 20 | carry, num3 = 0, [] 21 | for digit in result: 22 | sum = carry + digit 23 | carry = sum / 10 24 | num3.insert(0, str(sum % 10)) 25 | 26 | while len(num3) > 1 and num3[0] == "0": 27 | del num3[0] 28 | 29 | return ''.join(num3) 30 | 31 | if __name__ == "__main__": 32 | print Solution().multiply("123", "1000") -------------------------------------------------------------------------------- /Python/next-permutation.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers. 5 | # 6 | # If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order). 7 | # 8 | # The replacement must be in-place, do not allocate extra memory. 9 | # 10 | # Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column. 11 | # 1,2,3 -> 1,3,2 12 | # 3,2,1 -> 1,2,3 13 | # 1,1,5 -> 1,5,1 14 | # 15 | 16 | class Solution: 17 | # @param num, a list of integer 18 | # @return a list of integer 19 | def nextPermutation(self, num): 20 | k, l = -1, 0 21 | for i in xrange(len(num) - 1): 22 | if num[i] < num[i + 1]: 23 | k = i 24 | 25 | if k == -1: 26 | return num[::-1] 27 | 28 | for i in xrange(len(num)): 29 | if num[i] > num[k]: 30 | l = i 31 | 32 | num[k], num[l] = num[l], num[k] 33 | return num[:k + 1] + num[:k:-1] 34 | 35 | if __name__ == "__main__": 36 | num = [1, 4, 3, 2] 37 | num = Solution().nextPermutation(num) 38 | print num 39 | num = Solution().nextPermutation(num) 40 | print num 41 | num = Solution().nextPermutation(num) 42 | print num -------------------------------------------------------------------------------- /Python/one-edit-distance.py: -------------------------------------------------------------------------------- 1 | # Time: O(m + n) 2 | # Space: O(1) 3 | # 4 | # Given two strings S and T, determine if they are both one edit distance apart. 5 | # 6 | 7 | class Solution: 8 | # @param s, a string 9 | # @param t, a string 10 | # @return a boolean 11 | def isOneEditDistance(self, s, t): 12 | m, n = len(s), len(t) 13 | if m > n: 14 | return self.isOneEditDistance(t, s) 15 | if n - m > 1: 16 | return False 17 | 18 | i, shift = 0, n - m 19 | while i < m and s[i] == t[i]: 20 | i += 1 21 | if shift == 0: 22 | i += 1 23 | while i < m and s[i] == t[i + shift]: 24 | i += 1 25 | 26 | return i == m 27 | 28 | if __name__ == "__main__": 29 | print Solution().isOneEditDistance("teacher", "acher") -------------------------------------------------------------------------------- /Python/palindrome-number.py: -------------------------------------------------------------------------------- 1 | # Time: O(1) 2 | # Space: O(1) 3 | # 4 | # Determine whether an integer is a palindrome. Do this without extra space. 5 | # 6 | # Some hints: 7 | # Could negative integers be palindromes? (ie, -1) 8 | # 9 | # If you are thinking of converting the integer to string, note the restriction of using extra space. 10 | # 11 | # You could also try reversing an integer. However, if you have solved the problem "Reverse Integer", 12 | # you know that the reversed integer might overflow. How would you handle such case? 13 | # 14 | # There is a more generic way of solving this problem. 15 | # 16 | 17 | class Solution: 18 | # @return a boolean 19 | def isPalindrome(self, x): 20 | if x < 0: 21 | return False 22 | copy, reverse = x, 0 23 | 24 | while copy: 25 | reverse *= 10 26 | reverse += copy % 10 27 | copy /= 10 28 | 29 | return x == reverse 30 | 31 | if __name__ == "__main__": 32 | print Solution().isPalindrome(12321) 33 | print Solution().isPalindrome(12320) 34 | print Solution().isPalindrome(-12321) -------------------------------------------------------------------------------- /Python/palindrome-partitioning-ii.py: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n^2) 3 | # 4 | # Given a string s, partition s such that every substring of the partition is a palindrome. 5 | # 6 | # Return the minimum cuts needed for a palindrome partitioning of s. 7 | # 8 | # For example, given s = "aab", 9 | # Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut. 10 | # 11 | 12 | class Solution: 13 | # @param s, a string 14 | # @return an integer 15 | def minCut(self, s): 16 | lookup = [[False for j in xrange(len(s))] for i in xrange(len(s))] 17 | mincut = [len(s) - 1 - i for i in xrange(len(s) + 1)] 18 | 19 | for i in reversed(xrange(len(s))): 20 | for j in xrange(i, len(s)): 21 | if s[i] == s[j] and (j - i < 2 or lookup[i + 1][j - 1]): 22 | lookup[i][j] = True 23 | mincut[i] = min(mincut[i], mincut[j + 1] + 1) 24 | 25 | return mincut[0] 26 | 27 | if __name__ == "__main__": 28 | print Solution().minCut("aab") -------------------------------------------------------------------------------- /Python/pascals-triangle-ii.py: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | # 4 | # Given an index k, return the kth row of the Pascal's triangle. 5 | # 6 | # For example, given k = 3, 7 | # Return [1,3,3,1]. 8 | # 9 | # Note: 10 | # Could you optimize your algorithm to use only O(k) extra space? 11 | # 12 | 13 | class Solution: 14 | # @return a list of integers 15 | def getRow(self, rowIndex): 16 | result = [1] 17 | for i in range(1, rowIndex + 1): 18 | result = [1] + [result[j - 1] + result[j] for j in range(1, i)] + [1] 19 | return result 20 | 21 | class Solution2: 22 | # @return a list of integers 23 | def getRow(self, rowIndex): 24 | result = [0] * (rowIndex + 1) 25 | for i in xrange(rowIndex + 1): 26 | old = result[0] = 1 27 | for j in xrange(1, i + 1): 28 | old, result[j] = result[j], old + result[j] 29 | return result 30 | 31 | if __name__ == "__main__": 32 | print Solution().getRow(3) -------------------------------------------------------------------------------- /Python/pascals-triangle.py: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | # 4 | # Given numRows, generate the first numRows of Pascal's triangle. 5 | # 6 | # For example, given numRows = 5, 7 | # Return 8 | # 9 | # [ 10 | # [1], 11 | # [1,1], 12 | # [1,2,1], 13 | # [1,3,3,1], 14 | # [1,4,6,4,1] 15 | # ] 16 | # 17 | 18 | class Solution: 19 | # @return a list of lists of integers 20 | def generate(self, numRows): 21 | result = [] 22 | for i in xrange(numRows): 23 | result.append([]) 24 | for j in xrange(i + 1): 25 | if j in (0, i): 26 | result[i].append(1) 27 | else: 28 | result[i].append(result[i - 1][j - 1] + result[i - 1][j]) 29 | return result 30 | 31 | if __name__ == "__main__": 32 | print Solution().generate(5) 33 | -------------------------------------------------------------------------------- /Python/path-sum.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(logn) 3 | # 4 | # Given a binary tree and a sum, determine if the tree has a root-to-leaf path 5 | # such that adding up all the values along the path equals the given sum. 6 | # 7 | # For example: 8 | # Given the below binary tree and sum = 22, 9 | # 5 10 | # / \ 11 | # 4 8 12 | # / / \ 13 | # 11 13 4 14 | # / \ \ 15 | # 7 2 1 16 | # return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22. 17 | # 18 | 19 | # Definition for a binary tree node 20 | class TreeNode: 21 | def __init__(self, x): 22 | self.val = x 23 | self.left = None 24 | self.right = None 25 | 26 | class Solution: 27 | # @param root, a tree node 28 | # @param sum, an integer 29 | # @return a boolean 30 | def hasPathSum(self, root, sum): 31 | if root is None: 32 | return False 33 | 34 | if root.left is None and root.right is None and root.val == sum: 35 | return True 36 | 37 | return self.hasPathSum(root.left, sum - root.val) or self.hasPathSum(root.right, sum - root.val) 38 | 39 | if __name__ == "__main__": 40 | root = TreeNode(5) 41 | root.left = TreeNode(4) 42 | root.right = TreeNode(8) 43 | root.left.left = TreeNode(11) 44 | root.left.left.right = TreeNode(2) 45 | print Solution().hasPathSum(root, 22) -------------------------------------------------------------------------------- /Python/permutation-sequence.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # The set [1,2,3,...,n] contains a total of n! unique permutations. 5 | # 6 | # By listing and labeling all of the permutations in order, 7 | # We get the following sequence (ie, for n = 3): 8 | # 9 | # "123" 10 | # "132" 11 | # "213" 12 | # "231" 13 | # "312" 14 | # "321" 15 | # Given n and k, return the kth permutation sequence. 16 | # 17 | # Note: Given n will be between 1 and 9 inclusive. 18 | # 19 | 20 | import math 21 | 22 | # Cantor ordering solution 23 | class Solution: 24 | # @return a string 25 | def getPermutation(self, n, k): 26 | seq, k, fact = "", k - 1, math.factorial(n - 1) 27 | perm = [i for i in xrange(1, n + 1)] 28 | for i in reversed(xrange(n)): 29 | curr = perm[k / fact] 30 | seq += str(curr) 31 | perm.remove(curr) 32 | if i > 0: 33 | k %= fact 34 | fact /= i 35 | return seq 36 | 37 | if __name__ == "__main__": 38 | print Solution().getPermutation(3, 2) 39 | -------------------------------------------------------------------------------- /Python/permutations-ii.py: -------------------------------------------------------------------------------- 1 | # Time: O(n!) 2 | # Space: O(n) 3 | # 4 | # Given a collection of numbers that might contain duplicates, return all possible unique permutations. 5 | # 6 | # For example, 7 | # [1,1,2] have the following unique permutations: 8 | # [1,1,2], [1,2,1], and [2,1,1]. 9 | # 10 | 11 | 12 | class Solution: 13 | # @param num, a list of integer 14 | # @return a list of lists of integers 15 | def permuteUnique(self, nums): 16 | solutions = [[]] 17 | 18 | for num in nums: 19 | next = [] 20 | for solution in solutions: 21 | for i in xrange(len(solution) + 1): 22 | candidate = solution[:i] + [num] + solution[i:] 23 | if candidate not in next: 24 | next.append(candidate) 25 | 26 | solutions = next 27 | 28 | return solutions 29 | 30 | if __name__ == "__main__": 31 | print Solution().permuteUnique([1, 1, 2]) 32 | print Solution().permuteUnique([1, -1, 1, 2, -1, 2, 2, -1]) 33 | 34 | 35 | -------------------------------------------------------------------------------- /Python/permutations.py: -------------------------------------------------------------------------------- 1 | # Time: O(n!) 2 | # Space: O(n) 3 | # 4 | # Given a collection of numbers, return all possible permutations. 5 | # 6 | # For example, 7 | # [1,2,3] have the following permutations: 8 | # [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1]. 9 | # 10 | 11 | 12 | class Solution: 13 | # @param num, a list of integer 14 | # @return a list of lists of integers 15 | def permute(self, num): 16 | result = [] 17 | used = [False] * len(num) 18 | self.permuteRecu(result, used, [], num) 19 | return result 20 | 21 | def permuteRecu(self, result, used, cur, num): 22 | if len(cur) == len(num): 23 | result.append(cur + []) 24 | return 25 | for i in xrange(len(num)): 26 | if not used[i]: 27 | used[i] = True 28 | cur.append(num[i]) 29 | self.permuteRecu(result, used, cur, num) 30 | cur.pop() 31 | used[i] = False 32 | 33 | if __name__ == "__main__": 34 | print Solution().permute([1, 2, 3]) 35 | 36 | -------------------------------------------------------------------------------- /Python/plus-one.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given a non-negative number represented as an array of digits, plus one to the number. 5 | # 6 | # The digits are stored such that the most significant digit is at the head of the list. 7 | # 8 | 9 | class Solution: 10 | # @param digits, a list of integer digits 11 | # @return a list of integer digits 12 | def plusOne(self, digits): 13 | carry = 1 14 | for i in reversed(xrange(len(digits))): 15 | digits[i] += carry 16 | carry = digits[i] / 10 17 | digits[i] %= 10 18 | 19 | if carry: 20 | digits = [1] + digits 21 | 22 | return digits 23 | 24 | if __name__ == "__main__": 25 | print Solution().plusOne([9, 9, 9, 9]) -------------------------------------------------------------------------------- /Python/powx-n.py: -------------------------------------------------------------------------------- 1 | # Time: O(logn) 2 | # Space: O(logn) 3 | # 4 | # Implement pow(x, n). 5 | # 6 | 7 | class Solution: 8 | # @param x, a float 9 | # @param n, a integer 10 | # @return a float 11 | def pow(self, x, n): 12 | if n < 0: 13 | return 1 / self.powRecu(x, -n) 14 | 15 | return self.powRecu(x, n) 16 | 17 | def powRecu(self, x, n): 18 | if n == 0: 19 | return 1.0 20 | 21 | if n % 2 == 0: 22 | return self.powRecu(x * x, n / 2) 23 | else: 24 | return x * self.powRecu(x * x, n / 2) 25 | 26 | if __name__ == "__main__": 27 | print Solution().pow(3, 5) 28 | print Solution().pow(3, -5) -------------------------------------------------------------------------------- /Python/remove-duplicates-from-sorted-array-ii.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Follow up for "Remove Duplicates": 5 | # What if duplicates are allowed at most twice? 6 | # 7 | # For example, 8 | # Given sorted array A = [1,1,1,2,2,3], 9 | # 10 | # Your function should return length = 5, and A is now [1,1,2,2,3]. 11 | # 12 | 13 | class Solution: 14 | # @param a list of integers 15 | # @return an integer 16 | def removeDuplicates(self, A): 17 | if len(A) == 0: 18 | return 0 19 | 20 | last, i, same = 0, 1, False 21 | while i < len(A): 22 | if A[last] != A[i] or not same: 23 | same = A[last] == A[i] 24 | last += 1 25 | A[last] = A[i] 26 | i += 1 27 | 28 | return last + 1 29 | 30 | if __name__ == "__main__": 31 | print Solution().removeDuplicates([1, 1, 1, 2, 2, 3]) -------------------------------------------------------------------------------- /Python/remove-duplicates-from-sorted-array.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. 5 | # 6 | # Do not allocate extra space for another array, you must do this in place with constant memory. 7 | # 8 | # For example, 9 | # Given input array A = [1,1,2], 10 | # 11 | # Your function should return length = 2, and A is now [1,2]. 12 | # 13 | 14 | class Solution: 15 | # @param a list of integers 16 | # @return an integer 17 | def removeDuplicates(self, A): 18 | if len(A) == 0: 19 | return 0 20 | 21 | last, i = 0, 1 22 | while i < len(A): 23 | if A[last] != A[i]: 24 | last += 1 25 | A[last] = A[i] 26 | i += 1 27 | 28 | return last + 1 29 | 30 | if __name__ == "__main__": 31 | print Solution().removeDuplicates([1, 1, 2]) -------------------------------------------------------------------------------- /Python/remove-duplicates-from-sorted-list.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given a sorted linked list, delete all duplicates such that each element appear only once. 5 | # 6 | # For example, 7 | # Given 1->1->2, return 1->2. 8 | # Given 1->1->2->3->3, return 1->2->3. 9 | # 10 | 11 | # Definition for singly-linked list. 12 | class ListNode: 13 | def __init__(self, x): 14 | self.val = x 15 | self.next = None 16 | 17 | def __repr__(self): 18 | if self is None: 19 | return "Nil" 20 | else: 21 | return "{} -> {}".format(self.val, repr(self.next)) 22 | 23 | class Solution: 24 | # @param head, a ListNode 25 | # @return a ListNode 26 | def deleteDuplicates(self, head): 27 | current = head 28 | while current and current.next: 29 | next = current.next 30 | if current.val == next.val: 31 | current.next = current.next.next 32 | else: 33 | current = next 34 | return head 35 | 36 | if __name__ == "__main__": 37 | head, head.next, head.next.next = ListNode(1), ListNode(1), ListNode(2) 38 | head.next.next.next, head.next.next.next.next = ListNode(3), ListNode(3) 39 | print Solution().deleteDuplicates(head) 40 | -------------------------------------------------------------------------------- /Python/remove-element.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given an array and a value, remove all instances of that value in place and return the new length. 5 | # 6 | # The order of elements can be changed. It doesn't matter what you leave beyond the new length. 7 | # 8 | 9 | class Solution: 10 | # @param A a list of integers 11 | # @param elem an integer, value need to be removed 12 | # @return an integer 13 | def removeElement(self, A, elem): 14 | i, last = 0, len(A) - 1 15 | while i <= last: 16 | if A[i] == elem: 17 | A[i], A[last] = A[last], A[i] 18 | last -= 1 19 | else: 20 | i += 1 21 | return last + 1 22 | 23 | if __name__ == "__main__": 24 | print Solution().removeElement([1, 2, 3, 4, 5, 2, 2], 2) -------------------------------------------------------------------------------- /Python/reverse-integer.py: -------------------------------------------------------------------------------- 1 | # Time: O(logn) 2 | # Space: O(1) 3 | # 4 | # Reverse digits of an integer. 5 | # 6 | # Example1: x = 123, return 321 7 | # Example2: x = -123, return -321 8 | # 9 | # click to show spoilers. 10 | # 11 | # Have you thought about this? 12 | # Here are some good questions to ask before coding. Bonus points for you if you have already thought through this! 13 | # 14 | # If the integer's last digit is 0, what should the output be? ie, cases such as 10, 100. 15 | # 16 | # Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, 17 | # then the reverse of 1000000003 overflows. How should you handle such cases? 18 | # 19 | # Throw an exception? Good, but what if throwing an exception is not an option? 20 | # You would then have to re-design the function (ie, add an extra parameter). 21 | # 22 | 23 | class Solution: 24 | # @return an integer 25 | def reverse(self, x): 26 | ans = 0 27 | if x >= 0: 28 | while x: 29 | ans = ans * 10 + x % 10 30 | x /= 10 31 | return ans 32 | else: 33 | return -self.reverse(-x) 34 | 35 | if __name__ == "__main__": 36 | print Solution().reverse(123) 37 | print Solution().reverse(-321) -------------------------------------------------------------------------------- /Python/reverse-words-in-a-string.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | # 4 | # Given an input string, reverse the string word by word. 5 | # 6 | # For example, 7 | # Given s = "the sky is blue", 8 | # return "blue is sky the". 9 | # 10 | # click to show clarification. 11 | # 12 | # Clarification: 13 | # What constitutes a word? 14 | # A sequence of non-space characters constitutes a word. 15 | # Could the input string contain leading or trailing spaces? 16 | # Yes. However, your reversed string should not contain leading or trailing spaces. 17 | # How about multiple spaces between two words? 18 | # Reduce them to a single space in the reversed string. 19 | # 20 | 21 | class Solution: 22 | # @param s, a string 23 | # @return a string 24 | def reverseWords(self, s): 25 | return ' '.join(reversed(s.split())) 26 | 27 | if __name__ == '__main__': 28 | print Solution().reverseWords('hello world') 29 | -------------------------------------------------------------------------------- /Python/roman-to-integer.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given a roman numeral, convert it to an integer. 5 | # 6 | # Input is guaranteed to be within the xrange from 1 to 3999. 7 | # 8 | 9 | class Solution: 10 | # @return an integer 11 | def romanToInt(self, s): 12 | numeral_map = {"I": 1, "V": 5, "X": 10, "L": 50, "C":100, "D": 500, "M": 1000} 13 | decimal = 0 14 | for i in xrange(len(s)): 15 | if i > 0 and numeral_map[s[i]] > numeral_map[s[i - 1]]: 16 | decimal += numeral_map[s[i]] - 2 * numeral_map[s[i - 1]] 17 | else: 18 | decimal += numeral_map[s[i]] 19 | return decimal 20 | 21 | if __name__ == "__main__": 22 | print Solution().romanToInt("IIVX") 23 | print Solution().romanToInt("MMMCMXCIX") 24 | -------------------------------------------------------------------------------- /Python/rotate-image.py: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(1) 3 | # 4 | # You are given an n x n 2D matrix representing an image. 5 | # 6 | # Rotate the image by 90 degrees (clockwise). 7 | # 8 | # Follow up: 9 | # Could you do this in-place? 10 | # 11 | 12 | # Time: O(n^2) 13 | # Space: O(1) 14 | class Solution: 15 | # @param matrix, a list of lists of integers 16 | # @return a list of lists of integers 17 | def rotate(self, matrix): 18 | n = len(matrix) 19 | 20 | # anti-diagonal mirror 21 | for i in xrange(n): 22 | for j in xrange(n - i): 23 | matrix[i][j], matrix[n - 1 - j][n - 1 -i] = matrix[n - 1 - j][n - 1 -i], matrix[i][j] 24 | 25 | # horizontal mirror 26 | for i in xrange(n / 2): 27 | for j in xrange(n): 28 | matrix[i][j], matrix[n - 1 - i][j] = matrix[n - 1 - i][j], matrix[i][j] 29 | 30 | return matrix 31 | 32 | # Time: O(n^2) 33 | # Space: O(n^2) 34 | class Solution2: 35 | # @param matrix, a list of lists of integers 36 | # @return a list of lists of integers 37 | def rotate(self, matrix): 38 | return [list(reversed(x)) for x in zip(*matrix)] 39 | 40 | if __name__ == "__main__": 41 | matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 42 | print Solution().rotate(matrix) 43 | -------------------------------------------------------------------------------- /Python/rotate-list.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given a list, rotate the list to the right by k places, where k is non-negative. 5 | # 6 | # For example: 7 | # Given 1->2->3->4->5->NULL and k = 2, 8 | # return 4->5->1->2->3->NULL. 9 | # 10 | 11 | # Definition for singly-linked list. 12 | class ListNode: 13 | def __init__(self, x): 14 | self.val = x 15 | self.next = None 16 | 17 | def __repr__(self): 18 | if self: 19 | return "{} -> {}".format(self.val, repr(self.next)) 20 | 21 | class Solution: 22 | # @param head, a ListNode 23 | # @param k, an integer 24 | # @return a ListNode 25 | def rotateRight(self, head, k): 26 | if head is None: 27 | return head 28 | 29 | cur, len = head, 1 30 | while cur.next: 31 | cur = cur.next 32 | len += 1 33 | cur.next = head 34 | 35 | cur = head 36 | shift = len - k % len - 1 37 | while shift > 0: 38 | cur = cur.next 39 | shift -= 1 40 | 41 | result = cur.next 42 | cur.next = None 43 | 44 | return result 45 | 46 | if __name__ == "__main__": 47 | head = ListNode(1) 48 | head.next = ListNode(2) 49 | head.next.next = ListNode(3) 50 | head.next.next.next = ListNode(4) 51 | head.next.next.next.next = ListNode(5) 52 | print Solution().rotateRight(head, 2) -------------------------------------------------------------------------------- /Python/same-tree.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(logn) 3 | # 4 | # Given two binary trees, write a function to check if they are equal or not. 5 | # 6 | # Two binary trees are considered equal if they are structurally identical and the nodes have the same value. 7 | # 8 | 9 | # Definition for a binary tree node 10 | class TreeNode: 11 | def __init__(self, x): 12 | self.val = x 13 | self.left = None 14 | self.right = None 15 | 16 | class Solution: 17 | # @param p, a tree node 18 | # @param q, a tree node 19 | # @return a boolean 20 | def isSameTree(self, p, q): 21 | if p is None and q is None: 22 | return True 23 | 24 | if p is not None and q is not None: 25 | return p.val == q.val and self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right) 26 | 27 | return False 28 | 29 | if __name__ == "__main__": 30 | root1, root1.left, root1.right = TreeNode(1), TreeNode(2), TreeNode(3) 31 | root2, root2.left, root2.right = TreeNode(1), TreeNode(2), TreeNode(3) 32 | print Solution().isSameTree(root1, root2) -------------------------------------------------------------------------------- /Python/search-a-2d-matrix.py: -------------------------------------------------------------------------------- 1 | # Time: O(logm + logn) 2 | # Space: O(1) 3 | # 4 | # Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: 5 | # 6 | # Integers in each row are sorted from left to right. 7 | # The first integer of each row is greater than the last integer of the previous row. 8 | # For example, 9 | # 10 | # Consider the following matrix: 11 | # 12 | # [ 13 | # [1, 3, 5, 7], 14 | # [10, 11, 16, 20], 15 | # [23, 30, 34, 50] 16 | # ] 17 | # Given target = 3, return true. 18 | # 19 | 20 | class Solution: 21 | # @param matrix, a list of lists of integers 22 | # @param target, an integer 23 | # @return a boolean 24 | def searchMatrix(self, matrix, target): 25 | m = len(matrix) 26 | n = len(matrix[0]) 27 | i, j = 0, m * n 28 | 29 | while i < j: 30 | mid = i + (j - i) / 2 31 | val = matrix[mid / n][mid % n] 32 | if val == target: 33 | return True 34 | elif val < target: 35 | i = mid + 1 36 | else: 37 | j = mid 38 | return False 39 | 40 | if __name__ == "__main__": 41 | matrix = [[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50]] 42 | print Solution().searchMatrix(matrix, 3) -------------------------------------------------------------------------------- /Python/search-for-a-range.py: -------------------------------------------------------------------------------- 1 | # Time: O(logn) 2 | # Space: O(1) 3 | # 4 | # Given a sorted array of integers, find the starting and ending position of a given target value. 5 | # 6 | # Your algorithm's runtime complexity must be in the order of O(log n). 7 | # 8 | # If the target is not found in the array, return [-1, -1]. 9 | # 10 | # For example, 11 | # Given [5, 7, 7, 8, 8, 10] and target value 8, 12 | # return [3, 4]. 13 | # 14 | 15 | class Solution: 16 | # @param A, a list of integers 17 | # @param target, an integer to be searched 18 | # @return a list of length 2, [index1, index2] 19 | def searchRange(self, A, target): 20 | left = self.binarySearch(lambda x, y: x > y, A, target) 21 | if left >= len(A) or A[left] != target: 22 | return [-1, -1] 23 | right = self.binarySearch(lambda x, y: x >= y, A, target) 24 | return [left, right - 1] 25 | 26 | def binarySearch(self, compare, A, target): 27 | start, end = 0, len(A) 28 | while start < end: 29 | mid = start + (end - start) / 2 30 | if compare(target, A[mid]): 31 | start = mid + 1 32 | else: 33 | end = mid 34 | return start 35 | 36 | if __name__ == "__main__": 37 | print Solution().searchRange([2, 2], 3) 38 | print Solution().searchRange([5, 7, 7, 8, 8, 10], 8) -------------------------------------------------------------------------------- /Python/search-in-rotated-sorted-array-ii.py: -------------------------------------------------------------------------------- 1 | # Time: O(logn) 2 | # Space: O(1) 3 | # 4 | # Follow up for "Search in Rotated Sorted Array": 5 | # What if duplicates are allowed? 6 | # 7 | # Would this affect the run-time complexity? How and why? 8 | # 9 | # Write a function to determine if a given target is in the array. 10 | # 11 | 12 | class Solution: 13 | # @param A a list of integers 14 | # @param target an integer 15 | # @return a boolean 16 | def search(self, A, target): 17 | low, high = 0, len(A) 18 | 19 | while low < high: 20 | mid = low + (high - low) / 2 21 | 22 | if A[mid] == target: 23 | return True 24 | 25 | if A[low] < A[mid]: 26 | if A[low] <= target and target < A[mid]: 27 | high = mid 28 | else: 29 | low = mid + 1 30 | elif A[low] > A[mid]: 31 | if A[mid] < target and target <= A[high - 1]: 32 | low = mid + 1 33 | else: 34 | high = mid 35 | else: 36 | low += 1 37 | 38 | return False 39 | 40 | 41 | if __name__ == "__main__": 42 | print Solution().search([3, 5, 1], 3) 43 | print Solution().search([2, 2, 3, 3, 4, 1], 1) 44 | print Solution().search([4, 4, 5, 6, 7, 0, 1, 2], 5) -------------------------------------------------------------------------------- /Python/search-in-rotated-sorted-array.py: -------------------------------------------------------------------------------- 1 | # Time: O(logn) 2 | # Space: O(1) 3 | # 4 | # Suppose a sorted array is rotated at some pivot unknown to you beforehand. 5 | # 6 | # (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). 7 | # 8 | # You are given a target value to search. If found in the array return its index, otherwise return -1. 9 | # 10 | # You may assume no duplicate exists in the array. 11 | # 12 | 13 | class Solution: 14 | # @param A, a list of integers 15 | # @param target, an integer to be searched 16 | # @return an integer 17 | def search(self, A, target): 18 | low, high = 0, len(A) 19 | 20 | while low < high: 21 | mid = low + (high - low) / 2 22 | 23 | if A[mid] == target: 24 | return mid 25 | 26 | if A[low] <= A[mid]: 27 | if A[low] <= target and target < A[mid]: 28 | high = mid 29 | else: 30 | low = mid + 1 31 | else: 32 | if A[mid] < target and target <= A[high - 1]: 33 | low = mid + 1 34 | else: 35 | high = mid 36 | 37 | return -1 38 | 39 | 40 | if __name__ == "__main__": 41 | print Solution().search([3, 5, 1], 3) 42 | print Solution().search([1], 1) 43 | print Solution().search([4, 5, 6, 7, 0, 1, 2], 5) -------------------------------------------------------------------------------- /Python/search-insert-position.py: -------------------------------------------------------------------------------- 1 | # Time: O(logn) 2 | # Space: O(1) 3 | # 4 | # Given a sorted array and a target value, return the index if the target is found. 5 | # 6 | # If not, return the index where it would be if it were inserted in order. 7 | # 8 | # You may assume no duplicates in the array. 9 | # 10 | # Here are few examples. 11 | # [1,3,5,6], 5 -> 2 12 | # [1,3,5,6], 2 -> 1 13 | # [1,3,5,6], 7 -> 4 14 | # [1,3,5,6], 0 -> 0 15 | # 16 | 17 | class Solution: 18 | # @param A, a list of integers 19 | # @param target, an integer to be inserted 20 | # @return integer 21 | def searchInsert(self, A, target): 22 | low, high = 0, len(A) - 1 23 | 24 | while low <= high: 25 | mid = low + (high - low) / 2 26 | if A[mid] == target: 27 | return mid 28 | elif A[mid] < target: 29 | low = mid + 1 30 | else: 31 | high = mid - 1 32 | 33 | return low 34 | 35 | if __name__ == "__main__": 36 | print Solution().searchInsert([1, 3, 5, 6], 5) 37 | print Solution().searchInsert([1, 3, 5, 6], 2) 38 | print Solution().searchInsert([1, 3, 5, 6], 7) 39 | print Solution().searchInsert([1, 3, 5, 6], 0) -------------------------------------------------------------------------------- /Python/simplify-path.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | # 4 | # Given an absolute path for a file (Unix-style), simplify it. 5 | # 6 | # For example, 7 | # path = "/home/", => "/home" 8 | # path = "/a/./b/../../c/", => "/c" 9 | # click to show corner cases. 10 | # 11 | # Corner Cases: 12 | # Did you consider the case where path = "/../"? 13 | # In this case, you should return "/". 14 | # Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/". 15 | # In this case, you should ignore redundant slashes and return "/home/foo". 16 | # 17 | 18 | class Solution: 19 | # @param path, a string 20 | # @return a string 21 | def simplifyPath(self, path): 22 | stack, tokens = [], path.split("/") 23 | for token in tokens: 24 | if token == ".." and stack: 25 | stack.pop() 26 | elif token != ".." and token != "." and token: 27 | stack.append(token) 28 | return "/" + "/".join(stack) 29 | 30 | if __name__ == "__main__": 31 | print Solution().simplifyPath("/../") 32 | print Solution().simplifyPath("/home//foo/") -------------------------------------------------------------------------------- /Python/single-number-ii.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given an array of integers, every element appears three times except for one. Find that single one. 5 | # 6 | # Note: 7 | # Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 8 | # 9 | 10 | class Solution: 11 | # @param A, a list of integer 12 | # @return an integer 13 | def singleNumber(self, A): 14 | one, two, carry = 0, 0, 0 15 | for x in A: 16 | two |= one & x 17 | one ^= x 18 | carry = one & two 19 | one &= ~carry 20 | two &= ~carry 21 | return one 22 | 23 | if __name__ == "__main__": 24 | print Solution().singleNumber([1, 1, 1, 2, 2, 2, 3]) -------------------------------------------------------------------------------- /Python/single-number.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given an array of integers, every element appears twice except for one. Find that single one. 5 | # 6 | # Note: 7 | # Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 8 | # 9 | 10 | import operator 11 | 12 | class Solution: 13 | # @param A, a list of integer 14 | # @return an integer 15 | def singleNumber(self, A): 16 | return reduce(operator.xor, A) 17 | 18 | if __name__ == '__main__': 19 | print Solution().singleNumber([1, 1, 2, 2, 3]) -------------------------------------------------------------------------------- /Python/sqrtx.py: -------------------------------------------------------------------------------- 1 | # Time: O(logn) 2 | # Space: O(1) 3 | # 4 | # Implement int sqrt(int x). 5 | # 6 | # Compute and return the square root of x. 7 | # 8 | 9 | class Solution: 10 | # @param x, an integer 11 | # @return an integer 12 | def sqrt(self, x): 13 | if x < 2: 14 | return x 15 | 16 | low, high = 1, x / 2 17 | while high >= low: 18 | mid = low + (high - low) / 2 19 | if x / mid < mid: 20 | high = mid - 1 21 | else: 22 | low = mid + 1 23 | return high 24 | 25 | if __name__ == "__main__": 26 | print Solution().sqrt(10) 27 | -------------------------------------------------------------------------------- /Python/subsets.py: -------------------------------------------------------------------------------- 1 | # Time: O(2^n) 2 | # Space: O(1) 3 | # 4 | # Given a set of distinct integers, S, return all possible subsets. 5 | # 6 | # Note: 7 | # Elements in a subset must be in non-descending order. 8 | # The solution set must not contain duplicate subsets. 9 | # For example, 10 | # If S = [1,2,3], a solution is: 11 | # 12 | # [ 13 | # [3], 14 | # [1], 15 | # [2], 16 | # [1,2,3], 17 | # [1,3], 18 | # [2,3], 19 | # [1,2], 20 | # [] 21 | # ] 22 | # 23 | 24 | class Solution: 25 | # @param S, a list of integer 26 | # @return a list of lists of integer 27 | def subsets(self, S): 28 | result = [] 29 | i, count = 0, 1 << len(S) 30 | S = sorted(S) 31 | 32 | while i < count: 33 | cur = [] 34 | for j in xrange(len(S)): 35 | if i & 1 << j: 36 | cur.append(S[j]) 37 | result.append(cur) 38 | i += 1 39 | 40 | return result 41 | 42 | class Solution2: 43 | # @param S, a list of integer 44 | # @return a list of lists of integer 45 | def subsets(self, S): 46 | return self.subsetsRecu([], sorted(S)) 47 | 48 | def subsetsRecu(self, cur, S): 49 | if len(S) == 0: 50 | return [cur] 51 | 52 | return self.subsetsRecu(cur, S[1:]) + self.subsetsRecu(cur + [S[0]], S[1:]) 53 | 54 | if __name__ == "__main__": 55 | print Solution().subsets([1, 2, 3]) -------------------------------------------------------------------------------- /Python/sum-root-to-leaf-numbers.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(logn) 3 | # 4 | # Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. 5 | # 6 | # An example is the root-to-leaf path 1->2->3 which represents the number 123. 7 | # 8 | # Find the total sum of all root-to-leaf numbers. 9 | # 10 | # For example, 11 | # 12 | # 1 13 | # / \ 14 | # 2 3 15 | # The root-to-leaf path 1->2 represents the number 12. 16 | # The root-to-leaf path 1->3 represents the number 13. 17 | # 18 | # Return the sum = 12 + 13 = 25. 19 | # 20 | 21 | # Definition for a binary tree node 22 | class TreeNode: 23 | def __init__(self, x): 24 | self.val = x 25 | self.left = None 26 | self.right = None 27 | 28 | class Solution: 29 | # @param root, a tree node 30 | # @return an integer 31 | def sumNumbers(self, root): 32 | return self.sumNumbersRecu(root, 0) 33 | 34 | def sumNumbersRecu(self, root, num): 35 | if root is None: 36 | return 0 37 | 38 | if root.left is None and root.right is None: 39 | return num * 10 + root.val 40 | 41 | return self.sumNumbersRecu(root.left, num * 10 + root.val) + self.sumNumbersRecu(root.right, num * 10 + root.val) 42 | 43 | if __name__ == "__main__": 44 | root = TreeNode(1) 45 | root.left = TreeNode(2) 46 | root.right = TreeNode(3) 47 | print Solution().sumNumbers(root) -------------------------------------------------------------------------------- /Python/swap-nodes-in-pairs.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given a linked list, swap every two adjacent nodes and return its head. 5 | # 6 | # For example, 7 | # Given 1->2->3->4, you should return the list as 2->1->4->3. 8 | # 9 | # Your algorithm should use only constant space. 10 | # You may not modify the values in the list, only nodes itself can be changed. 11 | # 12 | 13 | # Definition for singly-linked list. 14 | class ListNode: 15 | def __init__(self, x): 16 | self.val = x 17 | self.next = None 18 | 19 | def __repr__(self): 20 | if self: 21 | return "{} -> {}".format(self.val, self.next) 22 | 23 | class Solution: 24 | # @param a ListNode 25 | # @return a ListNode 26 | def swapPairs(self, head): 27 | dummy = ListNode(0) 28 | dummy.next = head 29 | current = dummy 30 | while current.next and current.next.next: 31 | next_one, next_two, next_three = current.next, current.next.next, current.next.next.next 32 | current.next = next_two 33 | next_two.next = next_one 34 | next_one.next = next_three 35 | current = next_one 36 | return dummy.next 37 | 38 | if __name__ == "__main__": 39 | head = ListNode(1) 40 | head.next, head.next.next, head.next.next.next = ListNode(2), ListNode(3), ListNode(4) 41 | print Solution().swapPairs(head) 42 | -------------------------------------------------------------------------------- /Python/triangle.py: -------------------------------------------------------------------------------- 1 | # Time: O(m * n) 2 | # Space: O(n) 3 | # 4 | # Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below. 5 | # 6 | # For example, given the following triangle 7 | # [ 8 | # [2], 9 | # [3,4], 10 | # [6,5,7], 11 | # [4,1,8,3] 12 | # ] 13 | # The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11). 14 | # 15 | # Note: 16 | # Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle. 17 | # 18 | 19 | class Solution: 20 | # @param triangle, a list of lists of integers 21 | # @return an integer 22 | def minimumTotal(self, triangle): 23 | if len(triangle) == 0: 24 | return 0 25 | 26 | cur = triangle[0] + [float("inf")] 27 | for i in xrange(1, len(triangle)): 28 | next = [] 29 | next.append(triangle[i][0] + cur[0]) 30 | for j in xrange(1, i + 1): 31 | next.append(triangle[i][j] + min(cur[j - 1], cur[j])) 32 | cur = next + [float("inf")] 33 | 34 | return reduce(min, cur) 35 | 36 | if __name__ == "__main__": 37 | print Solution().minimumTotal([[-1], [2, 3], [1, -1, -3]]) 38 | -------------------------------------------------------------------------------- /Python/two-sum-ii-input-array-is-sorted.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given an array of integers that is already sorted in ascending order, 5 | # find two numbers such that they add up to a specific target number. 6 | # 7 | # The function twoSum should return indices of the two numbers such that 8 | # they add up to the target, where index1 must be less than index2. 9 | # Please note that your returned answers (both index1 and index2) are not zero-based. 10 | # 11 | # You may assume that each input would have exactly one solution. 12 | # 13 | # Input: numbers={2, 7, 11, 15}, target=9 14 | # Output: index1=1, index2=2 15 | # 16 | 17 | class Solution: 18 | def twoSum(self, nums, target): 19 | start, end = 0, len(nums) - 1 20 | 21 | while start != end: 22 | sum = nums[start] + nums[end] 23 | if sum > target: 24 | end -= 1 25 | elif sum < target: 26 | start += 1 27 | else: 28 | return [start + 1, end + 1] 29 | 30 | if __name__ == "__main__": 31 | print Solution().twoSum([2, 7, 11, 15], 9) 32 | -------------------------------------------------------------------------------- /Python/two-sum-iii-data-structure-design.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | # 4 | # Design and implement a TwoSum class. It should support the following operations: add and find. 5 | # 6 | # add - Add the number to an internal data structure. 7 | # find - Find if there exists any pair of numbers which sum is equal to the value. 8 | # 9 | # For example, 10 | # add(1); add(3); add(5); 11 | # find(4) -> true 12 | # find(7) -> false 13 | # 14 | 15 | class TwoSum: 16 | 17 | # initialize your data structure here 18 | def __init__(self): 19 | self.lookup = {} 20 | 21 | 22 | # @return nothing 23 | def add(self, number): 24 | if number in self.lookup: 25 | self.lookup[number] += 1 26 | else: 27 | self.lookup[number] = 1 28 | 29 | # @param value, an integer 30 | # @return a Boolean 31 | def find(self, value): 32 | for key in self.lookup: 33 | num = value - key 34 | if num in self.lookup and (num != key or self.lookup[key] > 1): 35 | return True 36 | return False 37 | 38 | if __name__ == "__main__": 39 | Sol = TwoSum() 40 | 41 | for i in (1, 3, 5): 42 | Sol.add(i) 43 | 44 | for i in (4, 7): 45 | print Sol.find(i) 46 | 47 | -------------------------------------------------------------------------------- /Python/two-sum.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | # 4 | # Given an array of integers, find two numbers such that 5 | # they add up to a specific target number. 6 | # The function twoSum should return indices of the two numbers such that 7 | # they add up to the target, 8 | # where index1 must be less than index2. Please note that 9 | # your returned answers (both index1 and index2) are not zero-based. 10 | # You may assume that each input would have exactly one solution. 11 | # 12 | # Input: numbers={2, 7, 11, 15}, target=9 13 | # Output: index1=1, index2=2 14 | # 15 | 16 | class Solution: 17 | def twoSum(self, nums, target): 18 | lookup = {} 19 | for i, num in enumerate(nums): 20 | if target - num in lookup: 21 | return (lookup[target - num] + 1, i + 1) 22 | lookup[num] = i 23 | 24 | if __name__ == '__main__': 25 | print "index1=%d, index2=%d" % Solution().twoSum((2, 7, 11, 15), 9) -------------------------------------------------------------------------------- /Python/unique-binary-search-trees.py: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | # 4 | # Given n, how many structurally unique BST's (binary search trees) that store values 1...n? 5 | # 6 | # For example, 7 | # Given n = 3, there are a total of 5 unique BST's. 8 | # 9 | # 1 3 3 2 1 10 | # \ / / / \ \ 11 | # 3 2 1 1 3 2 12 | # / / \ \ 13 | # 2 1 2 3 14 | # 15 | 16 | class Solution: 17 | # @return an integer 18 | def numTrees(self, n): 19 | counts = [1, 1] 20 | for i in xrange(2, n + 1): 21 | count = 0 22 | for j in xrange(i): 23 | count += counts[j] * counts[i - j - 1] 24 | counts.append(count) 25 | return counts[-1] 26 | 27 | if __name__ == "__main__": 28 | print Solution().numTrees(3) 29 | -------------------------------------------------------------------------------- /Python/unique-paths.py: -------------------------------------------------------------------------------- 1 | # Time: O(m * n) 2 | # Space: O(m + n) 3 | # 4 | # A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). 5 | # 6 | # The robot can only move either down or right at any point in time. 7 | # The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). 8 | # 9 | # How many possible unique paths are there? 10 | # 11 | # Note: m and n will be at most 100. 12 | # 13 | 14 | class Solution: 15 | # @return an integer 16 | def uniquePaths(self, m, n): 17 | if m < n: 18 | return self.uniquePaths(n, m) 19 | ways = [1] * n 20 | 21 | for i in xrange(1, m): 22 | for j in xrange(1, n): 23 | ways[j] += ways[j - 1] 24 | 25 | return ways[n - 1] 26 | 27 | if __name__ == "__main__": 28 | print Solution().uniquePaths(1, 2) 29 | -------------------------------------------------------------------------------- /Python/valid-palindrome.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. 5 | # 6 | # For example, 7 | # "A man, a plan, a canal: Panama" is a palindrome. 8 | # "race a car" is not a palindrome. 9 | # 10 | # Note: 11 | # Have you consider that the string might be empty? This is a good question to ask during an interview. 12 | # 13 | # For the purpose of this problem, we define empty string as valid palindrome. 14 | # 15 | 16 | class Solution: 17 | # @param s, a string 18 | # @return a boolean 19 | def isPalindrome(self, s): 20 | i, j = 0, len(s) - 1 21 | while i < j: 22 | while i < j and not (s[i].isalpha() or s[i].isdigit()): 23 | i += 1 24 | while i < j and not (s[j].isalpha() or s[j].isdigit()): 25 | j -= 1 26 | if s[i].lower() != s[j].lower(): 27 | return False 28 | i, j = i + 1, j - 1 29 | return True 30 | 31 | if __name__ == "__main__": 32 | print Solution().isPalindrome("A man, a plan, a canal: Panama") -------------------------------------------------------------------------------- /Python/valid-parentheses.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | # 4 | # Given a string containing just the characters '(', ')', '{', '}', '[' and ']', 5 | # determine if the input string is valid. 6 | # 7 | # The brackets must close in the correct order, "()" and "()[]{}" 8 | # are all valid but "(]" and "([)]" are not. 9 | # 10 | 11 | class Solution: 12 | # @return a boolean 13 | def isValid(self, s): 14 | stack, lookup = [], {"(": ")", "{": "}", "[": "]"} 15 | for parenthese in s: 16 | if parenthese in lookup: 17 | stack.append(parenthese) 18 | elif len(stack) == 0 or lookup[stack.pop()] != parenthese: 19 | return False 20 | return len(stack) == 0 21 | 22 | if __name__ == "__main__": 23 | print Solution().isValid("()[]{}") 24 | print Solution().isValid("()[{]}") -------------------------------------------------------------------------------- /Python/validate-binary-search-tree.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(logn) 3 | # 4 | # Given a binary tree, determine if it is a valid binary search tree (BST). 5 | # 6 | # Assume a BST is defined as follows: 7 | # 8 | # The left subtree of a node contains only nodes with keys less than the node's key. 9 | # The right subtree of a node contains only nodes with keys greater than the node's key. 10 | # Both the left and right subtrees must also be binary search trees. 11 | # 12 | 13 | # Definition for a binary tree node 14 | class TreeNode: 15 | def __init__(self, x): 16 | self.val = x 17 | self.left = None 18 | self.right = None 19 | 20 | class Solution: 21 | # @param root, a tree node 22 | # @return a boolean 23 | def isValidBST(self, root): 24 | return self.isValidBSTRecu(root, float("-inf"), float("inf")) 25 | 26 | def isValidBSTRecu(self, root, low, high): 27 | if root is None: 28 | return True 29 | 30 | return low < root.val and root.val < high \ 31 | and self.isValidBSTRecu(root.left, low, root.val) \ 32 | and self.isValidBSTRecu(root.right, root.val, high) 33 | 34 | if __name__ == "__main__": 35 | root = TreeNode(2) 36 | root.left = TreeNode(1) 37 | root.right = TreeNode(3) 38 | print Solution().isValidBST(root) -------------------------------------------------------------------------------- /Python/word-break.py: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | # 4 | # Given a string s and a dictionary of words dict, 5 | # determine if s can be segmented into a space-separated sequence of one or more dictionary words. 6 | # 7 | # For example, given 8 | # s = "leetcode", 9 | # dict = ["leet", "code"]. 10 | # 11 | # Return true because "leetcode" can be segmented as "leet code". 12 | # 13 | 14 | class Solution: 15 | # @param s, a string 16 | # @param dict, a set of string 17 | # @return a boolean 18 | def wordBreak(self, s, dict): 19 | n = len(s) 20 | possible = [False for _ in xrange(n)] 21 | for i in xrange(n): 22 | if s[:i+1] in dict: 23 | possible[i] = True 24 | for j in xrange(i): 25 | if possible[j] and s[j+1:i+1] in dict: 26 | possible[i] = True 27 | break 28 | 29 | return possible[n-1] 30 | 31 | if __name__ == "__main__": 32 | print Solution().wordBreak("leetcode", ["leet", "code"]) -------------------------------------------------------------------------------- /Python/zigzag-conversion.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: 5 | # (you may want to display this pattern in a fixed font for better legibility) 6 | # 7 | # P A H N 8 | # A P L S I I G 9 | # Y I R 10 | # And then read line by line: "PAHNAPLSIIGYIR" 11 | # Write the code that will take a string and make this conversion given a number of rows: 12 | # 13 | # string convert(string text, int nRows); 14 | # convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR". 15 | # 16 | 17 | class Solution: 18 | # @return a string 19 | def convert(self, s, nRows): 20 | step, zigzag = 2 * nRows - 2, "" 21 | if s == None or len(s) == 0 or nRows <= 0: 22 | return "" 23 | if nRows == 1: 24 | return s 25 | for i in xrange(nRows): 26 | for j in xrange(i, len(s), step): 27 | zigzag += s[j] 28 | if i > 0 and i < nRows - 1 and j + step - 2 * i < len(s): 29 | zigzag += s[j + step - 2 * i] 30 | return zigzag 31 | 32 | if __name__ == "__main__": 33 | print Solution().convert("PAYPALISHIRING", 3) --------------------------------------------------------------------------------