Repository: leetcoders/LeetCode Branch: master Commit: 6109e6b06c01 Files: 172 Total size: 289.8 KB Directory structure: gitextract_en36ixoy/ ├── .gitattributes ├── .gitignore ├── 3Sum.h ├── 3SumClosest.h ├── 4Sum.h ├── AddBinary.h ├── AddTwoNumbers.h ├── Anagrams.h ├── BalancedBinaryTree.h ├── BestTimetoBuyandSellStock.h ├── BestTimetoBuyandSellStockII.h ├── BestTimetoBuyandSellStockIII.h ├── BinarySearchTreeIterator.h ├── BinaryTreeInorderTraversal.h ├── BinaryTreeLevelOrderTraversal.h ├── BinaryTreeLevelOrderTraversalII.h ├── BinaryTreeMaximumPathSum.h ├── BinaryTreePostorderTraversal.h ├── BinaryTreePreorderTraversal.h ├── BinaryTreeZigzagLevelOrderTraversal.h ├── Candy.h ├── ClimbingStairs.h ├── CloneGraph.h ├── CombinationSum.h ├── CombinationSumII.h ├── Combinations.h ├── CompareVersionNumbers.h ├── ConstructBinaryTreefromInorderandPostorderTraversal.h ├── ConstructBinaryTreefromPreorderandInorderTraversal.h ├── ContainerWithMostWater.h ├── ConvertSortedArraytoBinarySearchTree.h ├── ConvertSortedListtoBinarySearchTree.h ├── CopyListwithRandomPointer.h ├── CountandSay.h ├── DecodeWays.h ├── DistinctSubsequences.h ├── DivideTwoIntegers.h ├── DungeonGame.h ├── EditDistance.h ├── EvaluateReversePolishNotation.h ├── ExcelSheetColumnNumber.h ├── ExcelSheetColumnTitle.h ├── FactorialTrailingZeroes.cpp ├── FindMinimumInRotatedSortedArray.h ├── FindMinimumInRotatedSortedArrayII.h ├── FindPeakElement.h ├── FirstMissingPositive.h ├── FlattenBinaryTreetoLinkedList.h ├── FractionToRecurringDecimal.h ├── GasStation.h ├── GenerateParentheses.h ├── GrayCode.h ├── ImplementstrStr().h ├── InsertInterval.h ├── InsertionSortList.h ├── IntegertoRoman.h ├── InterleavingString.h ├── IntersectionOfTwoLinkedLists.h ├── JumpGame.h ├── JumpGameII.h ├── LRUCache.h ├── LargestNumber.h ├── LargestRectangleinHistogram.h ├── LengthofLastWord.h ├── LetterCombinationsofaPhoneNumber.h ├── LinkedListCycle.h ├── LinkedListCycleII.h ├── LongestCommonPrefix.h ├── LongestConsecutiveSequence.h ├── LongestPalindromicSubstring.h ├── LongestSubstringWithoutRepeatingCharacters.h ├── LongestValidParentheses.h ├── MajorityElement.h ├── MaxPointsOnALine.h ├── MaximalRectangle.h ├── MaximumDepthofBinaryTree.h ├── MaximumGap.h ├── MaximumProductSubarray.h ├── MaximumSubarray.h ├── MedianofTwoSortedArrays.h ├── MergeIntervals.h ├── MergeSortedArray.h ├── MergeTwoSortedLists.h ├── MergekSortedLists.h ├── MinStack.h ├── MinimumDepthofBinaryTree.h ├── MinimumPathSum.h ├── MinimumWindowSubstring.h ├── MultiplyStrings.h ├── N-Queens.h ├── N-QueensII.h ├── NextPermutation.h ├── PalindromeNumber.h ├── PalindromePartitioning.h ├── PalindromePartitioningII.h ├── PartitionList.h ├── Pascal'sTriangle.h ├── Pascal'sTriangleII.h ├── PathSum.h ├── PathSum2.h ├── PermutationSequence.h ├── Permutations.h ├── PermutationsII.h ├── PlusOne.h ├── PopulatingNextRightPointersinEachNode.h ├── PopulatingNextRightPointersinEachNodeII.h ├── Pow(x,n).h ├── README.md ├── RecoverBinarySearchTree.h ├── RegularExpressionMatching.h ├── RemoveDuplicatesfromSortedArray.h ├── RemoveDuplicatesfromSortedArrayII.h ├── RemoveDuplicatesfromSortedList.h ├── RemoveDuplicatesfromSortedListII.h ├── RemoveElement.h ├── RemoveNthNodeFromEndofList.h ├── ReorderList.h ├── RepeatedDNASequences.h ├── RestoreIPAddresses.h ├── ReverseInteger.h ├── ReverseLinkedListII.h ├── ReverseNodesinkGroup.h ├── ReverseWordsInAString.h ├── RomantoInteger.h ├── RotateImage.h ├── RotateList.h ├── SameTree.h ├── ScrambleString.h ├── SearchInsertPosition.h ├── Searcha2DMatrix.h ├── SearchforaRange.h ├── SearchinRotatedSortedArray.h ├── SearchinRotatedSortedArrayII.h ├── SetMatrixZeroes.h ├── SimplifyPath.h ├── SingleNumber.h ├── SingleNumberII.h ├── SortColors.h ├── SortList.h ├── SpiralMatrix.h ├── SpiralMatrixII.h ├── Sqrt(x).h ├── StringtoInteger(atoi).h ├── Subsets.h ├── SubsetsII.h ├── SubstringwithConcatenationofAllWords.h ├── SudokuSolver.h ├── SumRoottoLeafNumbers.h ├── SurroundedRegions.h ├── SwapNodesinPairs.h ├── SymmetricTree.h ├── TextJustification.h ├── TrappingRainWater.h ├── Triangle.h ├── TwoSum.h ├── TwoSumIII.h ├── UniqueBinarySearchTrees.h ├── UniqueBinarySearchTreesII.h ├── UniquePaths.h ├── UniquePathsII.h ├── ValidNumber.h ├── ValidPalindrome.h ├── ValidParentheses.h ├── ValidSudoku.h ├── ValidateBinarySearchTree.h ├── WildcardMatching.h ├── WordBreak.h ├── WordBreakII.h ├── WordLadder.h ├── WordLadderII.h ├── WordSearch.h └── ZigZagConversion.h ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ # Auto detect text files and perform LF normalization * text=auto # Custom for Visual Studio *.cs diff=csharp *.sln merge=union *.csproj merge=union *.vbproj merge=union *.fsproj merge=union *.dbproj merge=union # Standard to msysgit *.doc diff=astextplain *.DOC diff=astextplain *.docx diff=astextplain *.DOCX diff=astextplain *.dot diff=astextplain *.DOT diff=astextplain *.pdf diff=astextplain *.PDF diff=astextplain *.rtf diff=astextplain *.RTF diff=astextplain ================================================ FILE: .gitignore ================================================ ################# ## Eclipse ################# *.pydevproject .project .metadata bin/ tmp/ *.tmp *.bak *.swp *~.nib local.properties .classpath .settings/ .loadpath # External tool builders .externalToolBuilders/ # Locally stored "Eclipse launch configurations" *.launch # CDT-specific .cproject # PDT-specific .buildpath ################# ## Visual Studio ################# ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. # User-specific files *.suo *.user *.sln.docstates # Build results [Dd]ebug/ [Rr]elease/ *_i.c *_p.c *.ilk *.meta *.obj *.pch *.pdb *.pgc *.pgd *.rsp *.sbr *.tlb *.tli *.tlh *.tmp *.vspscc .builds *.dotCover ## TODO: If you have NuGet Package Restore enabled, uncomment this #packages/ # Visual C++ cache files ipch/ *.aps *.ncb *.opensdf *.sdf # Visual Studio profiler *.psess *.vsp # ReSharper is a .NET coding add-in _ReSharper* # Installshield output folder [Ee]xpress # DocProject is a documentation generator add-in DocProject/buildhelp/ DocProject/Help/*.HxT DocProject/Help/*.HxC DocProject/Help/*.hhc DocProject/Help/*.hhk DocProject/Help/*.hhp DocProject/Help/Html2 DocProject/Help/html # Click-Once directory publish # Others [Bb]in [Oo]bj sql TestResults *.Cache ClientBin stylecop.* ~$* *.dbmdl Generated_Code #added for RIA/Silverlight projects # Backup & report files from converting an old project file to a newer # Visual Studio version. Backup files are not needed, because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML ############ ## Windows ############ # Windows image file caches Thumbs.db # Folder config file Desktop.ini ############# ## Python ############# *.py[co] # Packages *.egg *.egg-info dist build eggs parts bin var sdist develop-eggs .installed.cfg # Installer logs pip-log.txt # Unit test / coverage reports .coverage .tox #Translations *.mo #Mr Developer .mr.developer.cfg # Mac crap .DS_Store ================================================ FILE: 3Sum.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 19, 2013 Update: Sep 22, 2013 Problem: 3Sum Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_15 Notes: Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. Note: Elements in a triplet (a,b,c) must be in non-descending order. (ie, a <= b <= c) The solution set must not contain duplicate triplets. For example, given array S = {-1 0 1 2 -1 -4}, A solution set is: (-1, 0, 1) (-1, -1, 2) Solution: Simplify '3sum' to '2sum' O(n^2). http://en.wikipedia.org/wiki/3SUM */ class Solution { public: vector > threeSum(vector &num) { vector> res; sort(num.begin(), num.end()); int N = num.size(); for (int i = 0; i < N-2 && num[i] <= 0; ++i) { if (i > 0 && num[i] == num[i-1]) continue; // avoid duplicates int twosum = 0 - num[i]; int l = i + 1, r = N - 1; while (l < r) { int sum = num[l] + num[r]; if (sum < twosum) l++; else if (sum > twosum) r--; else { res.push_back(vector{num[i],num[l],num[r]}); l++; r--; while (l < r && num[l] == num[l-1]) l++; // avoid duplicates while (l < r && num[r] == num[r+1]) r--; // avoid duplicates } } } return res; } }; ================================================ FILE: 3SumClosest.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 20, 2013 Problem: 3Sum Closest Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_16 Notes: Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. For example, given array S = {-1 2 1 -4}, and target = 1. The sum that is closest to the target is 2. (-1 + 2 + 1 = 2). Solution: Similar to 3Sum, taking O(n^2) time complexity. */ class Solution { public: int threeSumClosest(vector &num, int target) { int N = num.size(); if (N < 3) return 0; int res = num[0] + num[1] + num[2]; sort(num.begin(), num.end()); for (int i = 0; i < N-2; ++i) { int l = i + 1, r = N - 1; while (l < r) { int threesum = num[i] + num[l] + num[r]; if (threesum == target) return target; else if (threesum < target) ++l; else --r; if (abs(threesum - target) < abs(res - target)) res = threesum; } } return res; } }; ================================================ FILE: 4Sum.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 20, 2013 Update: Sep 26, 2013 Problem: 4Sum Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_18 Notes: Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. Note: Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target. Note: Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a <= b <= c <= d) The solution set must not contain duplicate quadruplets. For example, given array S = {1 0 -1 0 -2 2}, and target = 0. A solution set is: (-1, 0, 0, 1) (-2, -1, 1, 2) (-2, 0, 0, 2) Solution: Similar to 3Sum, 2Sum. */ class Solution { public: vector > fourSum(vector &num, int target) { int N = num.size(); vector > res; if (N < 4) return res; sort(num.begin(), num.end()); for (int i = 0; i < N; ++i) { if (i > 0 && num[i] == num[i-1]) continue; // avoid duplicates for (int j = i+1; j < N; ++j) { if (j > i+1 && num[j] == num[j-1]) continue; // avoid duplicates int twosum = target - num[i] - num[j]; int l = j + 1, r = N - 1; while (l < r) { int sum = num[l] + num[r]; if (sum == twosum) { vector quadruplet(4); quadruplet[0] = num[i]; quadruplet[1] = num[j]; quadruplet[2] = num[l]; quadruplet[3] = num[r]; res.push_back(quadruplet); while (l < r && num[l+1] == num[l]) l++; // avoid duplicates while (l < r && num[r-1] == num[r]) r--; // avoid duplicates l++; r--; } else if (sum < twosum) l++; else r--; } } } return res; } }; ================================================ FILE: AddBinary.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 17, 2013 Update: Sep 25, 2013 Problem: Add Binary Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_67 Notes: Given two binary strings, return their sum (also a binary string). For example, a = "11" b = "1" Return "100". Solution: '1'-'0' = 1. */ class Solution { public: string addBinary(string a, string b) { int N = a.size(), M = b.size(), K = max(N, M); string res(K, ' '); int carry = 0; int i = N-1, j = M-1, k = K-1; while (i >= 0 || j >= 0) { int sum = carry; if (i >= 0) sum += a[i--] - '0'; if (j >= 0) sum += b[j--] - '0'; carry = sum / 2; res[k--] = sum % 2 + '0'; } if (carry == 1) res.insert(res.begin(), '1'); return res; } }; ================================================ FILE: AddTwoNumbers.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Jan 16, 2013 Update: Sep 22, 2013 Problem: Add Two Numbers Difficulty: easy Source: http://www.leetcode.com/onlinejudge Notes: You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 0 -> 8 Solution: dummy head... */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) { ListNode dummy(0), *cur = &dummy; int carry = 0; while (l1 || l2 || carry) { int sum = carry; if (l1) { sum += l1->val; l1 = l1->next; } if (l2) { sum += l2->val; l2 = l2->next; } carry = sum >= 10 ? 1 : 0; sum %= 10; ListNode *newNode = new ListNode(sum); cur->next = newNode; cur = newNode; } return dummy.next; } }; ================================================ FILE: Anagrams.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 17, 2013 Update: Sep 25, 2013 Problem: Anagrams Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_49 Notes: Given an array of strings, return all groups of strings that are anagrams. Note: All inputs will be in lower-case. Solution: Sort the string to see if they're anagrams. Solution 1 is simpler than 2. */ class Solution { public: vector anagrams(vector &strs) { return anagrams_1(strs); } // solution 1 vector anagrams_1(vector &strs) { typedef map > MAP; MAP map; for (int i = 0; i < strs.size(); ++i) { string s = strs[i]; sort(s.begin(), s.end()); map[s].push_back(i); } vector res; MAP::iterator it = map.begin(); for (; it != map.end(); it++) { vector &anagrams = it->second; if (anagrams.size() > 1) { for (int i = 0; i < anagrams.size(); ++i) res.push_back(strs[anagrams[i]]); } } return res; } // solution 2 vector anagrams_2(vector &strs) { typedef unordered_map MAP; vector res; MAP anagram; for (int i = 0; i < strs.size(); ++i) { string s = strs[i]; sort(s.begin(), s.end()); MAP::iterator it = anagram.find(s); if (it == anagram.end()) { anagram[s] = i; } else { if (it->second >= 0) { res.push_back(strs[it->second]); it->second = -1; } res.push_back(strs[i]); } } return res; } }; ================================================ FILE: BalancedBinaryTree.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Apr 10, 2013 Update: Oct 07, 2014 Problem: Balanced Binary Tree Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_110 Notes: Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1. Solution: DFS. */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: bool isBalanced(TreeNode *root) { return solve(root) != -1; } int solve(TreeNode *root) { if (root == NULL) return 0; int left = solve(root->left); int right = solve(root->right); if (left == -1 || right == -1 || abs(left - right) > 1) return -1; return max(left,right) + 1; } }; ================================================ FILE: BestTimetoBuyandSellStock.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Apr 28, 2013 Update: Oct 07, 2014 Problem: Best Time to Buy and Sell Stock Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_121 Notes: Say you have an array for which the ith element is the price of a given stock on day i. 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. Solution: For each element, calculate the max difference with the former elements. */ class Solution { public: int maxProfit(vector &prices) { int size = prices.size(); if (prices.empty()) return 0; int minVal = prices[0], res = 0; for (int i = 1; i < size; ++i) { minVal = min(minVal, prices[i]); res = max(res, prices[i] - minVal); } return res; } }; ================================================ FILE: BestTimetoBuyandSellStockII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 28, 2013 Problem: Best Time to Buy and Sell Stock II Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_122 Notes: Say you have an array for which the ith element is the price of a given stock on day i. Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again). Solution: 1. At the beginning of the ascending order: buy. At the ending of the ascending order: sell. 2. For ascending order [1,2,4], (4 - 1) == (2 - 1) + (4 - 2). */ class Solution { public: int maxProfit(vector &prices) { return maxProfit_2(prices); } int maxProfit_1(vector &prices) { int res = 0; int buy_i = -1; for (int i = 1; i < prices.size(); ++i) { if (prices[i] > prices[i-1] && buy_i == -1) { buy_i = i - 1; } else if (prices[i] < prices[i -1] && buy_i != -1) { res += prices[i-1] - prices[buy_i]; buy_i = -1; } } if (buy_i != -1) res += prices[prices.size() - 1] - prices[buy_i]; return res; } int maxProfit_2(vector &prices) { int res = 0; for (int i = 1; i < prices.size(); ++i) if (prices[i] > prices[i-1]) res += prices[i] - prices[i-1]; return res; } }; ================================================ FILE: BestTimetoBuyandSellStockIII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 28, 2013 Update: Aug 22, 2013 Problem: Best Time to Buy and Sell Stock III Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_123 Notes: Say you have an array for which the ith element is the price of a given stock on day i. Design an algorithm to find the maximum profit. You may complete at most two transactions. Note: You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again). Solution: dp. max profit = max { l2r[0...i] + r2l[i+1...N-1] }. 0 <= i <= N-1 */ class Solution { public: int maxProfit(vector &prices) { int N = prices.size(); if (N <= 1) return 0; int l2r[N], r2l[N]; l2r[0] = 0; r2l[N-1] = 0; int minn = prices[0]; for (int i = 1; i < N; ++i) { minn = min(minn, prices[i]); l2r[i] = max(l2r[i-1], prices[i] - minn); } int maxx = prices[N-1]; for (int i = N-2; i >= 0; --i) { maxx = max(maxx, prices[i]); r2l[i] = max(r2l[i+1], maxx - prices[i]); } int res = l2r[N-1]; for (int i = 0; i < N-1; ++i) res = max(res, l2r[i] + r2l[i+1]); return res; } }; ================================================ FILE: BinarySearchTreeIterator.h ================================================ /* Author: king, wangjingui@outlook.com Date: Dec 29, 2014 Problem: Binary Search Tree Iterator Difficulty: Easy Source: https://oj.leetcode.com/problems/binary-search-tree-iterator/ Notes: Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST. Calling next() will return the next smallest number in the BST. Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree. Solution: 1. Inorder traversal use stack. 2. Morris Inorder Traversal. */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class BSTIterator_1 { public: BSTIterator(TreeNode *root) { node = root; } /** @return whether we have a next smallest number */ bool hasNext() { if (stk.empty() == true && node == NULL) return false; return true; } /** @return the next smallest number */ int next() { if (stk.empty() == true && node == NULL) return 0; while (node != NULL) { stk.push(node); node = node->left; } int res = 0; node = stk.top(); stk.pop(); res = node->val; node = node->right; return res; } private: TreeNode * node; stack stk; }; class BSTIterator_2 { public: BSTIterator(TreeNode *root) { node = root; } /** @return whether we have a next smallest number */ bool hasNext() { return node != NULL; } /** @return the next smallest number */ int next() { if (node == NULL) return 0; int res = 0; while (node != NULL) { if (node->left == NULL) { res = node->val; node = node->right; return res; } TreeNode * pre = node->left; while (pre->right != NULL && pre->right != node) pre = pre->right; if (pre->right == NULL) { pre->right = node; node = node->left; } else { res = node->val; node = node->right; pre->right = NULL; return res; } } return res; } private: TreeNode * node; }; /** * Your BSTIterator will be called like this: * BSTIterator i = BSTIterator(root); * while (i.hasNext()) cout << i.next(); */ ================================================ FILE: BinaryTreeInorderTraversal.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 22, 2013 Update: Aug 18, 2013 Problem: Binary Tree Inorder Traversal Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_94 Notes: Given a binary tree, return the inorder traversal of its nodes' values. For example: Given binary tree {1,#,2,3}, 1 \ 2 / 3 return [1,3,2]. Note: Recursive solution is trivial, could you do it iteratively? Solution: 1. Iterative way (stack). Time: O(n), Space: O(n). 2. Recursive solution. Time: O(n), Space: O(n). 3. Threaded tree (Morris). Time: O(n), Space: O(1). */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector inorderTraversal(TreeNode *root) { return inorderTraversal_1(root); } vector inorderTraversal_1(TreeNode *root) { vector res; stack stk; TreeNode *cur = root; while (cur || !stk.empty()) { if (cur) { stk.push(cur); cur = cur->left; } else if (!stk.empty()) { res.push_back(stk.top()->val); cur = stk.top()->right; stk.pop(); } } return res; } vector inorderTraversal_2(TreeNode *root) { vector res; inorderTraversalRe(root, res); return res; } void inorderTraversalRe(TreeNode *node, vector &res) { if (!node) return; inorderTraversalRe(node->left, res); res.push_back(node->val); inorderTraversalRe(node->right, res); } vector inorderTraversal_3(TreeNode *root) { vector res; TreeNode *cur = root; while (cur) { if (cur->left) { TreeNode *prev = cur->left; while (prev->right && prev->right != cur) prev = prev->right; if (prev->right == cur) { res.push_back(cur->val); cur = cur->right; prev->right = NULL; } else { prev->right = cur; cur = cur->left; } } else { res.push_back(cur->val); cur = cur->right; } } return res; } }; ================================================ FILE: BinaryTreeLevelOrderTraversal.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 6, 2013 Update: Aug 15, 2013 Problem: Binary Tree Level Order Traversal Difficulty: easy Source: http://leetcode.com/onlinejudge#question_102 Notes: Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). For example: Given binary tree {3,9,20,#,#,15,7}, 3 / \ 9 20 / \ 15 7 return its level order traversal as: [ [3], [9,20], [15,7] ] Solution: 1. Use queue. In order to seperate the levels, use 'NULL' as the end indicator of one level. 2. DFS. */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector> levelOrder(TreeNode *root) { return levelOrder_1(root); } vector > levelOrder_1(TreeNode *root) { vector > res; if (!root) return res; queue q; q.push(root); q.push(NULL); vector level; while (true) { TreeNode *node = q.front(); q.pop(); if (!node) { res.push_back(level); level.clear(); if (q.empty()) break; // end q.push(NULL); } else { level.push_back(node->val); if (node->left) q.push(node->left); if (node->right) q.push(node->right); } } return res; } vector> levelOrder_2(TreeNode *root) { vector> res; levelOrderRe(root, 0, res); return res; } void levelOrderRe(TreeNode *node, int level, vector> &res) { if (!node) return; if (res.size() <= level) res.push_back(vector()); res[level].push_back(node->val); levelOrderRe(node->left, level + 1, res); levelOrderRe(node->right, level + 1, res); } }; ================================================ FILE: BinaryTreeLevelOrderTraversalII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 7, 2013 Problem: Binary Tree Level Order Traversal II Difficulty: easy Source: http://leetcode.com/onlinejudge#question_107 Notes: Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root). For example: Given binary tree {3,9,20,#,#,15,7}, 3 / \ 9 20 / \ 15 7 return its bottom-up level order traversal as: [ [15,7] [9,20], [3], ] Solution: Queue version. On the basis of 'Binary Tree Level Order Traversal', reverse the final vector. */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector > levelOrderBottom(TreeNode *root) { vector> root2leaf; queue q; if (!root) return root2leaf; q.push(root); q.push(NULL); // end indicator of one level vector level; while (true) { TreeNode *node = q.front(); q.pop(); if (node) { level.push_back(node->val); if (node->left) q.push(node->left); if (node->right) q.push(node->right); } else { root2leaf.push_back(level); level.clear(); if (q.empty()) break; // CAUTIOUS! infinite loop q.push(NULL); } } // reverse reverse(root2leaf.begin(), root2leaf.end()); return root2leaf; } }; ================================================ FILE: BinaryTreeMaximumPathSum.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Apr 28, 2013 Update: Oct 07, 2014 Problem: Binary Tree Maximum Path Sum Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_124 Notes: Given a binary tree, find the maximum path sum. The path may start and end at any node in the tree. For example: Given the below binary tree, 1 / \ 2 3 Return 6. Solution: Recursion... */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: int maxPathSum(TreeNode *root) { int res = INT_MIN; maxPathSumRe(root, res); return res; } int maxPathSumRe(TreeNode *node, int &res) { if (!node) return 0; int l = maxPathSumRe(node->left, res); int r = maxPathSumRe(node->right, res); int sum = max(node->val, max(l, r) + node->val); res = max(res, max(0, l) + max(0, r) + node->val); return sum; } }; ================================================ FILE: BinaryTreePostorderTraversal.h ================================================ /* Author: Matthew Jin, marthew777@gmail.com Co-author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Feb 21, 2014 Update: Nov 20, 2014 Problem: Binary Tree Postorder Traversal Difficulty: Easy Source: http://oj.leetcode.com/problems/binary-tree-postorder-traversal/ Notes: Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary tree {1,#,2,3}, 1 \ 2 / 3 return [3,2,1]. Note: Recursive solution is trivial, could you do it iteratively? Solution: 1. Iterative way (stack). Time: O(n), Space: O(n). 2. Recursive solution. Time: O(n), Space: O(n). 3. Threaded tree (Morris). Time: O(n), Space: O(1). You may refer to my blog for more detailed explanations: http://www.cnblogs.com/AnnieKim/archive/2013/06/15/MorrisTraversal.html 4. Recursive solution#2. transform into preorder traversal and reverse. 5. Threaded tree (Morris). Time: O(n), Space: O(logn); */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector postorderTraversal(TreeNode *root) { return postorderTraversal_1(root); } vector postorderTraversal_1(TreeNode *root) { vector res; stack stk; TreeNode *last = NULL, *cur = root; while(cur || !stk.empty()){ if (cur) { stk.push(cur); cur = cur->left; } else{ TreeNode *peak = stk.top(); if(peak->right && last != peak->right) cur = peak->right; else{ res.push_back(peak->val); stk.pop(); last = peak; } } } return res; } vector postorderTraversal_2(TreeNode *root) { vector res; postorderTraversalRe(root, res); return res; } void postorderTraversalRe(TreeNode *node, vector &res) { if (!node) return; postorderTraversalRe(node->left, res); postorderTraversalRe(node->right, res); res.push_back(node->val); } vector postorderTraversal_3(TreeNode *root) { vector res; TreeNode dump(0); dump.left = root; TreeNode *cur = &dump, *prev = NULL; while (cur) { if (cur->left == NULL) { cur = cur->right; } else { prev = cur->left; while (prev->right != NULL && prev->right != cur) prev = prev->right; if (prev->right == NULL) { prev->right = cur; cur = cur->left; } else { printReverse(cur->left, prev, res); // call print prev->right = NULL; cur = cur->right; } } } return res; } void printReverse(TreeNode* from, TreeNode *to, vector& res) // print the reversed tree nodes 'from' -> 'to'. { reverse(from, to); TreeNode *p = to; while (true) { res.push_back(p->val); if (p == from) break; p = p->right; } reverse(to, from); } void reverse(TreeNode *from, TreeNode *to) // reverse the tree nodes 'from' -> 'to'. { if (from == to) return; TreeNode *x = from, *y = from->right, *z; while (true) { z = y->right; y->right = x; x = y; y = z; if (x == to) break; } } vector postorderTraversal_4(TreeNode *root) { vectorres; stack s; if (root == NULL) return res; dfs(root, res); reverse(res.begin(), res.end()); return res; } void dfs(TreeNode * root, vector & res) { if (root == NULL) return; res.push_back(root->val); dfs(root->right, res); dfs(root->left, res); } vector postorderTraversal_5(TreeNode *root) { vectorres; stack s; if (root == NULL) return res; TreeNode dummy(-1); dummy.left = root; TreeNode * cur = &dummy; while (cur) { if(cur->left == NULL) { cur = cur->right; } else { TreeNode * node = cur->left; while (node->right && node->right != cur) { node = node->right; } if (node->right == NULL) { node->right = cur; cur = cur->left; } else { // reverse push into res vector tmp; TreeNode * it = cur->left; while(it != node) { tmp.push_back(it->val); it = it->right; } tmp.push_back(node->val); for(vector::reverse_iterator iter = tmp.rbegin(); iter != tmp.rend(); ++iter) { res.push_back(*iter); } node->right = NULL; cur = cur->right; } } } return res; } }; ================================================ FILE: BinaryTreePreorderTraversal.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Nov 11, 2013 Problem: Binary Tree Preorder Traversal Difficulty: Easy Source: http://oj.leetcode.com/problems/binary-tree-preorder-traversal/ Notes: Given a binary tree, return the preorder traversal of its nodes' values. For example: Given binary tree {1,#,2,3}, 1 \ 2 / 3 return [1,2,3]. Note: Recursive solution is trivial, could you do it iteratively? Solution: 1. Iterative way (stack). Time: O(n), Space: O(n). 2. Recursive solution. Time: O(n), Space: O(n). 3. Threaded tree (Morris). Time: O(n), Space: O(1). */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector preorderTraversal(TreeNode *root) { return preorderTraversal_3(root); } vector preorderTraversal_1(TreeNode *root) { vector res; stack stk; TreeNode *cur = root; while (cur || !stk.empty()) { if (cur) { res.push_back(cur->val); stk.push(cur); cur = cur->left; } else if (!stk.empty()) { cur = stk.top()->right; stk.pop(); } } return res; } vector preorderTraversal_2(TreeNode *root) { vector res; preorderTraversalRe(root, res); return res; } void preorderTraversalRe(TreeNode *node, vector &res) { if (!node) return; res.push_back(node->val); preorderTraversalRe(node->left, res); preorderTraversalRe(node->right, res); } vector preorderTraversal_3(TreeNode *root) { vector res; TreeNode *cur = root; while (cur) { if (cur->left) { TreeNode *prev = cur->left; while (prev->right && prev->right != cur) prev = prev->right; if (prev->right == cur) { cur = cur->right; prev->right = NULL; } else { res.push_back(cur->val); prev->right = cur; cur = cur->left; } } else { res.push_back(cur->val); cur = cur->right; } } return res; } }; ================================================ FILE: BinaryTreeZigzagLevelOrderTraversal.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 16, 2013 Update: Sep 12, 2013 Problem: Binary Tree Zigzag Level Order Traversal Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_103 Notes: Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). For example: Given binary tree {3,9,20,#,#,15,7}, 3 / \ 9 20 / \ 15 7 return its zigzag level order traversal as: [ [3], [20,9], [15,7] ] Solution: 1. Queue + reverse. 2. Two stacks. 3. Vector. Contributed by yinlinglin. */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector> zigzagLevelOrder(TreeNode *root) { return zigzagLevelOrder_1(root); } // solution 1: Queue + Reverse. vector> zigzagLevelOrder_1(TreeNode *root) { vector> res; if (!root) return res; queue q; q.push(root); q.push(NULL); // end indicator of one level bool left2right = true; vector level; while (true) { TreeNode *node = q.front(); q.pop(); if (node) { level.push_back(node->val); if (node->left) q.push(node->left); if (node->right) q.push(node->right); } else { if (!left2right) reverse(level.begin(), level.end()); res.push_back(level); level.clear(); if (q.empty()) break; q.push(NULL); left2right = !left2right; } } return res; } // Solution 2: Two stacks. vector> zigzagLevelOrder_2(TreeNode *root) { vector> res; if (!root) return res; stack stk[2]; bool left2right = true; int cur = 1, last = 0; stk[last].push(root); vector level; while (!stk[last].empty()) { TreeNode *node = stk[last].top(); stk[last].pop(); if (node) { level.push_back(node->val); if (left2right) { stk[cur].push(node->left); stk[cur].push(node->right); } else { stk[cur].push(node->right); stk[cur].push(node->left); } } if (stk[last].empty()) { if (!level.empty()) res.push_back(level); level.clear(); swap(cur, last); left2right = !left2right; } } return res; } // Solution 3: Vector. Contributed by yinlinglin. // Compared to solution 1&2, this solution costs a little more space. // This solution uses only one single vector instead of two stacks in solution 2. vector> zigzagLevelOrder_3(TreeNode *root) { vector> result; if(!root) return result; vector v; v.push_back(root); bool left2right = true; int begin = 0, end = 0; while(begin <= end) { vector row; for (int i = end; i >= begin; --i) { if (!v[i]) continue; row.push_back(v[i]->val); if(left2right) { v.push_back(v[i]->left); v.push_back(v[i]->right); } else { v.push_back(v[i]->right); v.push_back(v[i]->left); } } if (!row.empty()) result.push_back(row); begin = end + 1; end = v.size() - 1; left2right = !left2right; } return result; } }; ================================================ FILE: Candy.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com, King, wangjingui@outlook.com Date: Oct 3, 2013 Update: Dec 12, 2014 Problem: Candy Difficulty: Easy Source: https://oj.leetcode.com/problems/candy/ Notes: There are N children standing in a line. Each child is assigned a rating value. You are giving candies to these children subjected to the following requirements: - Each child must have at least one candy. - Children with a higher rating get more candies than their neighbors. What is the minimum candies you must give? Solution: You may refer to https://github.com/AnnieKim/ITint5/blob/master/031_%E5%88%86%E9%85%8D%E7%B3%96%E6%9E%9C.cpp 1. traverse only once with O(1) space. 2. O(n) space. 3. recursion + memo. */ class Solution { public: int candy(vector &ratings) { return candy_1(ratings); } int candy_1(vector &ratings) { int N = ratings.size(); if (N == 0) return 0; int candy = 1, res = 1; int maxValue = 1, maxIndex = 0; for (int i = 1; i < N; ++i) { if (ratings[i] >= ratings[i-1]) { candy = ratings[i] == ratings[i-1] ? 1 : candy + 1; maxValue = candy; maxIndex = i; } else { if (candy == 1) { if (maxValue <= i - maxIndex) { res += i - maxIndex; maxValue++; } else { res += i - maxIndex - 1; } } candy = 1; } res += candy; } return res; } int candy_2(vector &ratings) { int N = ratings.size(); if (N == 0) return 0; int candy[N]; for (int i = 0; i < N; ++i) candy[i] = 1; for (int i = 1; i < N; ++i) if (ratings[i] > ratings[i-1]) candy[i] = candy[i-1] + 1; for (int i = N-2; i >= 0; --i) if (ratings[i] > ratings[i+1] && candy[i] <= candy[i+1]) candy[i] = candy[i+1] + 1; int res = 0; for (int i = 0; i < N; ++i) res += candy[i]; return res; } int dfs(const vector& ratings, vector& dp, int i) { if (dp[i] != -1) return dp[i]; dp[i] = 1; if(i > 0 && ratings[i] > ratings[i-1]) dp[i] = max(dp[i], dfs(ratings, dp, i-1) + 1); if(i < ratings.size()-1 && ratings[i] > ratings[i+1]) dp[i] = max(dp[i], dfs(ratings, dp, i+1) + 1); return dp[i]; } int candy_3(vector& ratings) { vector dp(ratings.size(), -1); int res = 0; for(int i = 0;i < ratings.size(); ++i) res += dfs(ratings, dp, i); return res; } }; ================================================ FILE: ClimbingStairs.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 8, 2013 Problem: Climbing Stairs Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_70 Notes: You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? Solution: Clime one step from last stair or clime 2 steps from the last last stair. */ class Solution { public: int climbStairs(int n) { int last = 1; int lastlast = 1; for (int i = 2; i <= n; i++) { int step = last + lastlast; lastlast = last; last = step; } return last; } }; ================================================ FILE: CloneGraph.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Sep 26, 2013 Problem: Clone Graph Difficulty: Easy Source: http://oj.leetcode.com/problems/clone-graph/ Notes: Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's undirected graph serialization: Nodes are labeled from 0 to N - 1, where N is the total nodes in the graph. We use # as a separator for each node, and , as a separator for each neighbor of the node. As an example, consider the serialized graph {1,2#2#2}. The graph has a total of three nodes, and therefore contains three parts as separated by #. Connect node 0 to both nodes 1 and 2. Connect node 1 to node 2. Connect node 2 to node 2 (itself), thus forming a self-cycle. Visually, the graph looks like the following: 1 / \ / \ 0 --- 2 / \ \_/ Solution: 1. DFS. 2. BFS. */ /** * Definition for undirected graph. * struct UndirectedGraphNode { * int label; * vector neighbors; * UndirectedGraphNode(int x) : label(x) {}; * }; */ class Solution { public: typedef UndirectedGraphNode GraphNode; typedef unordered_map MAP; GraphNode *cloneGraph(GraphNode *node) { return cloneGraph_1(node); } // DFS GraphNode *cloneGraph_1(GraphNode *node) { MAP map; return cloneGraphRe(node, map); } GraphNode *cloneGraphRe(GraphNode *node, MAP &map) { if (!node) return NULL; if (map.find(node) != map.end()) return map[node]; GraphNode *newNode = new GraphNode(node->label); map[node] = newNode; for (int i = 0; i < node->neighbors.size(); ++i) newNode->neighbors.push_back(cloneGraphRe(node->neighbors[i], map)); return newNode; } // BFS UndirectedGraphNode *cloneGraph_2(UndirectedGraphNode *node) { if (node == nullptr) { return nullptr; } unordered_map nodesMap; nodesMap[node] = new UndirectedGraphNode(node->label); queue q; q.push(node); while (!q.empty()) { UndirectedGraphNode* tmp = q.front(); q.pop(); for (int i = 0; i < tmp->neighbors.size(); ++i) { UndirectedGraphNode* neighbor = tmp->neighbors[i]; if (nodesMap.find(neighbor) == nodesMap.end()) { UndirectedGraphNode* newNode = new UndirectedGraphNode(neighbor->label); nodesMap[neighbor] = newNode; q.push(neighbor); } nodesMap[tmp]->neighbors.push_back(nodesMap[neighbor]); } } return nodesMap[node]; } }; ================================================ FILE: CombinationSum.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 25, 2013 Problem: Combination Sum Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_39 Notes: Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. The same repeated number may be chosen from C unlimited number of times. Note: All numbers (including target) will be positive integers. Elements in a combination (a1, a2, .. , ak) must be in non-descending order. (ie, a1 <= a2 <= ... <= ak). The solution set must not contain duplicate combinations. For example, given candidate set 2,3,6,7 and target 7, A solution set is: [7] [2, 2, 3] Solution: Sort & Recursion. */ class Solution { public: vector> combinationSum(vector &candidates, int target) { vector> res; sort(candidates.begin(), candidates.end()); vector com; combinationSumRe(candidates, target, 0, com, res); return res; } void combinationSumRe(const vector &num, int target, int start, vector &com, vector> &res) { if (target == 0) { res.push_back(com); return; } for (int i = start; i < num.size() && target >= num[i]; ++i) { com.push_back(num[i]); combinationSumRe(num, target-num[i], i, com, res); com.pop_back(); } } }; ================================================ FILE: CombinationSumII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 6, 2013 Problem: Combination Sum II Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_40 Notes: Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. Each number in C may only be used once in the combination. Note: All numbers (including target) will be positive integers. Elements in a combination (a1, a2, .. , ak) must be in non-descending order. (ie, a1 <= a2 <= ... <= ak). The solution set must not contain duplicate combinations. For example, given candidate set 10,1,2,7,6,1,5 and target 8, A solution set is: [1, 7] [1, 2, 5] [2, 6] [1, 1, 6] Solution: ..Similar to Combination Sum I, except for line 42 && 44. */ class Solution { public: vector> combinationSum2(vector &num, int target) { vector> res; sort(num.begin(), num.end()); vector com; combinationSum2Re(num, target, 0, com, res); return res; } void combinationSum2Re(const vector &num, int target, int start, vector &com, vector> &res) { if (target == 0) { res.push_back(com); return; } for (int i = start; i < num.size() && num[i] <= target; ++i) { if (i > start && num[i] == num[i-1]) continue; com.push_back(num[i]); combinationSum2Re(num, target-num[i], i+1, com, res); com.pop_back(); } } }; ================================================ FILE: Combinations.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 5, 2013 Update: Sep 28, 2013 Problem: Combinations Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_77 Notes: Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For example, If n = 4 and k = 2, a solution is: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ] Solution: DFS. */ class Solution { public: vector > combine(int n, int k) { vector > res; vector com; combineRe(n, k, 1, com, res); return res; } void combineRe(int n, int k, int start, vector &com, vector > &res){ int m = com.size(); if (m == k) { res.push_back(com); return; } for (int i = start; i <= n-(k-m)+1; ++i) { com.push_back(i); combineRe(n, k, i+1, com, res); com.pop_back(); } } }; ================================================ FILE: CompareVersionNumbers.h ================================================ /* Author: King, wangjingui@outlook.com Date: Dec 15, 2014 Problem: Compare Version Numbers Difficulty: Easy Source: https://oj.leetcode.com/problems/compare-version-numbers/ Notes: Compare two version numbers version1 and version1. If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0. You may assume that the version strings are non-empty and contain only digits and the . character. The . character does not represent a decimal point and is used to separate number sequences. For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision. Here is an example of version numbers ordering: 0.1 < 1.1 < 1.2 < 13.37 Solution: ... */ class Solution { public: int compareVersion(string version1, string version2) { int v1len = version1.size(), v2len = version2.size(); for (int i = 0, j = 0; (i < v1len || j < v2len); ) { long long a = 0, b =0; while (i < v1len && version1[i] != '.') { a = a * 10 + version1[i++] - '0'; } ++i; while (j < v2len && version2[j] != '.') { b = b * 10 + version2[j++] - '0'; } ++j; if (a > b) return 1; if (a < b) return -1; } return 0; } }; ================================================ FILE: ConstructBinaryTreefromInorderandPostorderTraversal.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 16, 2013 Problem: Construct Binary Tree from Inorder and Postorder Traversal Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_106 Notes: Given inorder and postorder traversal of a tree, construct the binary tree. Note: You may assume that duplicates do not exist in the tree. Solution: Recursion. */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: TreeNode *buildTree(vector &inorder, vector &postorder) { int N = inorder.size(); return buildTreeRe(inorder.begin(), postorder.begin(), N); } TreeNode *buildTreeRe(vector::iterator inorder, vector::iterator postorder, int N) { if (N <= 0) return NULL; vector::iterator it = find(inorder, inorder+N, *(postorder+N-1)); int pos = it - inorder; TreeNode *root = new TreeNode(*(postorder+N-1)); root->left = buildTreeRe(inorder, postorder, pos); root->right = buildTreeRe(inorder+pos+1, postorder+pos, N-pos-1); return root; } }; ================================================ FILE: ConstructBinaryTreefromPreorderandInorderTraversal.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 16, 2013 Problem: Construct Binary Tree from Preorder and Inorder Traversal Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_105 Notes: Given preorder and inorder traversal of a tree, construct the binary tree. Note: You may assume that duplicates do not exist in the tree. Solution: Recursion. */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: TreeNode *buildTree(vector &preorder, vector &inorder) { return buildTreeRe(preorder.begin(), inorder.begin(), preorder.size()); } TreeNode *buildTreeRe(vector::iterator preorder, vector::iterator inorder, int N) { if (N <= 0) return NULL; vector::iterator it = find(inorder, inorder + N, *preorder); int pos = it - inorder; TreeNode *root = new TreeNode(*preorder); root->left = buildTreeRe(preorder+1, inorder, pos); root->right = buildTreeRe(preorder+1+pos, inorder+pos+1, N-1-pos); return root; } }; ================================================ FILE: ContainerWithMostWater.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 16, 2013 Update: Aug 22, 2013 Problem: Container With Most Water Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_11 Notes: Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water. Note: You may not slant the container. Solution: From both sides to the center. */ class Solution { public: int maxArea(vector &height) { int res = 0; int l = 0, r = height.size()-1; while (l < r) { if (height[l] <= height[r]) { res = max(res, (r-l) * height[l]); l++; } else { res = max(res, (r-l) * height[r]); r--; } } return res; } }; ================================================ FILE: ConvertSortedArraytoBinarySearchTree.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 9, 2013 Problem: Convert Sorted Array to Binary Search Tree Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_108 Notes: Given an array where elements are sorted in ascending order, convert it to a height balanced BST. Solution: Recursion. */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: TreeNode *sortedArrayToBST(vector &num) { return buildBST(num, 0, num.size() - 1); } TreeNode *buildBST(vector &num, int start, int end) { if (start > end) return NULL; int mid = (start + end) / 2; TreeNode *root = new TreeNode(num[mid]); root->left = buildBST(num, start, mid - 1); root->right = buildBST(num, mid + 1, end); return root; } }; ================================================ FILE: ConvertSortedListtoBinarySearchTree.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 10, 2013 Update: Jul 29, 2013 Problem: Convert Sorted List to Binary Search Tree Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_109 Notes: Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST. Solution: 1. Recursion. Pre-order. A very good Idea. O(n) 2. Recursion, Binary Search. */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: TreeNode *sortedListToBST_1(ListNode *head) { return sortedListToBSTRe(head, getLength(head)); } TreeNode *sortedListToBSTRe(ListNode *&head, int length) { if (length == 0) return NULL; int mid = length / 2; TreeNode *left = sortedListToBSTRe(head, mid); TreeNode *root = new TreeNode(head->val); TreeNode *right = sortedListToBSTRe(head->next, length - mid - 1); root->left = left; root->right = right; head = head->next; return root; } int getLength(ListNode *head) { int length = 0; while (head) { length++; head = head->next; } return length; } TreeNode *sortedListToBST_2(ListNode *head) { if(head==nullptr) return nullptr; if(head->next==nullptr) return new TreeNode(head->val); ListNode * slow = head; ListNode * fast = head; ListNode * pre = nullptr; while(fast->next&&fast->next->next){ pre = slow; slow = slow->next; fast = fast->next->next; } fast = slow->next; TreeNode * node = new TreeNode(slow->val); if(pre){ pre->next = nullptr; node->left = sortedListToBST(head); } node->right = sortedListToBST(fast); return node; } }; ================================================ FILE: CopyListwithRandomPointer.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Oct 5, 2013 Problem: Copy List with Random Pointer Difficulty: Easy Source: http://oj.leetcode.com/problems/copy-list-with-random-pointer/ Notes: A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. Return a deep copy of the list. Solution: Solution 1 uses constant extra space. */ /** * Definition for singly-linked list with a random pointer. * struct RandomListNode { * int label; * RandomListNode *next, *random; * RandomListNode(int x) : label(x), next(NULL), random(NULL) {} * }; */ class Solution { typedef unordered_map nodemap; public: RandomListNode *copyRandomList(RandomListNode *head) { return copyRandomList_1(head); } RandomListNode *copyRandomList_1(RandomListNode *head) { for (RandomListNode *cur = head; cur; cur = cur->next->next) { RandomListNode *newNode = new RandomListNode(cur->label); newNode->next = cur->next; cur->next = newNode; } for (RandomListNode *cur = head; cur; cur = cur->next->next) if (cur->random) cur->next->random = cur->random->next; RandomListNode dummy(0), *curNew = &dummy; for (RandomListNode *cur = head; cur; cur = cur->next) { curNew->next = cur->next; curNew = curNew->next; cur->next = cur->next->next; } return dummy.next; } RandomListNode *copyRandomList_2(RandomListNode *head) { if (!head) return NULL; unordered_map map; RandomListNode dummy(0), *curNew = &dummy, *cur = head; while (cur) { if (map.find(cur) == map.end()) map[cur] = new RandomListNode(cur->label); if (cur->random && map.find(cur->random) == map.end()) map[cur->random] = new RandomListNode(cur->random->label); curNew->next = map[cur]; curNew = curNew->next; curNew->random = map[cur->random]; cur = cur->next; } return dummy.next; } RandomListNode *copyRandomList_3(RandomListNode *head) { nodemap m; return copy(head, m); } RandomListNode *copy(RandomListNode *root, nodemap &m) { if (root == nullptr) return nullptr; nodemap::iterator iter = m.find(root); if (iter != m.end()) { return m[root]; } RandomListNode *node = new RandomListNode(root->label); m[root] = node; node->next = copy(root->next, m); node->random = copy(root->random, m); return node; } }; ================================================ FILE: CountandSay.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 8, 2013 Update: Aug 10, 2013 Problem: Count and Say Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_38 Notes: The count-and-say sequence is the sequence of integers beginning as follows: 1, 11, 21, 1211, 111221, ... 1 is read off as "one 1" or 11. 11 is read off as "two 1s" or 21. 21 is read off as "one 2, then one 1" or 1211. Given an integer n, generate the nth sequence. Note: The sequence of integers will be represented as a string. Solution: ... */ class Solution { public: string countAndSay(int n) { string res = "1"; for (int i = 2; i <= n; ++i) { stringstream ss; int j = 0, N = res.size(); while (j < N) { int k = j + 1; while (k < N && res[k] == res[j]) k++; ss << (k - j) << res[j]; j = k; } ss >> res; } return res; } }; ================================================ FILE: DecodeWays.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 20, 2013 Problem: Decode Ways Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_91 Notes: A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 Given an encoded message containing digits, determine the total number of ways to decode it. For example, Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12). The number of ways decoding "12" is 2. Solution: 1. dp. Note that '0' must be decoded in together with the number in front of it. 2. dp. Time : O(n); Space : O(1). */ class Solution { public: int numDecodings_1(string s) { if (s.empty() || s[0] == '0') return 0; int N = s.size(); int dp[N+1]; dp[0] = 1; dp[1] = 1; for (int i = 1; i < N; ++i) { if (s[i] == '0') { if (s[i-1] != '1' && s[i-1] != '2') return 0; dp[i+1] = dp[i-1]; } else { int num = s[i] - '0' + (s[i-1] - '0') * 10; if (num >= 11 && num <= 26) dp[i+1] = dp[i] + dp[i-1]; else dp[i+1] = dp[i]; } } return dp[N]; } int numDecodings_2(string s) { if (s.empty() || s[0] == '0') return 0; int N = s.size(); int f0 = 1, f1 = 1; for (int i = 1; i < N; ++i) { if (s[i] == '0') f1 = 0; int num = s[i] - '0' + (s[i-1] - '0') * 10; if (num < 10 || num > 26) { f0 = 0; } int tmp = f1; f1 = f1 + f0; f0 = tmp; } return f1; } }; ================================================ FILE: DistinctSubsequences.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: May 16, 2013 Update: Oct 07, 2014 Problem: Distinct Subsequences Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_115 Notes: Given a string S and a string T, count the number of distinct subsequences of T in S. A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not). Here is an example: S = "rabbbit", T = "rabbit" Return 3. Solution: dp. */ class Solution { public: int numDistinct(string S, string T) { return numDistinct_2(S, T); } int numDistinct_1(string S, string T) { int M = S.size(); int N = T.size(); vector > dp(M+1, vector(N+1)); for (int j = 0; j <= N; ++j) { dp[0][j] = 0; } for (int i = 0; i <= M; ++i) { dp[i][0] = 1; } for (int i = 1; i <= M; ++i) { for (int j = 1; j <= N; ++j) { dp[i][j] = dp[i-1][j] + (S[i-1] == T[j-1] ? dp[i-1][j-1] : 0); } } return dp[M][N]; } int numDistinct_2(string S, string T) { int M = S.size(); int N = T.size(); vector dp(N + 1); dp[0] = 1; for (int i = 1; i <= M; ++i) { for (int j = N; j >=1; --j) { dp[j] = dp[j] + (S[i-1] == T[j-1] ? dp[j-1] : 0); } } return dp[N]; } }; ================================================ FILE: DivideTwoIntegers.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Jul 8, 2013 Update: Nov 18, 2014 Problem: Divide Two Integers Difficulty: Medium Source: https://oj.leetcode.com/problems/divide-two-integers/ Notes: Divide two integers without using multiplication, division and mod operator. Solution: Use << operator. */ class Solution { public: //Top -> Down int divide_1(int dividend, int divisor) { assert(divisor != 0); bool flag = (dividend < 0) ^ (divisor < 0); long long dividendll = abs((long long)dividend); long long divisorll = abs((long long)divisor); long long res = 0; long long d = divisorll, q = 1; while ((d << 1) <= dividendll) { d <<= 1; q <<= 1; } while (dividendll >= divisorll) { if (dividendll >= d) { dividendll -= d; res += q; } d >>= 1; q >>= 1; } if (flag == true) res = -res; if (res > INT_MAX) return INT_MAX; return res; } //bottom -> up int divide(int dividend, int divisor) { assert(divisor != 0); bool flag = (dividend < 0) ^ (divisor < 0); long long Dividend = abs((long long)dividend); long long Divisor = abs((long long)divisor); long long res = 0; while (Dividend >= Divisor) { long long c = Divisor; for (int i = 0; (c << i) <= Dividend; ++i) { Dividend -= (c << i); res += (1 << i); } } if (flag == true) res = -res; if (res > INT_MAX) return INT_MAX; return res; } }; ================================================ FILE: DungeonGame.h ================================================ /* Author: King, wangjingui@outlook.com Date: Jan 6, 2015 Problem: Dungeon Game Difficulty: Easy Source: https://oj.leetcode.com/problems/dungeon-game/ Notes: The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. The dungeon consists of M x N rooms laid out in a 2D grid. Our valiant knight (K) was initially positioned in the top-left room and must fight his way through the dungeon to rescue the princess. The knight has an initial health point represented by a positive integer. If at any point his health point drops to 0 or below, he dies immediately. Some of the rooms are guarded by demons, so the knight loses health (negative integers) upon entering these rooms; other rooms are either empty (0's) or contain magic orbs that increase the knight's health (positive integers). In order to reach the princess as quickly as possible, the knight decides to move only rightward or downward in each step. Write a function to determine the knight's minimum initial health so that he is able to rescue the princess. For example, given the dungeon below, the initial health of the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN. -2 (K) -3 3 -5 -10 1 10 30 -5 (P) Notes: The knight's health has no upper bound. Any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned. Solution: Fortunately, this problem can be solved through a table-filling Dynamic Programming technique, similar to other "grid walking" problems: To begin with, we should maintain a 2D array D of the same size as the dungeon, where D[i][j] represents the minimum health that guarantees the survival of the knight for the rest of his quest BEFORE entering room(i, j). Obviously D[0][0] is the final answer we are after. Hence, for this problem, we need to fill the table from the bottom right corner to left top. Then, let us decide what the health should be at least when leaving room (i, j). There are only two paths to choose from at this point: (i+1, j) and (i, j+1). Of course we will choose the room that has the smaller D value, or in other words, the knight can finish the rest of his journey with a smaller initial health. Therefore we have: min_HP_on_exit = min(D[i+1][j], D[i][j+1]) Now D[i][j] can be computed from dungeon[i][j] and min_HP_on_exit based on one of the following situations: If dungeon[i][j] == 0, then nothing happens in this room; the knight can leave the room with the same health he enters the room with, i.e. D[i][j] = min_HP_on_exit. If dungeon[i][j] < 0, then the knight must have a health greater than min_HP_on_exit before entering (i, j) in order to compensate for the health lost in this room. The minimum amount of compensation is "-dungeon[i][j]", so we have D[i][j] = min_HP_on_exit - dungeon[i][j]. If dungeon[i][j] > 0, then the knight could enter (i, j) with a health as little as min_HP_on_exit - dungeon[i][j], since he could gain "dungeon[i][j]" health in this room. However, the value of min_HP_on_exit - dungeon[i][j] might drop to 0 or below in this situation. When this happens, we must clip the value to 1 in order to make sure D[i][j] stays positive: D[i][j] = max(min_HP_on_exit - dungeon[i][j], 1). Notice that the equation for dungeon[i][j] > 0 actually covers the other two situations. We can thus describe all three situations with one common equation, i.e.: D[i][j] = max(min_HP_on_exit - dungeon[i][j], 1) for any value of dungeon[i][j]. Take D[0][0] and we are good to go. Also, like many other "table-filling" problems, the 2D array D can be replaced with a 1D "rolling" array here. */ class Solution { public: int calculateMinimumHP(vector > &dungeon) { int M = dungeon.size(), res = 0; if (M == 0) return res; int N = dungeon[0].size(); vector> dp(M, vector(N,0)); dp[M-1][N-1] = 1 - min(0, dungeon[M-1][N-1]); for (int i = M - 2; i >= 0; --i) { if (dp[i+1][N-1] - dungeon[i][N-1] <= 0) dp[i][N-1] = 1; else dp[i][N-1] = dp[i+1][N-1] - dungeon[i][N-1]; } for (int j = N - 2; j >= 0; --j) { if (dp[M-1][j+1] - dungeon[M-1][j] <= 0) dp[M-1][j] = 1; else dp[M-1][j] = dp[M-1][j+1] - dungeon[M-1][j]; } for (int i = M - 2; i >= 0; --i) { for (int j = N - 2; j >= 0; --j) { int val = min(dp[i+1][j], dp[i][j+1]); if (dungeon[i][j] >= val) dp[i][j] = 1; else dp[i][j] = val - dungeon[i][j]; } } return max(1,dp[0][0]); } }; ================================================ FILE: EditDistance.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 7, 2013 Update: Sep 28, 2013 Problem: Edit Distance Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_72 Notes: Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.) You have the following 3 operations permitted on a word: a) Insert a character b) Delete a character c) Replace a character Solution: Dynamic Programming. 1. Time: O(mn) Space: O(mn) 2. Time: O(mn) Space: O(n); */ class Solution { public: int minDistance(string word1, string word2) { return minDistance_2(word1, word2); } int minDistance_1(string word1, string word2) { int M = word1.size(), N = word2.size(); int dp[N+1][M+1]; for (int j = 0; j <= M; j++) dp[0][j] = j; for (int i = 0; i <= N; i++) dp[i][0] = i; for (int i = 1; i <= N; i++) for (int j = 1; j <= M; j++) if (word2[i-1] == word1[j-1]) dp[i][j] = dp[i-1][j-1]; else dp[i][j] = min(dp[i-1][j-1], min(dp[i][j-1], dp[i-1][j])) + 1; return dp[N][M]; } int minDistance_2(string word1, string word2) { int M = word1.size(), N = word2.size(); int dp[N+1]; for (int j = 0; j <= N; ++j) dp[j] = j; for (int i = 1; i <= M; ++i) { int upperLeftBackup = dp[0]; dp[0] = i; for (int j = 1; j <= N; ++j) { int upperLeft = upperLeftBackup; upperLeftBackup = dp[j]; if (word1[i-1] == word2[j-1]) dp[j] = upperLeft; else dp[j] = min(min(dp[j-1], dp[j]), upperLeft) + 1; } } return dp[N]; } }; ================================================ FILE: EvaluateReversePolishNotation.h ================================================ /* Author: Matthew Jin, marthew777@gmail.com Date: Problem: Evaluate Reverse Polish Notation Difficulty: Easy Notes: Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, *, /. Each operand may be an integer or another expression. Some examples: ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9 ["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6 Solution: stack. */ class Solution { public: int evalRPN(vector &tokens) { stack s; for (int i = 0; i < tokens.size(); ++i) { if (tokens[i] != "+" && tokens[i] != "-" && tokens[i] != "*" && tokens[i] != "/") s.push(stoi(tokens[i])); else { int op2 = s.top();s.pop(); int op1 = s.top();s.pop(); int result = 0; if(tokens[i] == "+") result = op1 + op2; else if(tokens[i] == "-") result = op1 - op2; else if(tokens[i] == "*") result = op1 * op2; else if(tokens[i] == "/") result = op1 / op2; s.push(result); } } return s.top(); } }; ================================================ FILE: ExcelSheetColumnNumber.h ================================================ /* Author: King, wangjingui@outlook.com Date: Dec 28, 2014 Problem: Excel Sheet Column Number Difficulty: Medium Source: https://oj.leetcode.com/problems/excel-sheet-column-number/ Notes: Related to question Excel Sheet Column Title Given a column title as appear in an Excel sheet, return its corresponding column number. For example: A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -> 27 AB -> 28 Solution: 1. ... */ class Solution { public: int titleToNumber(string s) { int res = 0; if (s.length() == 0) return 0; for (int i = 0; i < s.length(); ++i) { res = res * 26 + s[i] - 'A' + 1; } return res; } }; ================================================ FILE: ExcelSheetColumnTitle.h ================================================ /* Author: King, wangjingui@outlook.com Date: Dec 19, 2014 Problem: Excel Sheet Column Title Difficulty: Easy Source: https://oj.leetcode.com/problems/excel-sheet-column-title/ Notes: Given a non-zero positive integer, return its corresponding column title as appear in an Excel sheet. For example: 1 -> A 2 -> B 3 -> C ... 26 -> Z 27 -> AA 28 -> AB Solution: 1. Iteration. 2&3. recursion. */ class Solution { public: string convertToTitle_1(int n) { string res; while (n){ res.push_back((n - 1)%26 + 'A'); n = (n - 1) / 26; } reverse(res.begin(), res.end()); return res; } void convertToTitleRe(int n, string &res) { if (n == 0) return; convertToTitleRe((n-1)/26, res); res.push_back((n-1)%26 + 'A'); } string convertToTitle_2(int n) { string res; convertToTitleRe(n, res); return res; } void convertToTitleRe3(int n, string &res) { if (n == 0) return; res.push_back((n-1)%26 + 'A'); convertToTitleRe3((n-1)/26, res); } string convertToTitle(int n) { string res; convertToTitleRe3(n, res); reverse(res.begin(), res.end()); return res; } }; ================================================ FILE: FactorialTrailingZeroes.cpp ================================================ /* Author: King, wangjingui@outlook.com Date: Dec 13, 2014 Problem: Factorial Trailing Zeroes Difficulty: Easy Source: https://oj.leetcode.com/problems/factorial-trailing-zeroes/ Notes: Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in logarithmic time complexity. Solution: ... */ class Solution { public: int trailingZeroes(int n) { int res = 0; while (n) { res += n / 5; n /= 5; } return res; } }; ================================================ FILE: FindMinimumInRotatedSortedArray.h ================================================ /* Author: King, higuige@gmail.com Date: Oct 22, 2014 Problem: Find Minimum in Rotated Sorted Array Difficulty: Medium Source: https://oj.leetcode.com/problems/find-minimum-in-rotated-sorted-array/ Notes: Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). Find the minimum element. You may assume no duplicate exists in the array. */ class Solution { public: int findMin(vector &num) { if(num.empty()) return 0; int size = num.size(); int left = 0; int right = size - 1; while (left < right && num[left] >= num[right]) { int mid = (left + right) / 2; if (num[mid] > num[right]) { left = mid + 1; } else { right = mid; } } return num[left]; } }; ================================================ FILE: FindMinimumInRotatedSortedArrayII.h ================================================ /* Author: King, higuige@gmail.com Date: Oct 22, 2014 Problem: Find Minimum in Rotated Sorted ArrayII Difficulty: Hard Source: https://oj.leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/ Notes: Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). Find the minimum element. The array may contain duplicates. */ class Solution { public: int findMin(vector &num) { if(num.empty()) return 0; int size = num.size(); int left = 0; int right = size - 1; while (left < right && num[left] >= num[right]) { int mid = (left + right) / 2; if (num[mid] > num[right]) { left = mid + 1; } else if (num[mid] < num[left]) { right = mid; } else { ++left; } } return num[left]; } }; ================================================ FILE: FindPeakElement.h ================================================ /* Author: King, wangjingui@outlook.com Date: Dec 06, 2014 Problem: Find Peak Element Difficulty: Medium Source: https://oj.leetcode.com/problems/find-peak-element/ Notes: A peak element is an element that is greater than its neighbors. Given an input array where num[i] ≠ num[i+1], find a peak element and return its index. You may imagine that num[-1] = num[n] = -∞. For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2. Find the peak element. */ class Solution { public: int findPeakElement(const vector &num) { int n = num.size(); int left = 0, right = n - 1,mid = -1; while (left <= right) { mid = (left + right) / 2; if ((mid == 0 || num[mid-1] <= num[mid]) && (mid == n -1 || num[mid+1] <= num[mid])) return mid; if (mid > 0 && num[mid - 1] > num[mid]) { right = mid - 1; } else if (num[mid + 1] > num[mid]) { left = mid + 1; } } return mid; } }; ================================================ FILE: FirstMissingPositive.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 21, 2013 Problem: First Missing Positive Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_41 Notes: Given an unsorted integer array, find the first missing positive integer. For example, Given [1,2,0] return 3, and [3,4,-1,1] return 2. Your algorithm should run in O(n) time and uses constant space. Solution: Although we can only use constant space, we can still exchange elements within input A! Swap elements in A and try to make all the elements in A satisfy: A[i] == i + 1. Pick out the first one that does not satisfy A[i] == i + 1. */ class Solution { public: int firstMissingPositive(int A[], int n) { int i = 0; while (i < n) { if (A[i] != (i+1) && A[i] >= 1 && A[i] <= n && A[A[i]-1] != A[i]) swap(A[i], A[A[i]-1]); else i++; } for (i = 0; i < n; ++i) if (A[i] != (i+1)) return i+1; return n+1; } }; ================================================ FILE: FlattenBinaryTreetoLinkedList.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Apr 28, 2013 Update: Oct 7, 2014 Problem: Flatten Binary Tree to Linked List Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_114 Notes: Given a binary tree, flatten it to a linked list in-place. For example, Given 1 / \ 2 5 / \ \ 3 4 6 The flattened tree should look like: 1 \ 2 \ 3 \ 4 \ 5 \ 6 Hints: If you notice carefully in the flattened tree, each node's right child points to the next node of a pre-order traversal. Solution: Recursion. Return the last element of the flattened sub-tree. */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: void flatten(TreeNode *root) { flatten_3(root); } void flatten_1(TreeNode *root) { if (root == NULL) return; flatten_1(root->left); flatten_2(root->right); if (root->left == NULL) return; TreeNode *p = root->left; while (p->right) p = p->right; p->right = root->right; root->right = root->left; root->left = NULL; } TreeNode * dfs (TreeNode * root, TreeNode * tail){ if(root == NULL) return tail; root->right = dfs(root->left,dfs(root->right,tail)); root->left = NULL; return root; } void flatten_2(TreeNode *root) { if(root == NULL) return; dfs(root, NULL); } void flatten_3(TreeNode *root) { if(root==nullptr) return; stack s; s.push(root); while(!s.empty()){ auto p=s.top(); s.pop(); if(p->right) s.push(p->right); if(p->left) s.push(p->left); p->left = nullptr; if(!s.empty()){ p->right=s.top(); }else p->right = nullptr; } } void flatten_4(TreeNode *root) { TreeNode *end = NULL; flattenRe(root, end); } void flattenRe(TreeNode *node, TreeNode *&end) { if (!node) return; TreeNode *lend = NULL, *rend = NULL; flattenRe(node->left, lend); flattenRe(node->right, rend); if (node->left) { lend->right = node->right; node->right = node->left; node->left = NULL; } end = rend ? rend : (lend ? lend : node); } }; ================================================ FILE: FractionToRecurringDecimal.h ================================================ /* Author: King, wangjingui@outlook.com Date: Dec 15, 2014 Problem: Fraction to Recurring Decimal Difficulty: Easy Source: https://oj.leetcode.com/problems/fraction-to-recurring-decimal/ Notes: Given two integers representing the numerator and denominator of a fraction, return the fraction in string format. If the fractional part is repeating, enclose the repeating part in parentheses. For example, Given numerator = 1, denominator = 2, return "0.5". Given numerator = 2, denominator = 1, return "2". Given numerator = 2, denominator = 3, return "0.(6)". Solution: ... */ class Solution { public: string fractionToDecimal(int numerator, int denominator) { if (numerator == 0) return string("0"); bool flag = (numerator < 0)^(denominator < 0); long long Numerator = abs((long long)numerator); long long Denominator = abs((long long)denominator); string res; if (flag == true) res.push_back('-'); ostringstream out; out << (Numerator / Denominator); res.insert(res.size(),out.str()); Numerator = Numerator % Denominator; if (Numerator == 0) return res; res.push_back('.'); unordered_map map; for (int i = res.size(); Numerator != 0; ++i) { if (map.find(Numerator) != map.end()) break; map[Numerator] = i; Numerator *= 10; res.push_back((Numerator / Denominator) + '0'); Numerator %= Denominator; } if (Numerator == 0) return res; res.insert(map[Numerator],"("); res.push_back(')'); return res; } }; ================================================ FILE: GasStation.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Oct 3, 2013 Problem: Gas Station Difficulty: Easy Source: http://oj.leetcode.com/problems/gas-station/ Notes: There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. 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). You begin the journey with an empty tank at one of the gas stations. Return the starting gas station's index if you can travel around the circuit once, otherwise return -1. The solution is guaranteed to be unique. Solution: ... */ class Solution { public: int canCompleteCircuit(vector &gas, vector &cost) { int N = gas.size(); int res = 0, min = gas[0] - cost[0], sum = min; for (int i = 1; i < N; ++i) { sum += gas[i] - cost[i]; if (sum < min) { min = sum; res = i; } } return sum >= 0 ? (res + 1) % N : -1; } }; ================================================ FILE: GenerateParentheses.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 17, 2013 Update: Jul 20, 2013 Problem: Generate Parentheses Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_22 Notes: Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. For example, given n = 3, a solution set is: "((()))", "(()())", "(())()", "()(())", "()()()" Solution: Place n left '(' and n right ')'. Cannot place ')' if there are no enough matching '('. */ class Solution { public: vector generateParenthesis(int n) { vector res; generateParenthesisRe(res, n, n, ""); return res; } void generateParenthesisRe(vector &res, int left, int right, string s) { if (left == 0 && right == 0) res.push_back(s); if (left > 0) generateParenthesisRe(left - 1, right, s + "("); if (right > left) generateParenthesisRe(left, right - 1, s + ")"); } }; ================================================ FILE: GrayCode.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 16, 2013 Problem: Gray Code Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_89 Notes: The gray code is a binary numeral system where two successive values differ in only one bit. Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0. For example, given n = 2, return [0,1,3,2]. Its gray code sequence is: 00 - 0 01 - 1 11 - 3 10 - 2 Note: For a given n, a gray code sequence is not uniquely defined. For example, [0,2,3,1] is also a valid gray code sequence according to the above definition. For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that. Solution: Refer to http://en.wikipedia.org/wiki/Gray_code. */ class Solution { public: vector grayCode(int n) { vector result(1 << n, 0); for (int i = 0; i < 1 << n; ++i) result[i] = (i >> 1) ^ i; return result; } }; ================================================ FILE: ImplementstrStr().h ================================================ /* Author: King, wangjingui@outlook.com Date: Dec 17, 2014 Problem: Implement strStr() Difficulty: Easy Source: https://oj.leetcode.com/problems/implement-strstr/ Notes: Implement strStr(). Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack. Solution: 1. Check in the haystack one by one. If not equal to needle, reset the pointer.(TLE) 2. Classice KMP solution. 3. Simplified RK Soluiton. Thanks for [wenyuanhust, wenyuanhust@gmail.com] */ class Solution { public: int strStr_1(char *haystack, char *needle) { int sLen = strlen(haystack); const int tLen = strlen(needle); if (tLen == 0) return 0; if(haystack==NULL || needle==NULL || sLen==0) return -1; int i = 0, j =0; while (i < sLen) { j = 0; int k = i; while (j < tLen && haystack[k] == needle[j]) { ++k, ++j; } if (j == tLen) return k - j; ++i; } return -1; } void getNext(char * T, int next[], int n){ int i=0, j=-1; next[0]=-1; while(i-1&&T[j]!=T[i]) j = next[j]; i++,j++; if(T[j]==T[i]) next[i]=next[j]; else next[i]=j; } } int strStr_2(char *haystack, char *needle) { int sLen = strlen(haystack); const int tLen = strlen(needle); if (tLen == 0) return 0; if(haystack==NULL || needle==NULL || sLen==0) return -1; int next[tLen+1]; getNext(needle,next,tLen); int i=0, j=0; while(i-1&&needle[j]!=haystack[i]) j = next[j]; i++,j++; if(j==tLen){ return i - j; } } return -1; } int strStr_3(char *haystack, char *needle) { if (needle && *needle == '\0') return 0; if (haystack == NULL || needle == NULL || *haystack == '\0') return -1; long long fh = 0, fn = 0; char *n = needle, *tail = haystack, *head = haystack; while (*n) { if (*tail == '0') return -1; fh += *tail; fn += *n; ++n, ++tail; } --tail; while (*tail) { if (fn == fh) { char *pTemp = head,*nTemp = needle; while (*nTemp && *nTemp == *pTemp) { ++nTemp; ++pTemp; } if (*nTemp == '\0') return head - haystack; } fh -= *head; ++tail; ++head; fh += *tail; } return -1; } }; ================================================ FILE: InsertInterval.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, wangjingui@outlook.com Date: Jun 7, 2013 Update: Dec 14, 2014 Problem: Insert Interval Difficulty: Medium Source: https://oj.leetcode.com/problems/insert-interval/ Notes: Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). You may assume that the intervals were initially sorted according to their start times. Example 1: Given intervals [1,3],[6,9], insert and merge [2,5] in as [1,5],[6,9]. Example 2: Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as [1,2],[3,10],[12,16]. This is because the new interval [4,9] overlaps with [3,5],[6,7],[8,10]. Solution: For example 2: 1. compare [1,2] with [4,9], then insert [1,2]; 2. merge [3,5] with [4,9], get newInterval = [3,9]; 3. merge [6,7] with [3,9], get newInterval = [3,9]; 4. merge [8,10] with [3,9], get newInterval = [3,10]; 5. compare [12,16] with [3,10], insert newInterval [3,10], then all the remaining intervals... Solution 1 : Time O(N). Solution 2 : Time O(Log(N)). */ /** * Definition for an interval. * struct Interval { * int start; * int end; * Interval() : start(0), end(0) {} * Interval(int s, int e) : start(s), end(e) {} * }; */ class Solution { public: vector insert_1(vector &intervals, Interval newInterval) { vector res; vector::iterator it = intervals.begin(); bool inserted = false; for (; it != intervals.end(); ++it) { if (inserted == true || it->end < newInterval.start) // non-overlaping { res.push_back(*it); } else if (newInterval.end < it->start) { res.push_back(newInterval); res.push_back(*it); inserted = true; } else { newInterval.start = min(it->start, newInterval.start); newInterval.end = max(it->end, newInterval.end); } } if (inserted == false) res.push_back(newInterval); return res; } vector insert_2(vector &intervals, Interval newInterval) { vector res; int n = intervals.size(); int left = 0, right = n-1; while(left<=right){ int mid = (left+right)/2; if(intervals[mid].start>newInterval.start) right=mid-1; else left = mid+1; } int idxStart = right; left = 0; right = n-1; while(left<=right){ int mid = (left+right)/2; if(intervals[mid].end>=newInterval.end) right = mid -1; else left = mid+1; } int idxEnd = left; if (idxStart>=0 && newInterval.start<=intervals[idxStart].end) { newInterval.start=intervals[idxStart--].start; } if (idxEnd=intervals[idxEnd].start) { newInterval.end=intervals[idxEnd++].end; } for(int i=0;i<=idxStart;i++) res.push_back(intervals[i]); res.push_back(newInterval); for(int i=idxEnd;inext) { if (cur->next->val >= cur->val) cur = cur->next; else insert(&dummy, cur, cur->next); } return dummy.next; } void insert(ListNode *head, ListNode *tail, ListNode *node) { ListNode *cur = head; while (cur->next->val < node->val) cur = cur->next; tail->next = node->next; node->next = cur->next; cur->next = node; } }; ================================================ FILE: IntegertoRoman.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 13, 2013 Problem: Integer to Roman Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_12 Notes: Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999. Solution: Buffer the roman numbers. */ class Solution { public: const string rom[4][10] = {{"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"}, {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"}, {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"}, {"", "M", "MM", "MMM"}}; string intToRoman_1(int num) { string res; int i = 3; while (num > 0) { int divisor = (int)pow(10, i); res += rom[i][num / divisor]; num %= divisor; i--; } return res; } string intToRoman_2(int num) { int values[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 }; string numerals[] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" }; string res; for (int i = 0; i < 13; ++i) { while (num >= values[i]) { num -= values[i]; res += numerals[i]; } } return res; } }; ================================================ FILE: InterleavingString.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 6, 2013 Problem: Interleaving String Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_97 Notes: Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. For example, Given: s1 = "aabcc", s2 = "dbbca", When s3 = "aadbbcbcac", return true. When s3 = "aadbbbaccc", return false. Solution: 1. dp. O(MN) time & space. 'dp[i][j] == true' means that there is at least one way to construct the string s3[0...i+j-1] by interleaving s1[0...j-1] and s2[0...i-1]. 2. Recursion. Okay for Small but TLE for Large Test data. */ class Solution { public: bool isInterleave(string s1, string s2, string s3) { return isInterleave_1(s1, s2, s3); } bool isInterleave_1(string s1, string s2, string s3) { int M = s1.size(), N = s2.size(), K = s3.size(); if (M + N != K) return false; bool dp[N+1][M+1]; dp[0][0] = true; for (int i = 1; i <= N; ++i) dp[i][0] = dp[i-1][0] && s2[i-1] == s3[i-1]; for (int j = 1; j <= M; ++j) dp[0][j] = dp[0][j-1] && s1[j-1] == s3[j-1]; for (int i = 1; i <= N; ++i) for (int j = 1; j <= M; ++j) dp[i][j] = dp[i-1][j] && s2[i-1] == s3[i+j-1] || dp[i][j-1] && s1[j-1] == s3[i+j-1]; return dp[N][M]; } bool isInterleave_2(string s1, string s2, string s3) { return isInterleaveRe(s1.c_str(), s2.c_str(), s3.c_str()); } bool isInterleaveRe(const char *s1, const char *s2, const char *s3) { if (*s1 == '\0' && *s2 == '\0' && *s3 == '\0') return true; if (*s3 == '\0') return false; if (*s1 == '\0') return strcmp(s2, s3) == 0; if (*s2 == '\0') return strcmp(s1, s3) == 0; return *s1 == *s3 && isInterleaveRe(s1+1, s2, s3+1) || *s2 == *s3 && isInterleaveRe(s1, s2+1, s3+1); } }; ================================================ FILE: IntersectionOfTwoLinkedLists.h ================================================ /* Author: King, wangjingui@outlook.com Date: Nov 28, 2014 Problem: Intersection of Two Linked Lists Difficulty: Easy Source: https://oj.leetcode.com/problems/intersection-of-two-linked-lists/ Notes: Write a program to find the node at which the intersection of two singly linked lists begins. Hints: If the two linked lists have no intersection at all, return null. The linked lists must retain their original structure after the function returns. You may assume there are no cycles anywhere in the entire linked structure. Your code should preferably run in O(n) time and use only O(1) memory. Solution: Two iteration. */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { ListNode * cur = NULL; int lenA = 0, lenB = 0; cur = headA; while (cur) { ++lenA; cur = cur->next; } cur = headB; while (cur) { ++lenB; cur = cur->next; } if (lenA >= lenB) { int diff = lenA - lenB; while (diff > 0) { headA = headA->next; --diff; } while (headA && headB) { if(headA == headB) { return headA; } headA = headA->next; headB = headB->next; } } else { int diff = lenB - lenA; while (diff > 0) { headB = headB->next; --diff; } while (headA && headB) { if(headA == headB) { return headA; } headA = headA->next; headB = headB->next; } } return NULL; } }; ================================================ FILE: JumpGame.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 21, 2013 Update: Jul 12, 2013 Problem: Jump Game Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_55 Notes: Given an array of non-negative integers, you are initially positioned at the first index of the array. Each element in the array represents your maximum jump length at that position. Determine if you are able to reach the last index. For example: A = [2,3,1,1,4], return true. A = [3,2,1,0,4], return false. Solution: Updated solution: try every reachable index. Thank to Wenxin Xing for kindly feedback and pointing out my big mistake:) */ class Solution { public: bool canJump(int A[], int n) { int start = 0, end = 0; while (start <= end && end < n-1) { end = max(end, start + A[start]); start++; } return end >= (n-1); } }; ================================================ FILE: JumpGameII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 21, 2013 Update: Dec 22, 2014 Problem: Jump Game II Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_45 Notes: Given an array of non-negative integers, you are initially positioned at the first index of the array. Each element in the array represents your maximum jump length at that position. Your goal is to reach the last index in the minimum number of jumps. For example: Given array A = [2,3,1,1,4] 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.) Solution: Jump to the position where we can jump farthest (index + A[index]) next time. */ class Solution { public: int jump_1(int A[], int n) { int start = 0; int res = 0; while (start < n-1) { res++; if (start + A[start] >= n-1) return res; int mx = start; for (int i = start + 1; i <= start + A[start]; ++i) if (i + A[i] >= mx + A[mx]) mx = i; start = mx; } } int jump_2(int A[], int n) { if(n==1) return 0; int res = 0; int last = 0; int cur = 0; for(int i=0;ilast){ last = cur; ++res; if (cur >= n - 1) break; } cur = max(cur,i+A[i]); } return res; } }; ================================================ FILE: LRUCache.h ================================================ /* Author: Matthew Jin, marthew777@gmail.com Date: March 12, 2014 Problem: LRU Cache Difficulty: Easy Source: http://oj.leetcode.com/problems/lru-cache/ Notes: Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set. get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item. Solution: Hash + list. */ struct CacheNode{ int key; int value; CacheNode(int k, int v) : key(k), value(v) {} }; class LRUCache{ public: LRUCache(int capacity) : size(capacity) { } int get(int key){ if (cachemap.find(key) != cachemap.end()) { cachelist.splice(cachelist.begin(), cachelist, cachemap[key]); return cachemap[key]->value; } else { return -1; } } void set(int key, int value) { if (cachemap.find(key) != cachemap.end()) { cachelist.splice(cachelist.begin(), cachelist, cachemap[key]); cachemap[key]->value = value; } else { if (size == cachelist.size()) { cachemap.erase(cachelist.back().key); cachelist.pop_back(); } cachelist.push_front(CacheNode(key, value)); cachemap[key] = cachelist.begin(); } } private: list cachelist; unordered_map::iterator> cachemap; int size; }; ================================================ FILE: LargestNumber.h ================================================ /* Author: King, nkuwjg@gmail.com Date: Jan 13, 2015 Problem: ZigZag Conversion Difficulty: Medium Source: https://oj.leetcode.com/problems/largest-number/ Notes: Given a list of non negative integers, arrange them such that they form the largest number. For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330. Note: The result may be very large, so you need to return a string instead of an integer. Solution: ... */ class Solution { public: static string itos(int i) { // convert int to string stringstream s; s << i; return s.str(); } static bool cmp(const int & a, const int &b) { string s1 = itos(a), s2 = itos(b); return s1+s2>s2+s1; } string largestNumber(vector &num) { sort(num.begin(),num.end(), cmp); stringstream res; int i = 0; while ((i < num.size() -1) && num[i] == 0) i++; while (i < num.size()) res << num[i++]; return res.str(); } }; ================================================ FILE: LargestRectangleinHistogram.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Oct 6, 2013 Update: Oct 8, 2014 Problem: Largest Rectangle in Histogram Difficulty: Hard Source: http://leetcode.com/onlinejudge#question_84 Notes: Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram. For example, Given height = [2,1,5,6,2,3], return 10. Solution: 1. Only calucate area when reaching local maximum value. 2. Keep a non-descending stack. O(n). 3. Keep a non-descending stack. O(n). if the vector height is not allowed to be changed. */ class Solution { public: int largestRectangleArea(vector &height) { return largestRectangleArea_1(height); } int largestRectangleArea_1(vector &height) { int res = 0; int N = height.size(); for (int i = 0; i < N; ++i) { if (i < N - 1 && height[i] <= height[i + 1]) { continue; } int minHeight = height[i]; for (int j = i; j >= 0; --j) { minHeight = min(minHeight, height[j]); res = max(res, (i - j + 1) * minHeight); } } return res; } int largestRectangleArea_2(vector &height) { height.push_back(0); int N = height.size(); int res = 0, i = 0; stack s; while (i < N) { if (s.empty() || height[i] >= height[s.top()]) { s.push(i++); } else { int idx = s.top(); s.pop(); int width = s.empty() ? i : (i - s.top() - 1); res = max(res, height[idx] * width); } } return res; } int largestRectangleArea_3(vector &height) { int N = height.size(); int res = 0, i = 0; stack s; while(i < N) { if(s.empty() || height[s.top()] <= height[i]){ s.push(i++); }else{ int idx = s.top(); s.pop(); int width = s.empty() ? i : (i - s.top() - 1); res = max(res, height[idx] * width); } } while(!s.empty()){ int idx = s.top(); s.pop(); int width = s.empty() ? i : (i - s.top() - 1); res = max(res, height[idx] * width); } return res; } }; ================================================ FILE: LengthofLastWord.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 17, 2013 Problem: Length of Last Word Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_58 Notes: Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string. If the last word does not exist, return 0. Note: A word is defined as a character sequence consists of non-space characters only. For example, Given s = "Hello World", return 5. Solution: ... */ class Solution { public: int lengthOfLastWord(const char *s) { int res = 0; int length = strlen(s); for (int i = length - 1; i >= 0; --i) if (s[i] != ' ') res++; else if(res > 0) break; return res; } }; ================================================ FILE: LetterCombinationsofaPhoneNumber.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 12, 2013 Update: Dec 02, 2014 Problem: Letter Combinations of a Phone Number Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_17 Notes: Given a digit string, return all possible letter combinations that the number could represent. A mapping of digit to letters (just like on the telephone buttons) is given below. Input:Digit string "23" Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. Note: Although the above answer is in lexicographical order, your answer could be in any order you want. Solution: ... */ class Solution { public: vector letterCombinations(string digits) { vector keyboard {" ","","abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; vector res; string s; letterCombinationsRe(keyboard,digits,s,res); return res; } void letterCombinationsRe(vector &keyboard, string &digits, string &s, vector&res){ if(s.size() == digits.size()){ res.push_back(s); return; } string &letters = keyboard[digits[s.size()]-'0']; for(size_t i = 0; i < letters.size(); ++i){ s.push_back(letters[i]); letterCombinationsRe(keyboard, digits,s,res); s.pop_back(); } } }; ================================================ FILE: LinkedListCycle.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Nov 9, 2013 Update: Oct 5, 2014 Problem: Linked List Cycle Difficulty: Easy Source: http://oj.leetcode.com/problems/linked-list-cycle/ Notes: Given a linked list, determine if it has a cycle in it. Follow up: Can you solve it without using extra space? Solution: two pointers. */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: bool hasCycle(ListNode *head) { ListNode *slow = head, *fast = head; while (fast && fast->next) { fast = fast->next->next; slow = slow->next; if (fast == slow) return true; } return false; } }; ================================================ FILE: LinkedListCycleII.h ================================================ /* Author: Matthew Jin, marthew777@gmail.com Date: Feb 21, 2014 Problem: Linked List Cycle II Difficulty: Easy Source: http://oj.leetcode.com/problems/linked-list-cycle-ii/ Notes: Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Follow up: Can you solve it without using extra space? Solution: From Matthew. Simpler. */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *detectCycle(ListNode *head) { if (head == NULL) return NULL; ListNode *slow = head, *fast = head; while (fast && fast->next) { fast = fast->next->next; slow = slow->next; if (fast == slow) break; } if (fast == NULL || fast->next == NULL) return NULL; fast = head; while (fast != slow) { fast = fast->next; slow = slow->next; } return slow; } }; ================================================ FILE: LongestCommonPrefix.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, wangjingui@outlook.com Date: Apr 16, 2013 Update: Dec 20, 2014 Problem: Longest Common Prefix Difficulty: Easy Source: https://oj.leetcode.com/problems/longest-common-prefix/ Notes: Write a function to find the longest common prefix string amongst an array of strings. Solution: ... */ class Solution { public: string longestCommonPrefix(vector &strs) { if(strs.empty()) return ""; for(int i = 0;i < strs[0].size(); ++i){ for(int j = 1;j < strs.size(); ++j){ if(strs[j][i] != strs[0][i]) return strs[0].substr(0,i); } } return strs[0]; } }; ================================================ FILE: LongestConsecutiveSequence.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 24, 2013 Update: Jun 18, 2014 Problem: Longest Consecutive Sequence Difficulty: Hard Source: https://oj.leetcode.com/problems/longest-consecutive-sequence/ Notes: Given an unsorted array of integers, find the length of the longest consecutive elements sequence. For example, Given [100, 4, 200, 1, 3, 2], The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4. Your algorithm should run in O(n) complexity. Solution 1: Update solution. This solution is from Peking2 (http://blog.sina.com.cn/s/blog_b9285de20101iqar.html). This solution is much easier to understand. Solution 2: by Yao Liu. */ class Solution { public: int longestConsecutive(vector &num) { return longestConsecutive1(num); } int longestConsecutive1(vector &num) { unordered_set s; int res = 0; for (int i = 0; i < num.size(); ++i) s.insert(num[i]); for (int i = 0; i < num.size() && !s.empty(); ++i) { if (s.find(num[i]) == s.end()) continue; int upper = num[i], lower = num[i]; while (s.find(upper+1) != s.end()) s.erase(++upper); while (s.find(lower-1) != s.end()) s.erase(--lower); if (upper != lower) s.erase(num[i]); res = max(res, upper - lower + 1); } return res; } int longestConsecutive2(vector &num) { int longest = 0; unordered_map table; for(int i = 0, count = num.size(); i < count; ++i) if(table.find(num[i]) == table.end()) { int val = num[i], update; if(table.find(val - 1) != table.end() && table.find(val + 1) != table.end()) // assigning to table[val] here is only for adding val as a key of the hashtable. update = table[val] = table[val - table[val - 1]] = table[val + table[val + 1]] = table[val - 1] + table[val + 1] + 1; else if(table.find(val - 1) != table.end()) update = table[val] = ++table[val - table[val - 1]]; else if(table.find(val + 1) != table.end()) update = table[val] = ++table[val + table[val + 1]]; else update = table[val] = 1; longest = max(longest, update); } return longest; } }; ================================================ FILE: LongestPalindromicSubstring.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Jul 13, 2013 Update: Nov 17, 2014 : By wangjingui@outlook.com Problem: Longest Palindromic Substring Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_5 Notes: Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. Solution: 1. Time O(n^2), Space O(n^2) 2. Time O(n^2), Space O(n) 3. Time O(n^2), Space O(1) (actually much more efficient than 1 & 2) 4. Time O(n), Space O(n) (Manacher's Algorithm) */ class Solution { public: string longestPalindrome(string s) { return longestPalindrome_4(s); } string longestPalindrome_1(string s) { int N = s.size(); bool dp[N][N]; pair res = make_pair(0, 0); // start pos and length for (int k = 0; k < N; ++k) // length { for (int i = 0; i < N-k; ++i) // start pos { if (k == 0 || k == 1) dp[i][i+k] = s[i] == s[i+k]; else dp[i][i+k] = (s[i] == s[i+k]) ? dp[i+1][i+k-1] : false; if (dp[i][i+k] && k+1 > res.second) res = make_pair(i, k+1); } } return s.substr(res.first, res.second); } string longestPalindrome_2(string s) { int N = s.size(); bool dp[2][N]; pair res = make_pair(0, 0); int cur = 1, last = 0; for (int i = 0; i < N; ++i) { cur = !cur; last = !last; for (int j = i; j >= 0; --j) { if (j == i || j == i-1) dp[cur][j] = s[j] == s[i]; else dp[cur][j] = s[j] == s[i] && dp[last][j+1]; if (dp[cur][j] && i-j+1 > res.second) res = make_pair(j, i-j+1); } } return s.substr(res.first, res.second); } string longestPalindrome_3(string s) { int N = s.size(); pair res = make_pair(0, 0); // start pos and length for (int i = 0; i < N; ++i) { for (int j = 0; j <= 1; ++j) { bool isP = true; for (int k = 0; i-k >= 0 && i+j+k < N && isP; ++k) { isP = s[i-k] == s[i+j+k]; if (isP && j+1+k*2 > res.second) res = make_pair(i-k, j+1+k*2); } } } return s.substr(res.first, res.second); } string longestPalindrome_4(string s) { int N = s.size(); int dp[2 * N + 1]; int id = 0, mx = 0; for (int i = 0; i < 2 * N + 1; ++i) { int j = 2 * id - i; dp[i] = mx > i ? min(dp[j], mx - i) : 1; int left = i - dp[i], right = i + dp[i]; for (; left >= 0 && right <= 2 * N; left--, right++) { if (left % 2 == 0 || s[left/2] == s[right/2]) // padding or char dp[i]++; else break; } if (i + dp[i] > mx) { id = i; mx = id + dp[id]; } } int res = 0; for (int i = 1; i < 2 * N + 1; ++i) if (dp[i] > dp[res]) res = i; return s.substr(res / 2 - (dp[res] - 1) / 2, dp[res] - 1); } }; ================================================ FILE: LongestSubstringWithoutRepeatingCharacters.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com, King, wangjingui@outlook.com Date: Apr 16, 2013 Update: Dec 12, 2014 Problem: Longest Substring Without Repeating Characters Difficulty: Medium Source: https://oj.leetcode.com/problems/longest-substring-without-repeating-characters/ Notes: Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1. Solution: 1. Pay attention when moving the 'start' pointer forward. 2. More space, but maybe faster. */ class Solution { public: int lengthOfLongestSubstring_1(string s) { bool exist[256]; memset(exist, false, sizeof(exist)); int res = 0; int start = 0, end = 0, N = s.size(); while (end < N && start + res < N) { if (!exist[s[end]]) exist[s[end++]] = true; else exist[s[start++]] = false; res = max(end - start, res); } return res; } int lengthOfLongestSubstring_2(string s) { int len = s.length(); if(len <= 1) return len; vector hash(256,-1); hash[s[0]]=0; int start = 0, cur = 0, res = 1; while(++cur < len){ if(hash[s[cur]]>=start){ start = hash[s[cur]]+1; } res = max (res, cur - start + 1); hash[s[cur]] = cur; } return res; } }; ================================================ FILE: LongestValidParentheses.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : Andy, nkuwjg@gmail.com Date: May 6, 2013 Update: Jan 15, 2015 Problem: Longest Valid Parentheses Difficulty: Easy Source: https://oj.leetcode.com/problems/longest-valid-parentheses/ Notes: Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring. For "(()", the longest valid parentheses substring is "()", which has length = 2. Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4. Solution: O(n). */ class Solution { public: int longestValidParentheses(string s) { return longestValidParentheses_1(s); } // Solution 1, from fuwutu. Smart! // push the length of last valid parentheses into stack. int longestValidParentheses_1(string s) { stack stk; int res = 0, count = 0; for(int i = 0; i < s.size(); ++i) { if (s[i] == '(') { stk.push(count); count = 0; } else if (!stk.empty()) { count += (1 + stk.top()); stk.pop(); res = max(res, count); } else { count = 0; } } return res * 2; } // Solution 2, By Annie. // Traverse the string twice, taking O(n) time. // First time, mark all the matching parentheses as '*' (push the index of '(' into ). // Second time, count the longest consecutive '*'. int longestValidParentheses_2(string s) { stack stk; for (int i = 0; i < s.size(); ++i) { if (s[i] == '(') { stk.push(i); } else if (!stk.empty()) { s[stk.top()] = '*'; s[i] = '*'; stk.pop(); } } int res = 0, part = 0; for (int i = 0; i < s.size(); ++i) { if (s[i] == '*') { part++; } else { res = max(res, part); part = 0; } } res = max(res, part); return res; } // Dp Solution. By Andy. int longestValidParentheses_3(string s) { int n = s.size(); if(s.empty()) return 0; if(n<=1) return 0; int res = 0; vector f(n,0); for(int i=n-2;i>=0;i--){ int match = i + f[i+1] + 1; if(match= 0; --i) { counter += s[i] == ')' ? 1 : -1; if (counter < 0) { val = counter = 0; continue; } val += s[i] == ')' ? 0 : 2; res = counter == 0 ? max(res, val) : res; } return res; } }; ================================================ FILE: MajorityElement.h ================================================ /* Author: King, wangjingui@outlook.com Date: Dec 20, 2014 Problem: Majority Element Difficulty: Easy Source: https://oj.leetcode.com/problems/majority-element/ Notes: Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. You may assume that the array is non-empty and the majority element always exist in the array. Solution: 1. Runtime: O(n) — Moore voting algorithm: We maintain a current candidate and a counter initialized to 0. As we iterate the array, we look at the current element x: If the counter is 0, we set the current candidate to x and the counter to 1. If the counter is not 0, we increment or decrement the counter based on whether x is the current candidate. After one pass, the current candidate is the majority element. Runtime complexity = O(n). 2. Runtime: O(n) — Bit manipulation: We would need 32 iterations, each calculating the number of 1's for the ith bit of all n numbers. Since a majority must exist, therefore, either count of 1's > count of 0's or vice versa (but can never be equal). The majority number’s ith bit must be the one bit that has the greater count. */ class Solution { public: int majorityElement_1(vector &num) { int n = num.size(); if (n == 0) return 0; if (n == 1) return num[0]; int res = num[0], cnt = 1; for (int i = 1; i < num.size(); ++i) { if (cnt == 0) { res = num[i]; ++cnt; continue; } if (res == num[i]) ++cnt; else --cnt; } return res; } int majorityElement_2(vector &num) { int n = num.size(); if (n == 0) return 0; if (n == 1) return num[0]; int res = 0; for (int i = 0; i < 32; ++i) { int one = 0, zero = 0; for (int j = 0; j < n; ++j) { if (((num[j]>>i) & 1) == 1) ++one; else ++zero; } if (one > zero) res = res | (1<0) dx=x/g,dy=y/g; else if(y<0) dx=-x/g,dy=-y/g; } int gcd(int a, int b) { if(b == 0) return a; else return gcd(b, a%b); } bool operator==(const pt &b) const { return dx == b.dx && dy == b.dy; } bool operator<(const pt &b) const { if(dx == b.dx) return dy < b.dy; return dx < b.dx; } }; int maxPoints_1(vector &points) { int N = points.size(), res(0); unordered_map m; for (int i =0; i < N; ++i) { m.clear(); int ss(1), sp(0);// ss: points with same slope, sp: same points. for (int j = i + 1; j < N; ++j) { double slope = std::numeric_limits::infinity(); if (points[i].x != points[j].x) { slope = 1.0*(points[i].y-points[j].y)/(points[i].x-points[j].x); } else if (points[i].y == points[j].y) { ++sp; continue; } int tmp = 0; if(m.find(slope) != m.end()) tmp = ++m[slope]; else tmp = m[slope] = 2; ss = max(ss, tmp); } res = max(res, ss + sp); } return res; } int maxPoints_2(vector &points) { int N = points.size(), res(0); pt zero(0,0); map m; for (int i=0; i < N; ++i) { m.clear(); int ss(0), sp(0); for (int j = 0; j < N; ++j) { pt slope(points[i].x-points[j].x, points[i].y-points[j].y); if (slope == zero) ++sp; else { ss = max(ss, ++m[slope]); } } res = max(res, ss + sp); } return res; } }; ================================================ FILE: MaximalRectangle.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: May 23, 2013 Update: Oct 09, 2014 Problem: Maximal Rectangle Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_85 Notes: Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area. Solution: 1. dp. (72 milli secs for the large). a) dp[i][j] records the number of consecutive '1' on the left and up of the element matrix[i][j]. b) For each element(i,j), calculate the area of rectangle including the element itself. 2. calculate 'Largest Rectangle in Histogram' for each row. 3. Time : O(n ^ 2), Space : O(n). */ class Solution { public: int maximalRectangle(vector> &matrix) { return maximalRectangle_3(matrix); } int maximalRectangle_1(vector> &matrix) { if (matrix.empty() || matrix[0].empty()) return 0; int N = matrix.size(), M = matrix[0].size(); pair dp[N][M]; memset(dp, 0, sizeof(dp)); int res = 0; for (int i = 0; i < N; ++i) { for (int j = 0; j < M; ++j) { if (matrix[i][j] == '0') continue; int x = (j == 0) ? 1 : dp[i][j-1].first + 1; int y = (i == 0) ? 1 : dp[i-1][j].second + 1; dp[i][j] = make_pair(x, y); int minHeight = y; for (int k = j; k > j - x; --k) { minHeight = min(minHeight, dp[i][k].second); res = max(res, minHeight * (j - k + 1)); } } } return res; } int maximalRectangle_2(vector > &matrix) { if (matrix.empty() || matrix[0].empty()) return 0; int N = matrix.size(), M = matrix[0].size(); vector height(M+1, 0); int res = 0; for (int i = 0; i < N; ++i) { for (int j = 0; j < M; ++j) height[j] = (matrix[i][j] == '0') ? 0 : height[j] + 1; res = max(res, largestRectangleArea(height)); } return res; } // a little different from 'Largest Rectangle in Histogram' // final 0 is already provided beforehand int largestRectangleArea(const vector &height) { stack stk; int res = 0, N = height.size(); for (int i = 0; i < N; ++i) { int count = 0; while (!stk.empty() && stk.top() > height[i]) { count++; res = max(res, count * stk.top()); stk.pop(); } while (count--) stk.push(height[i]); stk.push(height[i]); } return res; } int maximalRectangle_3(vector > &matrix) { if (matrix.empty()) return 0; int m = matrix.size(); int n = matrix[0].size(); std::vector H(n, 0); std::vector L(n, 0); std::vector R(n, n); int res = 0; for (int i = 0; i < m; ++i) { int left = 0, right = n; for (int j = 0; j < n; ++j) { if (matrix[i][j] == '1') { ++H[j]; L[j] = max(left, L[j]); } else { left = j + 1; H[j] = 0; L[j] = 0; R[j] = n; } } for (int j = n - 1; j >= 0; --j) { if (matrix[i][j] == '1') { R[j] = min(R[j], right); res = max(res, (R[j] - L[j]) * H[j]); } else { right = j; } } } return res; } }; ================================================ FILE: MaximumDepthofBinaryTree.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 9, 2013 Problem: Maximum Depth of Binary Tree Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_104 Notes: Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. Solution: Recursion. */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: int maxDepth(TreeNode *root) { if (!root) return 0; return 1 + max(maxDepth(root->left), maxDepth(root->right)); } }; ================================================ FILE: MaximumGap.h ================================================ /* Author: King, wangjingui@outlook.com Date: Dec 14, 2014 Problem: Maximum Gap Difficulty: Hard Source: https://oj.leetcode.com/problems/maximum-gap/ Notes: Given an unsorted array, find the maximum difference between the successive elements in its sorted form. Try to solve it in linear time/space. Return 0 if the array contains less than 2 elements. You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range. Solution: 1. Time : O(nlogn). Space : O(1); Sort the unsorted array, and find the maximum difference. 2. Time : O(n). Space : O(n). Drawer Theory. If we put n numbers into (n+1) drawers, then there must be at least one empty drawer. So we can find the maximum difference between two succesive non-empty drawers. */ class Solution { public: int maximumGap_1(vector &num) { sort(num.begin(), num.end()); int res = 0; for (int i = 1; i < num.size(); ++i) { res = max(res, num[i] - num[i-1]); } return res; } int maximumGap_2(vector &num) { int n = num.size(); if (n < 2) return 0; int minVal = num[0], maxVal = num[0]; for (int i = 1; i < n; ++i) { minVal = min(minVal, num[i]); maxVal = max(maxVal, num[i]); } //delta = (maxVal + 1 - minVal) / (n + 1) //idx = (val - minVal) / delta = (val - minVal) * (n + 1) / (maxVal + 1 - minVal) vector > pool(n+2,make_pair(-1,-1)); for (int i = 0; i < n; ++i) { int idx = (long long)(num[i] - minVal)* (n + 1) / (maxVal + 1 - minVal); if (pool[idx].first == -1) { pool[idx] = make_pair(num[i],num[i]); } else { pool[idx].first = min(pool[idx].first, num[i]); pool[idx].second = max(pool[idx].second, num[i]); } } int last = pool[0].second; int res = 0; for (int i = 1; i < n + 2; ++i) { if (pool[i].first != -1) { res = max(res, pool[i].first - last); last = pool[i].second; } } return res; } }; ================================================ FILE: MaximumProductSubarray.h ================================================ /* Author: King, higuige@gmail.com Date: Sep 24, 2014 Update: Oct 06, 2014 Problem: Maximum Product Subarray Difficulty: Medium Source: https://oj.leetcode.com/problems/maximum-product-subarray/ Notes: Find the contiguous subarray within an array (containing at least one number) which has the largest product. For example, given the array [2,3,-2,4], the contiguous subarray [2,3] has the largest product = 6. */ class Solution { public: int maxProduct(int A[], int n) { if (n <= 0) { return 0; } int maxVal = A[0], minVal = A[0], res = A[0]; for (int i = 1; i < n; ++i) { int tmpVal = maxVal; maxVal = max(max(maxVal * A[i], minVal * A[i]), A[i]); minVal = min(min(tmpVal * A[i], minVal * A[i]), A[i]); res = max(res, maxVal); } return res; } int maxProduct_2(int A[], int n) { if(n==0) return 0; if(n==1) return A[0]; int minVal = 0; int product = 1; int res = A[0]; for(int i=0;i n) return findKthSortedArrays(B, n, A, m, k); if (m == 0) return B[k-1]; if (k == 1) return min(A[0], B[0]); int i = min(k / 2, m); int j = k - i; int a = A[i-1]; int b = B[j-1]; if (a < b) return findKthSortedArrays(A + i, m - i, B, n, k - i); else if (a > b) return findKthSortedArrays(A, m, B + j, n - j, k - j); else return a; } double findMedianSortedArrays_3(int A[], int m, int B[], int n) { return findMedian(A, m, B, n, max(0, (m + n) / 2 - n), min(m - 1, (m + n) / 2)); } double findMedian(int A[], int m, int B[], int n, int l, int r) { if (l > r) return findMedian(B, n, A, m, max(0, (m + n) / 2 - m), min(n, (m + n) / 2)); int i = (l + r) / 2; int j = (m + n) / 2 - i; int Ai_1 = (i == 0) ? INT_MIN : A[i-1]; int Bj_1 = (j == 0) ? INT_MIN : B[j-1]; int Ai = (i == m) ? INT_MAX : A[i]; int Bj = (j == n) ? INT_MAX : B[j]; if (Ai < Bj_1) return findMedian(A, m, B, n, i+1, r); if (Ai > Bj) return findMedian(A, m, B, n, l, i-1); if ((m + n) % 2 == 1) return Ai; else return (Ai + max(Ai_1, Bj_1)) / 2.0; } }; ================================================ FILE: MergeIntervals.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Jun 7, 2013 Update: Jul 15, 2013 Problem: Merge Intervals Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_56 Notes: Given a collection of intervals, merge all overlapping intervals. For example, Given [1,3],[2,6],[8,10],[15,18], return [1,6],[8,10],[15,18]. Solution: 1. Sort in ascending order of 'start'. 2. Traverse the 'intervals', merge or push... */ /** * Definition for an interval. * struct Interval { * int start; * int end; * Interval() : start(0), end(0) {} * Interval(int s, int e) : start(s), end(e) {} * }; */ bool compare(Interval a, Interval b) { return a.start < b.start; } class Solution { public: vector merge(vector &intervals) { int N = intervals.size(); if (N <= 1) return intervals; sort(intervals.begin(), intervals.end(), mycompare); vector res; Interval last = intervals[0]; for (int i = 1; i < N; ++i) { if (intervals[i].start > last.end) { res.push_back(last); last = intervals[i]; } else { last.end = max(last.end, intervals[i].end); } } res.push_back(last); return res; } }; ================================================ FILE: MergeSortedArray.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 10, 2013 Update: Aug 7, 2013 Problem: Merge Sorted Array Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_88 Notes: Given two sorted integer arrays A and B, merge B into A as one sorted array. Note: You may assume that A has enough space to hold additional elements from B. The number of elements initialized in A and B are m and n respectively. Solution: From back to forth. */ class Solution { public: void merge(int A[], int m, int B[], int n) { int i = m - 1; int j = n - 1; int x = m + n - 1; while (i >= 0 && j >= 0) if (A[i] >= B[j]) A[x--] = A[i--]; else A[x--] = B[j--]; while (j >= 0) A[x--] = B[j--]; } }; ================================================ FILE: MergeTwoSortedLists.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 17, 2013 Update: Sep 2, 2013 Problem: Merge Two Sorted Lists Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_21 Notes: Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. Solution: ... */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) { ListNode head(0), *cur = &head; while (l1 && l2) { ListNode **min = l1->val < l2->val ? &l1 : &l2; cur->next = *min; cur = cur->next; *min = (*min)->next; } if (l1) cur->next = l1; if (l2) cur->next = l2; return head.next; } }; ================================================ FILE: MergekSortedLists.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, wangjingui@outlook.com Date: Apr 6, 2013 Update: Nov 17, 2014 Problem: Merge k Sorted Lists Difficulty: easy Source: http://leetcode.com/onlinejudge#question_23 Notes: Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. Solution: Find the smallest list-head first using minimum-heap(lgk). complexity: O(N*KlgK) */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Mycompare { public: bool operator()(ListNode *a, ListNode *b) { return a->val > b->val; } }; class Solution { public: ListNode *mergeKLists(vector &lists) { priority_queue, Mycompare> q; for (int i = 0; i < lists.size(); ++i) if (lists[i]) q.push(lists[i]); ListNode dummy(0), *cur = &dummy; while (!q.empty()) { ListNode *node = q.top(); q.pop(); cur = cur->next = node; if (node->next) q.push(node->next); } return dummy.next; } ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) { ListNode head(0), *cur = &head; while (l1 && l2) { ListNode **min = l1->val < l2->val ? &l1 : &l2; cur->next = *min; cur = cur->next; *min = (*min)->next; } if (l1) cur->next = l1; if (l2) cur->next = l2; return head.next; } ListNode *mergeKLists_2(vector &lists) { if(lists.size()==0) return NULL; int sz = lists.size(); int end = sz - 1; while (end > 0) { int begin = 0; while (begin < end) { lists[begin] = mergeTwoLists(lists[begin], lists[end]); ++begin; --end; } } return lists[0]; } }; ================================================ FILE: MinStack.h ================================================ /* Author: King, higuige@gmail.com Date: Nov 14, 2014 Problem: Min Stack Difficulty: Easy Source: https://oj.leetcode.com/problems/min-stack/ Notes: Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. push(x) -- Push element x onto stack. pop() -- Removes the element on top of the stack. top() -- Get the top element. getMin() -- Retrieve the minimum element in the stack. */ class MinStack { public: void push(int x) { elements.push(x); if (minstk.empty() || x <= minstk.top()) { minstk.push(x); } } void pop() { if (elements.empty()) { return; } if (elements.top() == minstk.top()) { minstk.pop(); } elements.pop(); } int top() { return elements.top(); } int getMin() { return minstk.top(); } private: stack elements; stack minstk; }; ================================================ FILE: MinimumDepthofBinaryTree.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 6, 2013 Update: Nov 17, 2014 : by King, wangjingui@outlook.com Problem: Minimum Depth of Binary Tree Difficulty: easy Source: http://leetcode.com/onlinejudge#question_111 Notes: Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. Solution: 1. Recursion. Pay attention to cases when the non-leaf node has only one child. 2. Iteration + Queue. Contributed by SUN Mian(孙冕). */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: int minDepth(TreeNode *root) { return minDepth_1(root); } int minDepth_1(TreeNode *root) { if (!root) return 0; if (!root->left) return 1 + minDepth_1(root->right); if (!root->right) return 1 + minDepth_1(root->left); return 1 + min(minDepth_1(root->left), minDepth_1(root->right)); } int minDepth_2(TreeNode *root) { if (!root) return 0; queue q; q.push(root); TreeNode * rightmost = root; int depth = 1; while (!q.empty()) { TreeNode *node = q.front(); q.pop(); if (!node->left && !node->right) return depth; if (node->left) q.push(node->left); if (node->right) q.push(node->right); if (node == rightmost) { ++depth; rightmost = node->right?node->right:node->left; } } } }; ================================================ FILE: MinimumPathSum.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 17, 2013 Update: Jul 30, 2013 Problem: Minimum Path Sum Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_64 Notes: Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time. Solution: Dynamic Programming. Space O(N). */ class Solution { public: int minPathSum(vector > &grid) { if (grid.empty()) return INT_MIN; int M = grid.size(), N = grid[0].size(); int dp[N]; dp[0] = grid[0][0]; for (int i = 1; i < N; ++i) dp[i] = grid[0][i] + dp[i-1]; for (int i = 1; i < M; ++i) { dp[0] += grid[i][0]; for (int j = 1; j < N; ++j) dp[j] = min(dp[j-1], dp[j]) + grid[i][j]; } return dp[N-1]; } }; ================================================ FILE: MinimumWindowSubstring.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 24, 2013 Update: Jul 30, 2013 Problem: Minimum Window Substring Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_76 Notes: Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n). For example, S = "ADOBECODEBANC" T = "ABC" Minimum window is "BANC". Note: If there is no such window in S that covers all characters in T, return the empty string "". If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S. Solution: 1. Use two pointers: start and end. First, move 'end'. After finding all the needed characters, move 'start'. 2. Use array as hashtable. */ class Solution { public: string minWindow(string S, string T) { int N = S.size(), M = T.size(); if (N < M) return ""; int need[256] = {0}; int find[256] = {0}; for (int i = 0; i < M; ++i) need[T[i]]++; int count = 0, resStart = -1, resEnd = N; for (int start = 0, end = 0; end < N; ++end) { if (need[S[end]] == 0) continue; if (find[S[end]] < need[S[end]]) count++; find[S[end]]++; if (count != M) continue; // move 'start' for (; start < end; ++start) { if (need[S[start]] == 0) continue; if (find[S[start]] <= need[S[start]]) break; find[S[start]]--; } // update result if (end - start < resEnd - resStart) { resStart = start; resEnd = end; } } return (resStart == -1) ? "" : S.substr(resStart, resEnd - resStart + 1); } }; ================================================ FILE: MultiplyStrings.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 23, 2013 Update: Aug 20, 2013 Problem: Multiply Strings Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_43 Notes: Given two numbers represented as strings, return multiplication of the numbers as a string. Note: The numbers can be arbitrarily large and are non-negative. Solution: Just like what we do when multiplying integers. */ class Solution { public: string multiply(string num1, string num2) { int N = num1.size(), M = num2.size(); string res(N+M, '0'); for (int i = N - 1; i >= 0; --i) { int carry = 0; for (int j = M - 1; j >= 0; --j) { int sum = carry + (res[i+j+1] - '0') + (num1[i] - '0') * (num2[j] - '0'); res[i+j+1] = sum % 10 + '0'; carry = sum / 10; } res[i] += carry; } while (res.size() > 1 && res[0] == '0') res.erase(res.begin()); return res; } }; ================================================ FILE: N-Queens.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 24, 2013 Update: Jul 25, 2013 Problem: N-Queens Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_51 Notes: The n-queens puzzle is the problem of placing n queens on an n*n chessboard such that no two queens attack each other. Given an integer n, return all distinct solutions to the n-queens puzzle. Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively. For example, There exist two distinct solutions to the 4-queens puzzle: [ [".Q..", // Solution 1 "...Q", "Q...", "..Q."], ["..Q.", // Solution 2 "Q...", "...Q", ".Q.."] ] Solution: Recursion (DFS). Use bit-manipulation solution (See N-QueensII for more details). */ class Solution { public: vector > solveNQueens(int n) { vector > res; vector sol; solveNQueensRe(n, 0, 0, 0, sol, res); return res; } void solveNQueensRe(int n, int row, int ld, int rd, vector &sol, vector> &res) { if (row == (1 << n) - 1) { res.push_back(sol); return; } int avail = ~(row | ld | rd); for (int i = n-1; i >= 0; --i) { int pos = 1 << i; if (avail & pos) { string s(n, '.'); s[i] = 'Q'; sol.push_back(s); solveNQueensRe(n, row | pos, (ld|pos) << 1, (rd|pos) >> 1, sol, res); sol.pop_back(); } } } }; ================================================ FILE: N-QueensII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 24, 2013 Update: Aug 23, 2013 Problem: N-Queens II Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_52 Notes: The n-queens puzzle is the problem of placing n queens on an n*n chessboard such that no two queens attack each other. Given an integer n, return all distinct solutions to the n-queens puzzle. Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively. For example, There exist two distinct solutions to the 4-queens puzzle: [ [".Q..", // Solution 1 "...Q", "Q...", "..Q."], ["..Q.", // Solution 2 "Q...", "...Q", ".Q.."] ] Solution: 1. Recursion. 2. Recursion + bit version. (fast) The idea is from http://www.matrix67.com/blog/archives/266 (in chinese). 3. Iteration. */ class Solution { public: int totalNQueens(int n) { return totalNQueens_2(n); } // solution 1: recursion int totalNQueens_1(int n) { int board[n]; memset(board, -1, sizeof(board)); int res = 0; totalNQueensRe(n, 0, board, res); return res; } void totalNQueensRe(int n, int row, int board[], int &res) { if (row == n) { res++; return; } for (int i = 0; i < n; ++i) { if (isValid(board, row, i)) { board[row] = i; totalNQueensRe(n, row + 1, board, res); board[row] = -1; } } } bool isValid(int board[], int row, int col) { for (int i = 0; i < row; ++i) if (board[i] == col || row - i == abs(col - board[i])) return false; return true; } // solution 2: bit version int totalNQueens_2(int n) { int res = 0; totalNQueensRe_2(n, 0, 0, 0, res); return res; } void totalNQueensRe_2(int n, int row, int ld, int rd, int &res) { if (row == (1 << n) - 1) { res++; return; } int avail = ~(row | ld | rd); for (int i = n - 1; i >= 0; --i) { int pos = 1 << i; if (avail & pos) totalNQueensRe_2(n, row | pos, (ld | pos) << 1, (rd | pos) >> 1, res); } } // solution 3: iterative solution int totalNQueens_3(int n) { int board[n]; memset(board, -1, sizeof(board)); int row = 0; int res = 0; while (row != -1) { if (row == n) { res++; row--; } int i = board[row] == -1 ? 0 : board[row] + 1; for (; i < n; ++i) { if (isValid(board, row, i)) { board[row] = i; row++; break; } } if (i == n) { board[row] = -1; row--; } } return res; } }; ================================================ FILE: NextPermutation.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, wangjingui@outlook.com Date: May 6, 2013 Update: Dec 16, 2014 Problem: Next Permutation Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_31 Notes: Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers. If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order). The replacement must be in-place, do not allocate extra memory. Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column. 1,2,3 -> 1,3,2 3,2,1 -> 1,2,3 1,1,5 -> 1,5,1 Solution: O(n) Processes: Take A = {1,3,2} as an example: 1. Traverse from back to forth, find the turning point, that is A[i] = 3. 2. Sort from the turning point to the end (A[i] to A[end]), so {3,2} becomes {2,3}. 3. If i equals to 0, finish! Else, goto 4. 4. Let j = i, search from A[j] to A[end] to find the first elem which is larger than A[i-1], '2' here. 5. Swap the elem A[j] with A[i-1]. Finally, the next permutation is {2,1,3}. */ class Solution { public: void nextPermutation(vector &num) { int n = num.size(), i = n - 1, j = 0; while(i > 0 && num[i-1] >= num[i]) --i; reverse(num.begin() + i,num.end()); if (i == 0) return; while (i+j < n && num[i-1] >= num[i+j]) ++j; swap(num[i-1], num[i+j]); } }; ================================================ FILE: PalindromeNumber.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 16, 2013 Update: Aug 22, 2013 Problem: Palindrome Number Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_9 Notes: Determine whether an integer is a palindrome. Do this without extra space. Some hints: Could negative integers be palindromes? (ie, -1) (No!) If you are thinking of converting the integer to string, note the restriction of using extra space. You could also try reversing an integer. However, if you have solved the problem "Reverse Integer", you know that the reversed integer might overflow. How would you handle such case? There is a more generic way of solving this problem. Solution: 1. Count the number of digits first (traverse once) then check the digits from both sides to center. 2. Reverse the number, then check to see if x == reverse(x). 3. Recursion (interesting but a little hard to understand). */ class Solution { public: bool isPalindrome(int x) { return isPalindrome1(x); } // solution 1 bool isPalindrome1(int x) { if (x < 0) return false; int d = 1; while (x / d >= 10) d *= 10; while (d > 1) { if (x % 10 != x / d) return false; x = x % d / 10; d /= 100; } return true; } // solution 2 bool isPalindrome2(int x) { if (x < 0) return false; return x == reverse(x); } int reverse(int x) { int rev = 0; while (x) { rev = rev * 10 + x % 10; x /= 10; } return rev; } // solution 3 bool isPalindrome3(int x) { return isPalindromeRe(x, x); } bool isPalindromeRe(int x, int &y) { if (x < 0) return false; if (x == 0) return true; if (isPalindromeRe(x / 10, y) && x % 10 == y % 10) { y /= 10; return true; } return false; } }; ================================================ FILE: PalindromePartitioning.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: May 20, 2013 Update: Oct 06, 2014 Problem: Palindrome Partitioning Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_131 Notes: Given a string s, partition s such that every substring of the partition is a palindrome. Return all possible palindrome partitioning of s. For example, given s = "aab", Return [ ["aa","b"], ["a","a","b"] ] Solution: ... */ class Solution { public: vector> partition(string s) { return partition_2(s); } vector> partition_2(string s) { int size = s.size(); vector > dp(size, vector(size)); for (int i = size - 1; i >= 0; --i) { for (int j = i; j < size; ++j) { dp[i][j]=(s[i]==s[j])&&(j > res[size]; for (int i = size - 1; i >= 0; --i) { for (int j = i; j < size; ++j) { if (dp[i][j] == false) continue; string word = s.substr(i, j - i + 1); if (j == size - 1) { res[i].push_back(vector{word}); } else { for (auto iter : res[j+1]) { iter.insert(iter.begin(), word); res[i].push_back(iter); } } } } return res[0]; } vector> partition_1(string s) { int size = s.size(); vector > dp(size, vector(size)); for (int i = size - 1; i >= 0; --i) { for (int j = i; j < size; ++j) { dp[i][j]=(s[i]==s[j])&&(j > res; vector path; dfs(s, dp, 0, path, res); return res; } void dfs(string s, vector > &dp, int start, vector &path, vector > &res) { int size = s.size(); if (start == size) { res.push_back(path); } for (int i = start; i < size; ++i) { if (dp[start][i] == false) { continue; } path.push_back(s.substr(start, i - start + 1)); dfs(s, dp, i + 1, path, res); path.pop_back(); } } }; ================================================ FILE: PalindromePartitioningII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 23, 2013 Update: Sep 23, 2013 Problem: Palindrome Partitioning II Difficulty: Hard Source: http://leetcode.com/onlinejudge#question_132 Notes: Given a string s, partition s such that every substring of the partition is a palindrome. Return the minimum cuts needed for a palindrome partitioning of s. For example, given s = "aab", Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut. Solution: dp. Contributed by 孙冕. Great job:) */ class Solution { public: int minCut(string s) { int size = s.size(); vector dp(size + 1); vector isP(size, true); dp[size] = -1; for (int i = size -1; i >= 0; --i) { dp[i] = dp[i + 1] + 1; for (int j = size - 1; j >= i; --j) { isP[j] = false; if (s[i] == s[j] && ( j - i < 2 || isP[j-1])) { isP[j] = true; dp[i] = min(dp[i], dp[j + 1] + 1); } } } return dp[0]; } }; ================================================ FILE: PartitionList.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Apr 9, 2013 Update: Oct 7, 2014 Problem: Partition List Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_86 Notes: Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x. You should preserve the original relative order of the nodes in each of the two partitions. For example, Given 1->4->3->2->5->2 and x = 3, return 1->2->2->4->3->5. Solution: ... */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *partition(ListNode *head, int x) { ListNode leftdummy(-1); ListNode rightdummy(-1); ListNode * lhead = &leftdummy; ListNode * rhead = &rightdummy; for(ListNode*cur = head; cur; cur=cur->next){ if(cur->valnext = cur; lhead = lhead->next; }else{ rhead->next = cur; rhead = rhead->next; } } lhead->next = rightdummy.next; rhead->next = nullptr; return leftdummy.next; } ListNode *partition_1(ListNode *head, int x) { ListNode dummy(0), *ins = &dummy, *cur = &dummy; dummy.next = head; while (cur->next) { if (cur->next->val >= x) { cur = cur->next; } else { if (cur == ins) { cur = cur->next; ins = ins->next; } else { ListNode *move = cur->next; cur->next = move->next; move->next = ins->next; ins->next = move; ins = move; } } } return dummy.next; } }; ================================================ FILE: Pascal'sTriangle.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 16, 2013 Problem: Pascal's Triangle Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_118 Notes: Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, Return [ [1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1] ] Solution: ..... */ class Solution { public: vector > generate(int numRows) { vector > res(numRows); if (numRows < 1) return res; res[0].push_back(1); for (int i = 1; i < numRows; ++i) { res[i].push_back(1); for (int j = 1; j < i; ++j) res[i].push_back(res[i-1][j-1] + res[i-1][j]); res[i].push_back(1); } return res; } }; ================================================ FILE: Pascal'sTriangleII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 16, 2013 Problem: Pascal's Triangle II Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_119 Notes: Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3, Return [1,3,3,1]. Note: Could you optimize your algorithm to use only O(k) extra space? Solution: from back to forth... */ class Solution { public: vector getRow(int rowIndex) { vector res(rowIndex+1, 1); for (int i = 1; i <= rowIndex; ++i) for (int j = i-1; j >= 1; --j) res[j] += res[j-1]; return res; } }; ================================================ FILE: PathSum.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 6, 2013 Update: Jul 26, 2013 Problem: Path Sum Difficulty: easy Source: http://www.leetcode.com/onlinejudge Notes: Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. For example: Given the below binary tree and sum = 22, 5 / \ 4 8 / / \ 11 13 4 / \ \ 7 2 1 return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22. Solution: Recursion. */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: bool hasPathSum(TreeNode *root, int sum) { if (!root) return false; if (!root->left and !root->right) return sum == root->val; return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val); } }; ================================================ FILE: PathSum2.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Apr 6, 2013 Update: Oct 7, 2014 Problem: Path Sum 2 Difficulty: easy Source: http://leetcode.com/onlinejudge#question_113 Notes: Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum. For example: Given the below binary tree and sum = 22, 5 / \ 4 8 / / \ 11 13 4 / \ / \ 7 2 5 1 return [ [5,4,11,2], [5,8,4,5] ] Solution: DFS. */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector > pathSum(TreeNode *root, int sum) { vector> res; vector path; pathSumRe(root, sum, res, path); return res; } void pathSumRe(TreeNode *root, int sum, vector> &res, vector &path) { if (!root) return; path.push_back(root->val); if (!root->left && !root->right && root->val == sum) { res.push_back(path); } pathSumRe(root->left, sum - root->val, res, path); pathSumRe(root->right, sum - root->val, res, path); path.pop_back(); } }; ================================================ FILE: PermutationSequence.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 8, 2013 Update: Aug 12, 2013 Problem: Permutation Sequence Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_60 Notes: The set [1,2,3,...,n] contains a total of n! unique permutations. By listing and labeling all of the permutations in order, We get the following sequence (ie, for n = 3): "123" "132" "213" "231" "312" "321" Given n and k, return the kth permutation sequence. Note: Given n will be between 1 and 9 inclusive. Solution: ... */ class Solution { public: string getPermutation(int n, int k) { string num, res; int total = 1; for (int i = 1; i <= n; ++i) { num.push_back(i + '0'); total *= i; } k--; while (n) { total /= n; int i = k / total; k %= total; res.push_back(num[i]); num.erase(i, 1); n--; } return res; } }; ================================================ FILE: Permutations.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 29, 2013 Update: Jul 19, 2013 Problem: Permutations Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_46 Notes: Given a collection of numbers, return all possible permutations. For example, [1,2,3] have the following permutations: [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1]. Solution: dfs... */ class Solution { public: vector> res; vector> permute(vector &num) { res.clear(); vector avail(num.size(), true); vector pum; permuteRe(num, avail, pum); return res; } void permuteRe(const vector &num, vector &avail, vector &pum) { if (pum.size() == num.size()) { res.push_back(pum); return; } for (int i = 0; i < num.size(); ++i) { if (avail[i]) { avail[i] = false; pum.push_back(num[i]); permuteRe(num, avail, pum); pum.pop_back(); avail[i] = true; } } } }; ================================================ FILE: PermutationsII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 29, 2013 Update: Sep 2, 2013 Problem: Permutations II Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_47 Notes: Given a collection of numbers that might contain duplicates, return all possible unique permutations. For example, [1,1,2] have the following unique permutations: [1,1,2], [1,2,1], and [2,1,1]. Solution: dfs... */ class Solution { public: vector> res; vector> permuteUnique(vector &num) { res.clear(); sort(num.begin(), num.end()); bool avail[num.size()]; memset(avail, true, sizeof(avail)); vector pum; permuteUniqueRe(num, pum, avail); return res; } void permuteUniqueRe(vector &num, vector &pum, bool avail[]) { if (pum.size() == num.size()) { res.push_back(pum); return; } int last_index = -1; for (int i = 0; i < num.size(); ++i) { if (!avail[i]) continue; if (last_index != -1 && num[i] == num[last_index]) continue; avail[i] = false; pum.push_back(num[i]); permuteUniqueRe(num, pum, avail); pum.pop_back(); avail[i] = true; last_index = i; } } }; ================================================ FILE: PlusOne.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 9, 2013 Update: Aug 29, 2013 Problem: Plus One Difficulty: Easy Source: https://oj.leetcode.com/problems/plus-one/ Notes: Given a number represented as an array of digits, plus one to the number. Solution: ... */ class Solution { public: vector plusOne(vector &digits) { int carry = 1, N = digits.size(); for (int i = N-1; i >= 0 && carry; --i) { int sum = carry + digits[i]; carry = sum / 10; digits[i] = sum % 10; } if (carry > 0) { digits.insert(digits.begin(), carry); } return digits; } }; ================================================ FILE: PopulatingNextRightPointersinEachNode.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Apr 22, 2013 Update: Oct 7, 2014 Problem: Populating Next Right Pointers in Each Node Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_116 Notes: Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; } Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL. Initially, all next pointers are set to NULL. Note: You may only use constant extra space. You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children). For example, Given the following perfect binary tree, 1 / \ 2 3 / \ / \ 4 5 6 7 After calling your function, the tree should look like: 1 -> NULL / \ 2 -> 3 -> NULL / \ / \ 4->5->6->7 -> NULL Solution: 1. Iterative: Two 'while' loops. 2. Iterative: Queue. Use extra space. 3. Recursive: DFS. Defect: Use extra stack space for recursion. */ /** * Definition for binary tree with next pointer. * struct TreeLinkNode { * int val; * TreeLinkNode *left, *right, *next; * TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {} * }; */ class Solution { public: void connect(TreeLinkNode *root) { connect_2(root); } void connect_1(TreeLinkNode *root) { if (root == nullptr) return; TreeLinkNode *cur = root; TreeLinkNode dummy(-1); TreeLinkNode *pre = &dummy; while (cur) { pre = &dummy; pre->next = nullptr; while (cur) { if (cur->left) { pre->next = cur->left; pre = pre->next; } if (cur->right) { pre->next = cur->right; pre = pre->next; } cur = cur->next; } cur = dummy.next; } } void connect_2(TreeLinkNode *root) { if (root == NULL) return; queue q; q.push(root); q.push(NULL); TreeLinkNode *last = NULL; TreeLinkNode dummy(-1); TreeLinkNode *pre = &dummy; while (!q.empty()) { TreeLinkNode *node = q.front(); q.pop(); if (node == NULL) { if (dummy.next) q.push(NULL); pre = &dummy; pre->next = NULL; } else { pre->next = node; pre = pre->next; if (node->left) q.push(node->left); if (node->right) q.push(node->right); } } } void connect_3(TreeLinkNode *root) { if (root == nullptr) return; TreeLinkNode dummy(-1); TreeLinkNode *pre = &dummy; TreeLinkNode *cur = root; while (cur) { if (cur->left) { pre->next = cur->left; pre = pre->next; } if (cur->right) { pre->next = cur->right; pre = pre->next; } cur = cur->next; } connect(dummy.next); } }; ================================================ FILE: PopulatingNextRightPointersinEachNodeII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Apr 23, 2013 Update: Oct 7, 2014 Problem: Populating Next Right Pointers in Each Node II Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_117 Notes: Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tree could be any binary tree? Would your previous solution still work? Note: You may only use constant extra space. For example, Given the following binary tree, 1 / \ 2 3 / \ \ 4 5 7 After calling your function, the tree should look like: 1 -> NULL / \ 2 -> 3 -> NULL / \ \ 4-> 5 -> 7 -> NULL Solution: 1. iterative way with CONSTANT extra space. 2. iterative way + queue. Contributed by SUN Mian(孙冕). 3. recursive solution. */ /** * Definition for binary tree with next pointer. * struct TreeLinkNode { * int val; * TreeLinkNode *left, *right, *next; * TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {} * }; */ class Solution { public: void connect(TreeLinkNode *root) { connect_2(root); } void connect_1(TreeLinkNode *root) { if (root == nullptr) return; TreeLinkNode *cur = root; TreeLinkNode dummy(-1); TreeLinkNode *pre = &dummy; while (cur) { pre = &dummy; pre->next = nullptr; while (cur) { if (cur->left) { pre->next = cur->left; pre = pre->next; } if (cur->right) { pre->next = cur->right; pre = pre->next; } cur = cur->next; } cur = dummy.next; } } void connect_2(TreeLinkNode *root) { if (root == NULL) return; queue q; q.push(root); q.push(NULL); TreeLinkNode *last = NULL; TreeLinkNode dummy(-1); TreeLinkNode *pre = &dummy; while (!q.empty()) { TreeLinkNode *node = q.front(); q.pop(); if (node == NULL) { if (dummy.next) q.push(NULL); pre = &dummy; pre->next = NULL; } else { pre->next = node; pre = pre->next; if (node->left) q.push(node->left); if (node->right) q.push(node->right); } } } void connect_3(TreeLinkNode *root) { if (root == nullptr) return; TreeLinkNode dummy(-1); TreeLinkNode *pre = &dummy; TreeLinkNode *cur = root; while (cur) { if (cur->left) { pre->next = cur->left; pre = pre->next; } if (cur->right) { pre->next = cur->right; pre = pre->next; } cur = cur->next; } connect(dummy.next); } }; ================================================ FILE: Pow(x,n).h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 6, 2013 Update: Jul 15, 2013 Problem: Pow(x, n) Difficulty: easy Source: http://leetcode.com/onlinejudge#question_50 Notes: Implement pow(x, n). Solution: recursion. */ class Solution { public: double pow(double x, int n) { if (x < 0) return (n % 2 == 0) ? pow(-x, n) : -pow(-x, n); if (x == 0 || x == 1) return x; if (n < 0) return 1.0 / pow(x, -n); if (n == 0) return 1.0; double half = pow(x, n / 2); if (n % 2 == 0) return half * half; else return x * half * half; } }; ================================================ FILE: README.md ================================================ # LeetCode Solve problems from [Leetcode](http://oj.leetcode.com/). All the codes are tested using online-judge. Here is a [difficulty and frequency distribution chart](http://wwwx.cs.unc.edu/~zhew/Leetcoder/) for each problem, which I got from the Internet and is very useful. Feel free to make pull request for adding the [difficulty and frequency for new problems here](https://github.com/leetcoders/Leetcoder). Please feel free to let me know if you have any problem or better solutions:) **Note**: The problem link in the file will take you to the Old OJ, which will expire on October 12, 12pm PST.
You may use [this link](http://oj.leetcode.com/) to the new OJ instead! ================================================ FILE: RecoverBinarySearchTree.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Jun 15, 2013 Problem: Recover Binary Search Tree Difficulty: High Source: http://leetcode.com/onlinejudge#question_99 Notes: Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure. Note: A solution using O(n) space is pretty straight forward. Could you devise a constant space solution? Solution: 1. recursive solution. O(n) space. get inorder list first. 2. recursive solution. O(n) space. with only auxiliary two pointers. 3. Morris inorder traversal. O(1) space. with only auxiliary two pointers. */ struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; class Solution { public: // first solution void recoverTree_1(TreeNode *root) { vector inorder; inorderTraversal(root, inorder); TreeNode *first = NULL, *second = NULL; for (int i = 1; i < inorder.size(); ++i) { if (inorder[i-1]->val < inorder[i]->val) continue; if (!first) first = inorder[i-1]; second = inorder[i]; } swap(first->val, second->val); } void inorderTraversal(TreeNode *root, vector &inorder) { if (!root) return; inorderTraversal(root->left, inorder); inorder.push_back(root); inorderTraversal(root->right, inorder); } // second solution void recoverTree_2(TreeNode *root) { TreeNode *prev = NULL, *first = NULL, *second = NULL; recoverTreeRe(root, prev, first, second); swap(first->val, second->val); } void recoverTreeRe(TreeNode *curNode, TreeNode *&preNode, TreeNode *&first, TreeNode *&second) { if (curNode == NULL) return; recoverTreeRe(curNode->left, preNode, first, second); if (preNode && preNode->val > curNode->val) { if (first == NULL) first = preNode; second = curNode; } preNode = curNode; recoverTreeRe(curNode->right, preNode, first, second); } // third solution void recoverTree_3(TreeNode *root) { TreeNode *cur = root, *prev = NULL; TreeNode *first = NULL, *second = NULL, *last = NULL; while (cur != NULL) { if (cur->left == NULL) { compare(last, cur, first, second); last = cur; cur = cur->right; } else { prev = cur->left; while (prev->right != NULL && prev->right != cur) prev = prev->right; if (prev->right == NULL) { prev->right = cur; cur = cur->left; } else { compare(last, cur, first, second); last = cur; prev->right = NULL; cur = cur->right; } } } swap(first->val, second->val); } void compare(TreeNode *last, TreeNode *cur, TreeNode *&first, TreeNode *&second) { if (last && last->val > cur->val) { if (!first) first = last; second = cur; } } }; ================================================ FILE: RegularExpressionMatching.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Co-author: King, higuige@gmail.com Date: May 26, 2013 Update: Oct 26, 2014 Problem: Regular Expression Matching Difficulty: Hard Source: http://leetcode.com/onlinejudge#question_10 Notes: Implement regular expression matching with support for '.' and '*'. '.' Matches any single character. '*' Matches zero or more of the preceding element. The matching should cover the entire input string (not partial). The function prototype should be: bool isMatch(const char *s, const char *p) Some examples: isMatch("aa","a") ? false isMatch("aa","aa") ? true isMatch("aaa","aa") ? false isMatch("aa", "a*") ? true isMatch("aa", ".*") ? true isMatch("ab", ".*") ? true isMatch("aab", "c*a*b") ? true Solution: Both of the two solutions are from http://leetcode.com/2011/09/regular-expression-matching.html . Solution 3: DP. Solution 4: DP. O(n^2) Time, O(n) Space. */ class Solution { public: bool isMatch(const char *s, const char *p) { if (*p == '\0') return *s == '\0'; if (*(p+1) == '*') // next is '*' { while ((*s == *p || *p == '.') && *s != '\0') { if (isMatch(s, p+2)) return true; s++; } return isMatch(s, p+2); } if (*s == '\0') return false; return (*s == *p || *p == '.') && isMatch(s+1, p+1); } bool isMatch_2(const char *s, const char *p) { if (*p == '\0') return *s == '\0'; if ((*s != '\0') && (*s == *p || *p =='.')) { if (*(p+1) == '*') { return isMatch(s+1,p) || isMatch(s, p+2); } else return isMatch(s+1, p+1); } return *(p+1) == '*' && isMatch(s, p+2); } bool isMatch_3(const char *s, const char *p) { int l1 = strlen(s), l2 = strlen(p), k; char ch1, ch2; vector > f(l1 + 1, vector(l2 + 1,false)); f[0][0] = true; for (int i = 2; i <= l2; i ++) if (*(p + i - 1) == '*') f[0][i] = f[0][i - 2]; for (int i = 1; i <= l1; i ++) for (int j = 1; j <= l2; j ++) { ch1 = *(s + i - 1); ch2 = *(p + j - 1); if (ch2 != '*') f[i][j] = f[i - 1][j - 1] && (ch1 == ch2 || ch2 == '.'); else { f[i][j] = f[i][j - 2]; if (*(s + i - 1) == *(p + j - 2) || *(p + j - 2) == '.') f[i][j] = f[i][j] | f[i - 1][j]; } } return f[l1][l2]; } bool isMatch_4(const char *s, const char *p) { int l1 = strlen(s), l2 = strlen(p), k; char ch1, ch2; vector > f(2, vector(l2 + 1,false)); f[0][0] = true; for (int i = 2; i <= l2; i ++) if (*(p + i - 1) == '*') f[0][i] = f[0][i - 2]; for (int i = 1; i <= l1; i ++){ for (int j = 1; j <= l2; j ++) { ch1 = *(s + i - 1); ch2 = *(p + j - 1); if (ch2 != '*') f[1][j] = f[0][j - 1] && (ch1 == ch2 || ch2 == '.'); else { f[1][j] = f[1][j - 2]; if (*(s + i - 1) == *(p + j - 2) || *(p + j - 2) == '.') f[1][j] = f[1][j] | f[0][j]; } } f[0] = f[1]; } return f[0][l2]; } }; ================================================ FILE: RemoveDuplicatesfromSortedArray.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 10, 2013 Update: Jul 16, 2013 Problem: Remove Duplicates from Sorted Array Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_26 Notes: Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. Do not allocate extra space for another array, you must do this in place with constant memory. For example, Given input array A = [1,1,2], Your function should return length = 2, and A is now [1,2]. Solution: Update 7/16/2013: Let j start from 0 for better understanding. */ class Solution { public: int removeDuplicates(int A[], int n) { int j = 0; for (int i = 0; i < n; ++i) if (i == 0 || A[i] != A[i-1]) A[j++] = A[i]; return j; } }; ================================================ FILE: RemoveDuplicatesfromSortedArrayII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 10, 2013 Update: Jul 16, 2013 [Two pointers ('last' and 'lastlast').] Problem: Remove Duplicates from Sorted Array II Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_80 Notes: Follow up for "Remove Duplicates": What if duplicates are allowed at most twice? For example, Given sorted array A = [1,1,1,2,2,3], Your function should return length = 5, and A is now [1,1,2,2,3]. Solution: ... */ class Solution { public: int removeDuplicates(int A[], int n) { if (n <= 2) return n; int j = 2; for (int i = 2; i < n; ++i) if (A[i] != A[j-2]) A[j++] = A[i]; return j; } }; ================================================ FILE: RemoveDuplicatesfromSortedList.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 10, 2013 Update: Jul 17, 2013 (Add solution 2) Problem: Remove Duplicates from Sorted List Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_83 Notes: Given a sorted linked list, delete all duplicates such that each element appear only once. For example, Given 1->1->2, return 1->2. Given 1->1->2->3->3, return 1->2->3. Solution: 1. Delete duplicates directly. 2. Copy value first (like Remove Duplicates from Array) and then delete the remaining elements. */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *deleteDuplicates(ListNode *head) { return deleteDuplicates_1(head); } ListNode *deleteDuplicates_1(ListNode *head) { if (!head) return head; ListNode *cur = head; while (cur->next) { if (cur->val == cur->next->val) { ListNode *del = cur->next; cur->next = del->next; delete del; } else { cur = cur->next; } } return head; } ListNode *deleteDuplicates_2(ListNode *head) { if (!head) return head; ListNode *last = head, *cur = head->next; while (cur) { if (last->val != cur->val) { last = last->next; last->val = cur->val; } cur = cur->next; } cur = last->next; while (cur) { ListNode *del = cur; cur = cur->next; delete del; } last->next = NULL; return head; } }; ================================================ FILE: RemoveDuplicatesfromSortedListII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 10, 2013 Update: Dec 12, 2014 Problem: Remove Duplicates from Sorted List II Difficulty: Easy Source: https://oj.leetcode.com/problems/remove-duplicates-from-sorted-list-ii/ Notes: Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. For example, Given 1->2->3->3->4->4->5, return 1->2->5. Given 1->1->1->2->3, return 2->3. Solution: 1. iterative 2. recursive */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *deleteDuplicates(ListNode *head) { return deleteDuplicates_1(head); } ListNode *deleteDuplicates_1(ListNode *head) { if(NULL==head||NULL==head->next) return head; ListNode dummy(-1); ListNode * pre = &dummy; while(head!=NULL){ if(head->next&&head->val==head->next->val){ while(head->next&&head->val==head->next->val) { ListNode *del = head; head = head->next; delete del; } }else{ pre->next = head; pre = pre->next; } head = head->next; } pre->next = NULL; return dummy.next; } ListNode *deleteDuplicates_2(ListNode *head) { if (!head) return NULL; if (!head->next || head->val != head->next->val) { head->next = deleteDuplicates(head->next); return head; } int val = head->val; while(head->next&&head->val==head->next->val) { ListNode *del = head; head = head->next; delete del; } return deleteDuplicates(head->next); } }; ================================================ FILE: RemoveElement.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 10, 2013 Update: Jul 20, 2013 Problem: Remove Element Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_27 Notes: Given an array and a value, remove all instances of that value in place and return the new length. The order of elements can be changed. It doesn't matter what you leave beyond the new length. Solution: Refactor: Update solution. Use two pointers. */ class Solution { public: int removeElement(int A[], int n, int elem) { int i = 0; for (int j = 0; j < n; ++j) if (A[j] != elem) A[i++] = A[j]; return i; } }; ================================================ FILE: RemoveNthNodeFromEndofList.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 10, 2013 Update: Sep 27, 2013 Problem: Remove Nth Node From End of List Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_19 Notes: Given a linked list, remove the nth node from the end of list and return its head. For example, Given linked list: 1->2->3->4->5, and n = 2. After removing the second node from the end, the linked list becomes 1->2->3->5. Note: Given n will always be valid. Try to do this in one pass. Solution: head---back------front------>NULL | | ---> n <---- */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *removeNthFromEnd(ListNode *head, int n) { ListNode dummy(0), *back = &dummy, *front = &dummy; dummy.next = head; while (n--) front = front->next; while (front->next) { front = front->next; back = back->next; } ListNode *del = back->next; back->next = del->next; delete del; return dummy.next; } ListNode *removeNthFromEnd_2(ListNode *head, int n) { if(head==NULL) return head; ListNode *slow = head, *fast = head; while(n--) fast = fast->next; if (fast == NULL) return head->next; while(fast->next) { fast = fast->next; slow = slow->next; } slow->next = slow->next->next; return head; } }; ================================================ FILE: ReorderList.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Nov 11, 2013 Problem: Reorder List Difficulty: Easy Source: http://oj.leetcode.com/problems/reorder-list/ Notes: Given a singly linked list L: L0->L1->...->Ln-1->Ln, reorder it to: L0->Ln->L1->Ln-1->L2->Ln-2->... You must do this in-place without altering the nodes' values. For example, Given {1,2,3,4}, reorder it to {1,4,2,3}. Solution: Reverse the back half first, then reorder. */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: void reorderList(ListNode *head) { if (!head || !head->next) return; ListNode *slow = head, *fast = head->next->next; while (fast && fast->next) { fast = fast->next->next; slow = slow->next; } if (fast) slow = slow->next; ListNode *mid = slow, *cur = slow->next; while (cur->next) { ListNode *mov = cur->next; cur->next = mov->next; mov->next = mid->next; mid->next = mov; } cur = head; while (cur != mid && mid->next) { ListNode *mov = mid->next; mid->next = mov->next; mov->next = cur->next; cur->next = mov; cur = cur->next->next; } } }; ================================================ FILE: RepeatedDNASequences.h ================================================ /* Author: Andy, nkuwjg@gmail.com Date: Feb 3, 2015 Problem: Repeated DNA Sequences Difficulty: Easy Source: https://oj.leetcode.com/problems/repeated-dna-sequences/ Notes: All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA. Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule. For example, Given s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT", Return: ["AAAAACCCCC", "CCCCCAAAAA"]. Solution: ... */ class Solution { public: vector findRepeatedDnaSequences(string s) { vector res; map m; map mole; mole['A'] = 0; mole['C'] = 1; mole['G'] = 2; mole['T'] = 3; if (s.length() < 11) return res; int x = 0, i = 0, mask = (1<<20) - 1; for (; i < 10; ++i) { x = (x<<2) | mole[s[i]]; } m[x] = 1; for (; i < s.length(); ++i) { x = mask & ((x<<2) | mole[s[i]]); if (++m[x] == 2) { res.push_back(convert2Str(x)); } } return res; } string convert2Str(int x) { string res; for (int i = 0; i < 10; ++i) { int k = x & 3; if (k == 0) res = 'A' + res; if (k == 1) res = 'C' + res; if (k == 2) res = 'G' + res; if (k == 3) res = 'T' + res; x = x >> 2; } return res; } }; ================================================ FILE: RestoreIPAddresses.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 1, 2013 Update: Jul 26, 2013 Problem: Restore IP Addresses Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_93 Notes: Given a string containing only digits, restore it by returning all possible valid IP address combinations. For example: Given "25525511135", return ["255.255.11.135", "255.255.111.35"]. (Order does not matter) Solution: DFS. */ class Solution { public: vector restoreIpAddresses(string s) { vector res; string ip; restoreIpAddressRe(s, res, ip, 0, 0); return res; } void restoreIpAddressRe(string &s, vector &res, string &ip, int deep, int start) { if (deep == 4 && start == s.size()) res.push_back(ip); if (deep == 4) return; int num = 0, origSize = ip.size(); if (origSize != 0) ip.push_back('.'); for (int i = start; i < s.size(); ++i) { num = num * 10 + s[i] - '0'; if (num > 255) break; ip.push_back(s[i]); restoreIpAddressRe(s, res, ip, deep + 1, i + 1); if (num == 0) break; } ip.resize(origSize); } }; ================================================ FILE: ReverseInteger.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 7, 2013 Update: Dec 14, 2014 (By wangjingui@outlook.com) Problem: Reverse Integer Difficulty: Easy Source: https://oj.leetcode.com/problems/reverse-integer/ Notes: Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, return -321 Have you thought about this? Here are some good questions to ask before coding. Bonus points for you if you have already thought through this! If the integer's last digit is 0, what should the output be? ie, cases such as 10, 100. Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, then the reverse of 1000000003 overflows. How should you handle such cases? Throw an exception? Good, but what if throwing an exception is not an option? You would then have to re-design the function (ie, add an extra parameter). Solution: Use % and / iteratively. */ class Solution { public: int reverse(int x) { long long res = 0; while (x) { res = res * 10 + (x % 10); x /= 10; } if (res < INT_MIN || res > INT_MAX) return 0; return res; } }; ================================================ FILE: ReverseLinkedListII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 9, 2013 Update: Jul 28, 2013 Problem: Reverse Linked List II Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_92 Notes: Reverse a linked list from position m to n. Do it in-place and in one-pass. For example: Given 1->2->3->4->5->NULL, m = 2 and n = 4, return 1->4->3->2->5->NULL. Note: Given m, n satisfy the following condition: 1 <= m <= n <= length of list. Solution: in-place & one-pass. */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *reverseBetween(ListNode *head, int m, int n) { ListNode dummy(0), *ins = &dummy; dummy.next = head; for (int i = 0; i < m-1; ++i) ins = ins->next; ListNode *cur = ins->next; for (int i = 0; i < n-m; ++i) { ListNode *move = cur->next; cur->next = move->next; move->next = ins->next; ins->next = move; } return dummy.next; } }; ================================================ FILE: ReverseNodesinkGroup.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 18, 2013 Update: Jul 20, 2013 Problem: Reverse Nodes in k-Group Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_25 Notes: Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is. You may not alter the values in the nodes, only nodes itself may be changed. Only constant memory is allowed. For example, Given this linked list: 1->2->3->4->5 For k = 2, you should return: 2->1->4->3->5 For k = 3, you should return: 3->2->1->4->5 Solution: ... */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *reverseKGroup(ListNode *head, int k) { if (k <= 1) return head; int reverseTimes = GetLength(head) / k; ListNode dummy(0); dummy.next = head; ListNode *ins = &dummy, *cur = ins->next; while (reverseTimes--) { for (int i = 0; i < k - 1; ++i) { ListNode *move = cur->next; cur->next = move->next; move->next = ins->next; ins->next = move; } ins = cur; cur = ins->next; } return dummy.next; } int GetLength(ListNode *head) { int length = 0; while (head) { head = head->next; length++; } return length; } }; ================================================ FILE: ReverseWordsInAString.h ================================================ /* Author: King, wangjingui@outlook.com Date: Dec 13, 2014 Problem: Reverse Words in a String Difficulty: Easy Source: https://oj.leetcode.com/problems/reverse-words-in-a-string/ Notes: Given an input string, reverse the string word by word. For example, Given s = "the sky is blue", return "blue is sky the". Solution: 1. Reverse the raw string and reverse each word. 2. In Place. */ class Solution { public: void reverseWords_1(string &s) { string res; reverse(s.begin(),s.end()); for (int i = 0; i < s.size(); ++i) { while (i < s.size() && s[i] == ' ') ++i; if(i == s.size()) break; string tmp; while(i < s.size() && s[i] != ' ') tmp.push_back(s[i++]); reverse(tmp.begin(), tmp.end()); if (!res.empty()) res = res + " " + tmp; else res = res + tmp; } s = res; } void reverseWords_2(string &s) { int N = s.size(); reverse(s.begin(),s.end()); for (string::iterator i = s.begin(); i != s.end();) { while (i != s.end() && *i == ' ') ++i; string::iterator left = i; while((i) != s.end() && *(i) != ' ') ++i; reverse(left,i); } int idx = 0; for (int i = 0; i < N;) { while (i < N && s[i] == ' ') ++i; while (i < N && s[i] != ' ') s[idx++] = s[i++]; while (i < N && s[i] == ' ') ++i; if (i == N) break; s[idx++] = ' '; } s.resize(idx); } }; ================================================ FILE: RomantoInteger.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 13, 2013 Update: Sep 22, 2013 Problem: Roman to Integer Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_13 Notes: Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999. Solution: use or (clean) */ class Solution { public: int romanToInt(string s) { unordered_map roman; roman['M'] = 1000; roman['D'] = 500; roman['C'] = 100; roman['L'] = 50; roman['X'] = 10; roman['V'] = 5; roman['I'] = 1; int res = 0, N = s.size(); for (int i = 0; i < N; ++i) { if (i < N-1 && roman[s[i]] < roman[s[i+1]]) res -= roman[s[i]]; else res += roman[s[i]]; } return res; } }; ================================================ FILE: RotateImage.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 9, 2013 Update: Jul 21, 2013 (Add solution 2) Problem: Rotate Image Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_48 Notes: You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). Follow up: Could you do this in-place? Solution: 1. Rotate one-fourth of the image clockwise. 2. 123 -> 147 -> 741 (preferable) 456 258 852 789 369 963 */ class Solution { public: void rotate(vector > &matrix) { rotate_2(matrix); } void rotate_1(vector > &matrix) { int n = matrix.size(); for (int i = 0; i < (n + 1) / 2; i++) for (int j = 0; j < n / 2; j++) rotateElement(matrix, i, j); } void rotateElement(vector > &matrix, int row, int col) { int temp = matrix[row][col]; for (int i = 0; i < 3; i++) { int c = row; int r = matrix.size() - 1 - col; matrix[row][col] = matrix[r][c]; row = r; col = c; } matrix[row][col] = temp; } void rotate_2(vector > &matrix) { int N = matrix.size(); for (int i = 0; i < N; ++i) for (int j = i+1; j < N; ++j) swap(matrix[i][j], matrix[j][i]); for (int j = 0; j < N/2; ++j) for (int i = 0; i < N; ++i) swap(matrix[i][j], matrix[i][N-j-1]); } }; ================================================ FILE: RotateList.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 8, 2013 Problem: Rotate List Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_61 Notes: Given a list, rotate the list to the right by k places, where k is non-negative. For example: Given 1->2->3->4->5->NULL and k = 2, return 4->5->1->2->3->NULL. Solution: Notice that k can be larger than the list size (k % list_size). This solution traverses the list twice at most. */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *rotateRight(ListNode *head, int k) { if (!head) return NULL; ListNode* tail = head; int count = 1; while (tail->next) { tail = tail->next; count++; } k = k % count; // in case the list rotates more than one round. if (k == 0) return head; ListNode* cur = head; for (int i = 0; i < count - k - 1; i++) cur = cur->next; ListNode* newHead = cur->next; cur->next = NULL; tail->next = head; return newHead; } }; ================================================ FILE: SameTree.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 7, 2013 Problem: Same Tree Difficulty: easy Source: http://leetcode.com/onlinejudge#question_100 Notes: Given two binary trees, write a function to check if they are equal or not. Two binary trees are considered equal if they are structurally identical and the nodes have the same value. Solution: recursion. */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: bool isSameTree(TreeNode *p, TreeNode *q) { if (!p && !q) return true; if (p && !q || !p && q) return false; if (p->val != q->val) return false; return isSameTree(p->left, q->left) && isSameTree(p->right, q->right); } }; ================================================ FILE: ScrambleString.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Jul 12, 2013 Update: Sep 13, 2013 Problem: Scramble String Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_87 Notes: Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively. Below is one possible representation of s1 = "great": great / \ gr eat / \ / \ g r e at / \ a t To scramble the string, we may choose any non-leaf node and swap its two children. For example, if we choose the node "gr" and swap its two children, it produces a scrambled string "rgeat". rgeat / \ rg eat / \ / \ r g e at / \ a t We say that "rgeat" is a scrambled string of "great". Similarly, if we continue to swap the children of nodes "eat" and "at", it produces a scrambled string "rgtae". rgtae / \ rg tae / \ / \ r g ta e / \ t a We say that "rgtae" is a scrambled string of "great". Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1. Solution: 1. 3-dimensional dp. Contributed by yinlinglin. I really appreciate it! 'dp[k][i][j] == true' means string s1(start from i, length k) is a scrambled string of string s2(start from j, length k). 2. Recursion + pruning. */ class Solution { public: bool isScramble(string s1, string s2) { return isScramble_2(s1, s2); } // solution 1: dp. bool isScramble_1(string s1, string s2) { if(s1.size() != s2.size()) return false; int N = s1.size(); bool dp[N+1][N][N]; for (int k = 1; k <= N; ++k) for (int i = 0; i <= N-k; ++i) for (int j = 0; j <= N-k; ++j) { dp[k][i][j] = false; if (k == 1) dp[1][i][j] = (s1[i] == s2[j]); for (int p = 1; p < k && !dp[k][i][j]; ++p) if (dp[p][i][j] && dp[k-p][i+p][j+p] || dp[p][i][j+k-p] && dp[k-p][i+p][j]) dp[k][i][j] = true; } return dp[N][0][0]; } // solution 2: recursion + pruning. typedef string::iterator Iterator; bool isScramble_2(string s1, string s2) { if (s1.size() != s2.size()) return false; return isScrambleRe(s1.begin(), s2.begin(), s1.size()); } bool isScrambleRe(Iterator s1, Iterator s2, int len) { if (!hasSameLetters(s1, s2, len)) return false; if (len == 0 || len == 1) return true; for (int i = 1; i < len; ++i) // highlight if (isScrambleRe(s1, s2, i) && isScrambleRe(s1 + i, s2 + i, len - i) || isScrambleRe(s1, s2 + len - i, i) && isScrambleRe(s1 + i, s2, len - i)) return true; return false; } bool hasSameLetters(Iterator s1, Iterator s2, int len) { int count[256] = {0}; for (int i = 0; i < len; ++i) count[*s1++]++; for (int i = 0; i < len; ++i) count[*s2++]--; for (int i = 0; i < 256; ++i) if (count[i] != 0) return false; return true; } }; ================================================ FILE: SearchInsertPosition.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 18, 2013 Problem: Search Insert Position Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_35 Notes: Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. You may assume no duplicates in the array. Here are few examples. [1,3,5,6], 5 -> 2 [1,3,5,6], 2 -> 1 [1,3,5,6], 7 -> 4 [1,3,5,6], 0 -> 0 Solution: Binary search. */ class Solution { public: int searchInsert(int A[], int n, int target) { int i = 0, j = n - 1; while (i <= j) { int mid = (i + j) / 2; if (A[mid] == target) return mid; if (A[mid] < target) i = mid + 1; else j = mid - 1; } return i; } }; ================================================ FILE: Searcha2DMatrix.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 16, 2013 Update: Sep 27, 2013 Problem: Search a 2D Matrix Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_74 Notes: Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: Integers in each row are sorted from left to right. The first integer of each row is greater than the last integer of the previous row. For example, Consider the following matrix: [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] Given target = 3, return true. Solution: Binary-search. */ class Solution { public: bool searchMatrix(vector > &matrix, int target) { return searchMatrix_2(matrix, target); } // Solution 1. bool searchMatrix_1(vector > &matrix, int target) { if (matrix.empty() || matrix[0].empty()) return false; int N = matrix.size(), M = matrix[0].size(); int i = 0, j = N-1; while (i <= j) { int mid = (i + j) / 2; if (matrix[mid][0] == target) return true; else if (matrix[mid][0] < target) i++; else j--; } int row = j; if (row < 0) return false; i = 0, j = M - 1; while (i <= j) { int mid = (i + j) / 2; if (matrix[row][mid] == target) return true; else if (matrix[row][mid] < target) i++; else j--; } return false; } // Solution 2. bool searchMatrix_2(vector > &matrix, int target) { if (matrix.empty() || matrix[0].empty()) return false; int N = matrix.size(), M = matrix[0].size(); int i = 0, j = M * N - 1; while (i <= j) { int mid = (i + j) / 2; int row = mid / M, col = mid % M; if (matrix[row][col] == target) return true; else if (matrix[row][col] < target) i = mid + 1; else j = mid - 1; } return false; } }; ================================================ FILE: SearchforaRange.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 8, 2013 Problem: Search for a Range Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_34 Notes: Given a sorted array of integers, find the starting and ending position of a given target value. Your algorithm's runtime complexity must be in the order of O(log n). If the target is not found in the array, return [-1, -1]. For example, Given [5, 7, 7, 8, 8, 10] and target value 8, return [3, 4]. Solution: It takes O(lgN) to find both the lower-bound and upper-bound. */ class Solution { public: vector searchRange(int A[], int n, int target) { vector res(2, -1); int lower = getLowerBound(A, n, target); int upper = getUpperBound(A, n, target); if (lower <= upper) { res[0] = lower; res[1] = upper; } return res; } int getLowerBound(int A[], int n, int target) { int l = 0, u = n-1; while (l <= u) { int mid = (l + u) / 2; if (A[mid] < target) l = mid + 1; else u = mid - 1; } return l; } int getUpperBound(int A[], int n, int target) { int l = 0, u = n-1; while (l <= u) { int mid = (l + u) / 2; if (A[mid] <= target) l = mid + 1; else u = mid - 1; } return u; } }; ================================================ FILE: SearchinRotatedSortedArray.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 8, 2013 Update: Aug 7, 2013 Problem: Search in Rotated Sorted Array Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_33 Notes: Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). You are given a target value to search. If found in the array return its index, otherwise return -1. You may assume no duplicate exists in the array. Solution: Binary search. O(lgn) eg. [4 5 6] -7- 8 1 2, 5 6 0 -1- [2 3 4] */ class Solution { public: int search(int A[], int n, int target) { int i = 0, j = n - 1; while (i <= j) { int mid = (i + j) / 2; if (A[mid] == target) return mid; if (A[i] <= A[mid]) { if (A[i] <= target && target < A[mid]) j = mid - 1; else i = mid + 1; } else { if (A[mid] < target && target <= A[j]) i = mid + 1; else j = mid - 1; } } return -1; } }; ================================================ FILE: SearchinRotatedSortedArrayII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Apr 8, 2013 Update: Nov 18, 2014 Problem: Search in Rotated Sorted Array II Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_81 Notes: Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). What if duplicates are allowed? Would this affect the run-time complexity? How and why? Write a function to determine if a given target is in the array. Solution: Sequence search. O(n) Since there are duplicates, it's hard to decide which branch to go if binary-search is deployed. */ class Solution { public: bool search(int A[], int n, int target) { for (int i = 0; i < n; i++) if (A[i] == target) return true; return false; } bool search_2(int A[], int n, int target) { if (A == NULL) return -1; int left = 0, right = n - 1; while (left <= right) { int mid = (left + right) /2; if (A[mid] == target) return true; if (A[left] < A[mid]) { if (A[left] <= target && target < A[mid]) { right = mid - 1; } else { left = mid + 1; } } else if (A[left] > A[mid]) { if (A[mid] < target && target <= A[right]) { left = mid + 1; } else { right = mid - 1; } } else { if (A[mid] == A[right]) { ++left, --right; } else { left = mid + 1; } } } return false; } }; ================================================ FILE: SetMatrixZeroes.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 25, 2013 Update: Jul 23, 2013 Problem: Set Matrix Zeroes Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_73 Notes: Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. Follow up: Did you use extra space? A straight forward solution using O(mn) space is probably a bad idea. A simple improvement uses O(m + n) space, but still not the best solution. Could you devise a constant space solution? Solution: Use first row and column as auxiliary spaces instead of newly allocating ones. */ class Solution { public: void setZeroes(vector> &matrix) { if (matrix.empty()) return; int N = matrix.size(), M = matrix[0].size(); bool setFirstRowZero = false; bool setFirstColZero = false; for (int i = 0; i < N && !setFirstColZero; ++i) setFirstColZero = (matrix[i][0] == 0); for (int j = 0; j < M && !setFirstRowZero; ++j) setFirstRowZero = (matrix[0][j] == 0); for (int i = 1; i < N; ++i) for (int j = 1; j < M; ++j) if (matrix[i][j] == 0) { matrix[0][j] = 0; matrix[i][0] = 0; } for (int i = 1; i < N; ++i) if (matrix[i][0] == 0) for (int j = 1; j < M; ++j) matrix[i][j] = 0; for (int j = 1; j < M; ++j) if (matrix[0][j] == 0) for (int i = 1; i < N; ++i) matrix[i][j] = 0; if (setFirstRowZero) for (int j = 0; j < M; ++j) matrix[0][j] = 0; if (setFirstColZero) for (int i = 0; i < N; ++i) matrix[i][0] = 0; } }; ================================================ FILE: SimplifyPath.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 13, 2013 Update: Aug 11, 2013 Problem: Simplify Path Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_71 Notes: Given an absolute path for a file (Unix-style), simplify it. For example, path = "/home/", => "/home" path = "/a/./b/../../c/", => "/c" Corner Cases: Did you consider the case where path = "/../"? In this case, you should return "/". Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/". In this case, you should ignore redundant slashes and return "/home/foo". Solution: Add an additional '/' at the end of 'path' for simply detecting the end. */ class Solution { public: string simplifyPath(string path) { string res; path += "/"; size_t pos = path.find_first_of("/"), last = 0; while (pos != string::npos) { string s = path.substr(last, pos - last); if (s == "..") { if (!res.empty()) res.resize(res.find_last_of("/")); } else if (!s.empty() && s != ".") { res += "/"; res += s; } last = pos + 1; pos = path.find_first_of("/", last); } return res.empty() ? "/" : res; } }; ================================================ FILE: SingleNumber.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Oct 3, 2013 Problem: Single Number Difficulty: Easy Source: http://oj.leetcode.com/problems/single-number/ Notes: Given an array of integers, every element appears twice except for one. Find that single one. Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? Solution: XOR. */ class Solution { public: int singleNumber(int A[], int n) { if (n < 1) return 0; for (int i = 1; i < n; ++i) A[0] ^= A[i]; return A[0]; } }; ================================================ FILE: SingleNumberII.h ================================================ /* Author: King, higuige@gmail.com : Annie Kim, anniekim.pku@gmail.com Date: Oct 5, 2013 Update: Oct 5, 2014 Problem: Single Number II Difficulty: Easy Source: http://oj.leetcode.com/problems/single-number-ii/ Notes: Given an array of integers, every element appears three times except for one. Find that single one. Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? Solution: 1. Count the number of each bit. 2. We can improve this based on the previous solution using three bitmask variables. 3. An excellent answer by @ranmocy in LeetCode Discuss: https://oj.leetcode.com/discuss/857/constant-space-solution?show=2542#a2542 */ class Solution { public: int singleNumber(int A[], int n) { int count[32]={0}; int res = 0; for (int i = 0; i < 32; ++i) { for (int j = 0; j < n; ++j) { if ((A[j]>>i)&1) { ++count[i]; } } res|= ((count[i]%3)< -> <- */ class Solution { public: void sortColors(int A[], int n) { int zero = -1, two = n; int i = 0; while (i < two) { switch(A[i]) { case 0: swap(A[i++], A[++zero]); break; case 1: i++; break; case 2: swap(A[i], A[--two]); } } } }; ================================================ FILE: SortList.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Jan 8, 2014 Problem: Sort List Difficulty: Medium Source: http://oj.leetcode.com/problems/sort-list/ Notes: Sort a linked list in O(nlogn) time using constant space complexity. Solution: merge sort. */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *sortList(ListNode *head) { return sortLinkedList(head, getLength(head)); } ListNode* sortLinkedList(ListNode *&head, int N) { if (N == 0) return NULL; if (N == 1) { ListNode* cur = head; head = head->next; cur->next = NULL; return cur; } int half = N / 2; ListNode* head1 = sortLinkedList(head, half); ListNode* head2 = sortLinkedList(head, N - half); return mergeList(head1, head2); } ListNode* mergeList(ListNode *head1, ListNode*head2) { ListNode dummy(0); dummy.next = NULL; ListNode *cur = &dummy; while (head1 && head2) { ListNode **min = head1->val < head2->val ? &head1 : &head2; cur->next = *min; cur = cur->next; *min = (*min)->next; } if (!head1) cur->next = head2; if (!head2) cur->next = head1; return dummy.next; } int getLength(ListNode *head) { int length = 0; while (head) { length++; head = head->next; } return length; } }; ================================================ FILE: SpiralMatrix.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 13, 2013 Update: Sep 30, 2013 Problem: Spiral Matrix Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_54 Notes: Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order. For example, Given the following matrix: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] You should return [1,2,3,6,9,8,7,4,5]. Solution: ... */ class Solution { public: vector spiralOrder(vector > &matrix) { vector res; if (matrix.empty() || matrix[0].empty()) return res; int imin = 0, imax = matrix.size()-1; int jmin = 0, jmax = matrix[0].size()-1; while (true) { for (int j = jmin; j <= jmax; ++j) res.push_back(matrix[imin][j]); if (++imin > imax) break; for (int i = imin; i <= imax; ++i) res.push_back(matrix[i][jmax]); if (jmin > --jmax) break; for (int j = jmax; j >= jmin; --j) res.push_back(matrix[imax][j]); if (imin > --imax) break; for (int i = imax; i >= imin; --i) res.push_back(matrix[i][jmin]); if (++jmin > jmax) break; } return res; } }; ================================================ FILE: SpiralMatrixII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 13, 2013 Update: Aug 24, 2013 Problem: Spiral Matrix II Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_59 Notes: Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For example, Given n = 3, You should return the following matrix: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ] Solution: ... */ class Solution { public: vector > generateMatrix(int n) { if (n == 0) return vector >(); vector > res(n, vector(n)); int imin = 0, imax = n-1, jmin = 0, jmax = n-1; int number = 1; while (true) { for (int j = jmin; j <= jmax; ++j) res[imin][j] = number++; if (++imin > imax) break; for (int i = imin; i <= imax; ++i) res[i][jmax] = number++; if (jmin > --jmax) break; for (int j = jmax; j >= jmin; --j) res[imax][j] = number++; if (imin > --imax) break; for (int i = imax; i >= imin; --i) res[i][jmin] = number++; if (++jmin > jmax) break; } return res; } }; ================================================ FILE: Sqrt(x).h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 18, 2013 Problem: Sqrt(x) Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_69 Notes: Implement int sqrt(int x). Compute and return the square root of x. Solution: 1. Binary search in range [0, x / 2 + 1]. 2. Newton iteration method. x(i+1) = (x(i) + n/x(i)) / 2. See my blog (http://www.cnblogs.com/AnnieKim/archive/2013/04/18/3028607.html) for more explanation (in Chinese). */ class Solution { public: int sqrt_1(int x) { long long i = 0; long long j = x / 2 + 1; while (i <= j) { long long mid = (i + j) / 2; long long sq = mid * mid; if (sq == x) return mid; else if (sq < x) i = mid + 1; else j = mid - 1; } return j; } int sqrt_2(int x) { if (x == 0) return 0; double last = 0; double res = 1; while (res != last) { last = res; res = (res + x / res) / 2; } return int(res); } }; ================================================ FILE: StringtoInteger(atoi).h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 17, 2013 Update: Dec 14, 2014(By wangjingui@outlook.com) Problem: String to Integer (atoi) Difficulty: Easy Source: https://oj.leetcode.com/problems/string-to-integer-atoi/solution/ Notes: Implement atoi to convert a string to an integer. Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases. Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front. Requirements for atoi: The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value. The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function. If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed. If no valid conversion could be performed, a zero value is returned. If the correct value is out of the range of representable values, INT_MAX (2147483647) or INT_MIN (-2147483648) is returned. Solution: 1. use long type to store the result to deal with overflow. 2. To deal with overflow, inspect the current number before multiplication. If the current number is greater than 214748364, we know it is going to overflow. On the other hand, if the current number is equal to 214748364, we know that it will overflow only when the current digit is greater than or equal to 8.. */ class Solution { public: int atoi_1(const char *str) { if (!str) return 0; while (*str == ' ') str++; bool positive = true; if (*str == '+' || *str == '-') { positive = *str == '+'; str++; } long long res = 0; while (isdigit(*str)) { res = res * 10 + (*str - '0'); str++; } res = positive ? res : -res; if (res > INT_MAX) return INT_MAX; if (res < INT_MIN) return INT_MIN; return (int)res; } int atoi_2(const char *str) { if(str == NULL) return 0; int res = 0; bool sign = true; while(*str == ' ') str++; if(*str == '+' || *str == '-') { sign = *str == '+'; str++; } while(isdigit(*str)) { if(res > INT_MAX/10 || (res == INT_MAX / 10 && *str - '0' > INT_MAX % 10)){ return sign ? INT_MAX : INT_MIN; } res = res * 10 + *str - '0'; str++; } return sign ? res : -res; } }; ================================================ FILE: Subsets.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Apr 24, 2013 Update: Nov 18, 2014 Problem: Subsets Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_78 Notes: Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset must be in non-descending order. The solution set must not contain duplicate subsets. For example, If S = [1,2,3], a solution is: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ] Solution: 1. Recursive solution. 2. Iterative solution. Contributed by yinlinglin. 3. Updated Recursive solution. 4. Updated Iterative solution. */ class Solution { public: vector > subsets(vector &S) { return subsets_1(S); } vector > subsets_1(vector &S) { vector > res(1, vector()); sort(S.begin(), S.end()); vector set; int N = S.size(); for (int l = 1; l <= N; ++l) subsetsRe(S, l, 0, set, res); return res; } void subsetsRe(vector &S, int L, int start, vector &set, vector > &res) { int N = S.size(), M = set.size(); if (M == L) { res.push_back(set); return; } for (int i = start; i <= N - (L - M); ++i) { set.push_back(S[i]); subsetsRe(S, L, i + 1, set, res); set.pop_back(); } } vector > subsets_2(vector &S) { vector > res(1, vector()); sort(S.begin(), S.end()); int N = S.size(); for (int L = 1; L <= N; ++L) { int stk[L]; stk[0] = 0; int top = 0; while (true) { if (stk[top] == N) { top--; if (top < 0) break; stk[top]++; } else if (top == L - 1) { vector set; for (int i = 0; i < L; ++i) set.push_back(S[stk[i]]); res.push_back(set); stk[top]++; } else { top++; stk[top] = stk[top-1] + 1; } } } return res; } vector > subsets_3(vector &S) { int sz = S.size(); vector> res(1); sort(S.begin(), S.end()); for (int i = 0; i < S.size(); ++i) { int sz = res.size(); for (int j = 0; j < sz; ++j) { res.push_back(res[j]); res.back().push_back(S[i]); } } return res; } vector > subsets_4(vector &S) { vector> res; sort(S.begin(), S.end()); vector path; dfs(S,res,path,0); return res; } void dfs(vector &S, vector>& res, vector&path, size_t step) { res.push_back(path); for (int i = step; i < S.size(); ++i) { path.push_back(S[i]); dfs(S,res,path,i+1); path.pop_back(); } } }; ================================================ FILE: SubsetsII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Apr 30, 2013 Update: Nov 18, 2014 Problem: Subsets II Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_90 Notes: Given a collection of integers that might contain duplicates, S, return all possible subsets. Note: Elements in a subset must be in non-descending order. The solution set must not contain duplicate subsets. For example, If S = [1,2,2], a solution is: [ [2], [1], [1,2,2], [2,2], [1,2], [] ] Solution: ..Similar to Subset I. */ class Solution { public: vector > subsetsWithDup(vector &S) { vector> res; sort(S.begin(), S.end()); vector path; dfs(S,res,path,0); return res; } void dfs(vector &S, vector>& res, vector&path, size_t step) { res.push_back(path); for (int i = step; i < S.size(); ++i) { if(i!=step&&S[i]==S[i-1]) continue; path.push_back(S[i]); dfs(S,res,path,i+1); path.pop_back(); } } // Solution 2. iterative solution. vector > subsetsWithDup_2(vector &S) { vector > res(1); sort(S.begin(),S.end()); size_t presz = 0; for(int i=0;i= presz) { res.push_back(res[j]); res.back().push_back(S[i]); } } presz = sz; } return res; } }; ================================================ FILE: SubstringwithConcatenationofAllWords.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : Andy, nkuwjg@gmail.com Date: May 26, 2013 Update: Jan 15, 2015 Problem: Substring with Concatenation of All Words Difficulty: Easy Source: https://oj.leetcode.com/problems/substring-with-concatenation-of-all-words/ Notes: You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters. For example, given: S: "barfoothefoobarman" L: ["foo", "bar"] You should return the indices: [0,9]. (order does not matter). Solution: 1. Brute + HashMap. 2. Sliding Window + HashMap. */ class Solution { public: vector findSubstring_1(string S, vector &L) { vector res; if (S.empty() || L.empty()) return res; int M = S.size(), N = L.size(); int K = L[0].size(); unordered_map need; unordered_map found; for (int i = 0; i < N; ++i) need[L[i]]++; for (int i = 0; i <= M - N * K; ++i) { found.clear(); int j; for (j = 0; j < N; ++j) { string s = S.substr(i + j * K, K); auto it = need.find(s); if (it == need.end()) break; if (it->second <= found[s]) break; found[s]++; } if (j == N) res.push_back(i); } return res; } vector findSubstring(string S, vector &L) { vector res; if (S.empty() || L.empty()) return res; unordered_map need; for (int i = 0; i < L.size(); ++i) need[L[i]]++; int n = L[0].length(), m = L.size(); for (int i = 0; i < n; ++i) { unordered_map find; for (int start = i, end = i, count = 0; end + n <= S.length(); end += n) { string str = S.substr(end, n); auto it = need.find(str); if (it == need.end()) { start = end + n; find.clear(); count = 0; continue; } while (find.find(str) != find.end() && find[str] >= need[str]) { string subStart = S.substr(start, n); find[subStart]--; start += n; --count; } find[str]++; ++count; if (count != m) continue; res.push_back(start); } } return res; } }; ================================================ FILE: SudokuSolver.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Jun 19, 2013 Update: Sep 29, 2013 Problem: Sudoku Solver Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_37 Notes: Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by the character '.'. You may assume that there will be only one unique solution. Solution: back-tracking.. */ class Solution { public: typedef vector > BOARDTYPE; void solveSudoku(BOARDTYPE &board) { solveSudokuRe(board, 0, 0); } bool solveSudokuRe(BOARDTYPE &board, int row, int col) { getNextEmpty(board, row, col); if (row == 9) return true; vector avail(9, true); getAvailable(board, avail, row, col); for (int i = 0; i < 9; ++i) { if (!avail[i]) continue; board[row][col] = i + '1'; if (solveSudokuRe(board, row, col)) return true; } board[row][col] = '.'; return false; } void getNextEmpty(BOARDTYPE &board, int &row, int &col) { do { if (board[row][col] == '.') return; row = (col == 8) ? row + 1 : row; col = (col + 1) % 9; } while (row < 9); } void getAvailable(BOARDTYPE &board, vector &avail, int row, int col) { for (int i = 0; i < 9; ++i) { if (board[row][i] != '.') avail[board[row][i]-'1'] = false; if (board[i][col] != '.') avail[board[i][col]-'1'] = false; int box_i = row/3*3 + i/3, box_j = col/3*3 + i%3; if (board[box_i][box_j] != '.') avail[board[box_i][box_j]-'1'] = false; } } }; ================================================ FILE: SumRoottoLeafNumbers.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 23, 2013 Update: Jul 21, 2013 Problem: Sum Root to Leaf Numbers Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_129 Notes: Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. An example is the root-to-leaf path 1->2->3 which represents the number 123. Find the total sum of all root-to-leaf numbers. For example, 1 / \ 2 3 The root-to-leaf path 1->2 represents the number 12. The root-to-leaf path 1->3 represents the number 13. Return the sum = 12 + 13 = 25. Solution: 1. Recursion (add to sum when reaching the leaf). 2. Iterative solution. */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: int sumNumbers(TreeNode *root) { return sumNumbers_1(root); } int sumNumbers_1(TreeNode *root) { int sum = 0; sumNumbersRe(root, 0, sum); return sum; } void sumNumbersRe(TreeNode *node, int num, int &sum) { if (!node) return; num = num * 10 + node->val; if (!node->left && !node->right) { sum += num; return; } sumNumbersRe(node->left, num, sum); sumNumbersRe(node->right, num, sum); } int sumNumbers_2(TreeNode *root) { if (!root) return 0; int res = 0; queue> q; q.push(make_pair(root, 0)); while(!q.empty()) { TreeNode *node = q.front().first; int sum = q.front().second * 10 + node->val; q.pop(); if (!node->left && !node->right) { res += sum; continue; } if (node->left) q.push(make_pair(node->left, sum)); if (node->right) q.push(make_pair(node->right, sum)); } return res; } }; ================================================ FILE: SurroundedRegions.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 20, 2013 Update: Aug 21, 2013 Problem: Surrounded Regions Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_130 Notes: Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A region is captured by flipping all 'O's into 'X's in that surrounded region . For example, X X X X X O O X X X O X X O X X After running your function, the board should be: X X X X X X X X X X X X X O X X Solution: Traverse from the boarder to the inside and mark all the 'O's that are not surrounded by 'X' as 'V' (visited). 1. DFS. 2. BFS (queue). */ class Solution { public: typedef vector > BOARDTYPE; void solve(BOARDTYPE &board) { if (board.empty() || board[0].empty()) return; int N = board.size(), M = board[0].size(); for (int i = 0; i < N; ++i) for (int j = 0; j < M; ++j) if (i == 0 || j == 0 || i == N-1 || j == M-1) bfs(board, i, j); // you may call dfs or bfs here! for (int i = 0; i < N; ++i) for (int j = 0; j < M; ++j) board[i][j] = (board[i][j] == 'V') ? 'O' : 'X'; } void dfs(BOARDTYPE &board, int row, int col) { int N = board.size(), M = board[0].size(); if (row < 0 || row >= N || col < 0 || col >= M) return; if (board[row][col] != 'O') return; board[row][col] = 'V'; dfs(board, row+1, col); dfs(board, row-1, col); dfs(board, row, col+1); dfs(board, row, col-1); } void bfs(BOARDTYPE &board, int row, int col) { if (board[row][col] != 'O') return; int N = board.size(), M = board[0].size(); queue> q; q.push(make_pair(row, col)); while (!q.empty()) { int i = q.front().first, j = q.front().second; q.pop(); if (i < 0 || i >= N || j < 0 || j >= M) continue; if (board[i][j] != 'O') continue;// important to recheck! board[i][j] = 'V'; q.push(make_pair(i-1, j)); q.push(make_pair(i+1, j)); q.push(make_pair(i, j-1)); q.push(make_pair(i, j+1)); } } }; ================================================ FILE: SwapNodesinPairs.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 9, 2013 Update: Sep 3, 2013 Problem: Swap Nodes in Pairs Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_24 Notes: Given a linked list, swap every two adjacent nodes and return its head. For example, Given 1->2->3->4, you should return the list as 2->1->4->3. Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed. Solution: 1. Iterative solution with constant space. 2. Recursive solution with O(n) space (for practice). */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *swapPairs(ListNode *head) { return swapPairs_1(head); } ListNode *swapPairs_1(ListNode *head) { ListNode dummy(0), *cur = &dummy; cur->next = head; while (cur->next && cur->next->next) { ListNode *move = cur->next->next; cur->next->next = move->next; move->next = cur->next; cur->next = move; cur = move->next; } return dummy.next; } ListNode *swapPairs_2(ListNode *head) { if (!head || !head->next) return head; ListNode *first = head, *second = head->next; first->next = second->next; second->next = first; first->next = swapPairs(first->next); return second; } }; ================================================ FILE: SymmetricTree.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Apr 22, 2013 Update: Oct 07, 2014 Problem: Symmetric Tree Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_101 Notes: Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). For example, this binary tree is symmetric: 1 / \ 2 2 / \ / \ 3 4 4 3 But the following is not: 1 / \ 2 2 \ \ 3 3 Note: Bonus points if you could solve it both recursively and iteratively. Solution: 1. Recursive solution 2.Iterative way (queue). */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: bool isSymmetric(TreeNode *root) { return isSymmetric_2(root); } bool isSymmetric_1(TreeNode *root) { if (root == NULL) return true; return solve (root->left, root->right); } bool solve(TreeNode * t1, TreeNode * t2) { if (!t1 && !t2) return true; if (!t1 && t2 || t1 && !t2 || t1->val != t2->val) return false; return solve(t1->left, t2->right) && solve(t1->right, t2->left); } bool isSymmetric_2(TreeNode *root) { if (root == NULL) return true; stack s; s.push(root->left); s.push(root->right); while (!s.empty()) { TreeNode *t2 = s.top(); s.pop(); TreeNode *t1 = s.top(); s.pop(); if (!t1 && !t2) continue; if (!t1 && t2 || t1 && !t2 || t1->val != t2->val) return false; s.push(t1->right); s.push(t2->left); s.push(t1->left); s.push(t2->right); } return true; } bool isSymmetric_3(TreeNode *root) { if (root == NULL) return true; queue q; q.push(root->left); q.push(root->right); while (!s.empty()) { TreeNode *t2 = q.front(); q.pop(); TreeNode *t1 = q.front(); q.pop(); if (!t1 && !t2) continue; if (!t1 && t2 || t1 && !t2 || t1->val != t2->val) return false; q.push(t1->left); q.push(t2->right); q.push(t1->right); q.push(t2->left); } return true; } }; ================================================ FILE: TextJustification.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 8, 2013 Problem: Text Justification Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_68 Notes: Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified. You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactly L characters. Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right. For the last line of text, it should be left justified and no extra space is inserted between words. For example, words: ["This", "is", "an", "example", "of", "text", "justification."] L: 16. Return the formatted lines as: [ "This is an", "example of text", "justification. " ] Note: Each word is guaranteed not to exceed L in length. Corner Cases: A line other than the last line might contain only one word. What should you do in this case? In this case, that line should be left-justified. Solution: ... */ class Solution { public: vector fullJustify(vector &words, int L) { vector res; int i = 0, N = words.size(); while (i < N) { int length = words[i].size(); int j = i + 1; while (j < N && length + words[j].size() + (j-i) <= L) length += words[j++].size(); // build line string s(words[i]); bool isLastLine = (j == N); bool oneWord = (j == i + 1); int average = isLastLine || oneWord ? 1 : (L - length) / (j - i - 1); int extra = isLastLine || oneWord ? 0 : (L - length) % (j - i - 1); for (int k = i + 1; k < j; ++k) { s.append(extra > 0 ? average + 1 : average, ' '); s.append(words[k]); extra--; } s.append(L - s.size(), ' '); // push line res.push_back(s); i = j; } return res; } }; ================================================ FILE: TrappingRainWater.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: May 25, 2013 Update: Oct 07, 2014 Problem: Trapping Rain Water Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_42 Notes: Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. For example, Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6. Solution: 1. Find left bound and right bound for each element. O(n). 2. more space efficiency. Time: O(n), Space: O(1); */ class Solution { public: int trap_1(int A[], int n) { if (n == 0) return 0; vector maxLeft(n,0); vector maxRight(n,0); maxLeft[0] = A[0]; maxRight[n - 1] = A[n - 1]; for (int i = 1; i < n; ++i) { maxLeft[i] = max(maxLeft[i - 1], A[i]); maxRight[n - 1 - i] = max(maxRight[n - i], A[n - 1 - i]); } int res = 0; for (int i = 1; i < n; ++i) { res += min(maxLeft[i], maxRight[i]) - A[i]; } return res; } int trap_2(int A[], int n) { if (A == NULL || n <= 2) return 0; int left= 1; int right = n - 2; int maxLeft = A[0]; int maxRight = A[n - 1]; int res = 0; while (left <= right) { if (maxLeft <= maxRight) { res += max(0, maxLeft - A[left]); maxLeft = max(maxLeft, A[left]); ++left; } else { res += max(0, maxRight - A[right]); maxRight = max(maxRight, A[right]); --right; } } return res; } int trap_3(int A[], int n) { int i = 0, j = n - 1, res = 0, cur; while (i < j) { if (A[i] < A[j]) { cur = i+1; while (cur <= j && A[cur] <= A[i]) res += A[i] - A[cur++]; i = cur; } else { cur = j - 1; while (cur >= i && A[cur] <= A[j]) res += A[j] - A[cur--]; j = cur; } } return res; } }; ================================================ FILE: Triangle.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 14, 2013 Problem: Triangle Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_120 Notes: Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below. For example, given the following triangle [ [2], [3,4], [6,5,7], [4,1,8,3] ] The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11). Note: 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. Solution: Note that there are n elements in the n-th row (n starts from 1). 1. DFS. (Time Limit Exceeded for large test data). 2. DP. Do not need additional spaces (happen in-place). 3. DP. O(n) space (If the input 'triangle' can not be changed). */ class Solution { public: int minimumTotal(vector> &triangle) { return minimumTotal_2(triangle); } int minimumTotal_1(vector> &triangle) { int res = INT_MAX; minimumTotal_1_Re(triangle, 0, res, 0, 0); return res; } void minimumTotal_1_Re(vector> &triangle, int partSum, int &res, int deep, int j) { if (deep == triangle.size()) { res = min(res, partSum); return; } for (int i = j; i < triangle[deep].size() && i <= j + 1; ++i) minimumTotal_1_Re(triangle, partSum + triangle[deep][i], res, deep + 1, i); } int minimumTotal_2(vector> &triangle) { for (int i = triangle.size() - 2; i >= 0; --i) for (int j = 0; j < i + 1; ++j) triangle[i][j] = triangle[i][j] + min(triangle[i+1][j], triangle[i+1][j+1]); return triangle[0][0]; } int minimumTotal_3(vector> &triangle) { int N = triangle.size(); int *dp = new int[N]; for (int i = 0; i < N; ++i) dp[i] = triangle[N-1][i]; for (int i = N - 2; i >= 0; --i) for (int j = 0; j < i + 1; ++j) dp[j] = triangle[i][j] + min(dp[j], dp[j+1]); int res = dp[0]; delete [] dp; return res; } }; ================================================ FILE: TwoSum.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Jan 17, 2013 Update: Jan 16, 2014 Problem: Two Sum Difficulty: Medium Source: http://oj.leetcode.com/problems/two-sum/ Notes: Given an array of integers, find two numbers such that they add up to a specific target number. The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based. You may assume that each input would have exactly one solution. Input: numbers={2, 7, 11, 15}, target=9 Output: index1=1, index2=2 Solution: 1. Sort first. O(nlgn) 2. Hash table. O(n) Note: Hash Table solution has been updated. In case that the two elements are the same, all the indices should be stored in the map. */ bool compare(pair a, pair b) { return a.first < b.first; } class Solution { public: vector twoSum(vector &numbers, int target) { return twoSum_1(numbers, target); } vector twoSum_1(vector &numbers, int target) { vector> nums(numbers.size()); for (int i = 0; i < numbers.size(); ++i) nums[i] = make_pair(numbers[i], i+1); sort(nums.begin(), nums.end(), compare); int l = 0, r = nums.size() - 1; while (l < r) { int sum = nums[l].first + nums[r].first; if (sum == target) break; else if (sum < target) l++; else r--; } vector res; res.push_back(min(nums[l].second, nums[r].second)); res.push_back(max(nums[l].second, nums[r].second)); return res; } vector twoSum_2(vector &numbers, int target) { unordered_map hash; for (int i = 0; i < numbers.size(); ++i) { int second = target - numbers[i]; if (hash.find(second) != hash.end()) { return vector{hash[res]+1, i+1}; } else { hash.insert(pair{numbers[i],i}); } } return vector(); } }; ================================================ FILE: TwoSumIII.h ================================================ /* Author: King, wangjingui@outlook.com Date: Dec 26, 2014 Problem: Two Sum III - Data structure design Difficulty: Easy Source: https://oj.leetcode.com/problems/ Notes: Design and implement a TwoSum class. It should support the following operations: add and find. add - Add the number to an internal data structure. find - Find if there exists any pair of numbers which sum is equal to the value. For example add(1); add(3); add(5);find(4) -> true; find(7) -> false, Solution: Thanks to Javaman Cao. */ class TwoSum { public: unordered_map hash; void add(int number) { ++hash[number]; } bool find(int value) { for (unordered_map::iterator t = hash.begin(); t != hash.end(); ++t) { int x = value - t->first; if (x <= t->first) { unordered_map::iterator it = hash.find(x); if ((it != hash.end()) && ((t != it) || (it->second > 1))) { return true; } } } return false; } }; ================================================ FILE: UniqueBinarySearchTrees.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Jul 10, 2013 Update: Oct 07, 2014 Problem: Unique Binary Search Trees Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_96 Notes: Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For example, Given n = 3, there are a total of 5 unique BST's. 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3 Solution: dp. */ class Solution { public: int numTrees(int n) { return numTrees_2(n); } int numTrees_1(int n) { int dp[n+1]; memset(dp, 0, sizeof(dp)); dp[0] = 1; for (int i = 1; i <= n; ++i) for (int j = 0; j < i; j++) dp[i] += dp[j] * dp[i-j-1]; return dp[n]; } int numTrees_2(int n) { if (n < 0) return 0; vector dp(n+1, 0); dp[0] = 1; dp[1] = 1; for(int i = 2;i <= n; ++i){ dp[i] = dp[i-1] * (4 * i - 2)/(i + 1); } return dp[n]; } }; ================================================ FILE: UniqueBinarySearchTreesII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Jul 11, 2013 Problem: Unique Binary Search Trees II Difficulty: Medium Source: http://leetcode.com/onlinejudge#question_95 Notes: Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For example, Given n = 3, your program should return all 5 unique BST's shown below. 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3 Solution: 1. DFS directly. (from the Internet) 2. DP + DFS. (my solution) a. Generate trees for 'n' from 1 to n. (DP) b. When generate trees for n = i, get the left and right subtrees by copying tree structures of dp[1...i-1]. (copy tree uses DFS) */ class Solution { public: vector generateTrees(int n) { return generateTrees_1(n); } // solution 1 vector generateTrees_1(int n) { return generateTreesRe(1, n); } vector generateTreesRe(int l, int r) { vector res; if (l > r) { res.push_back(NULL); return res; } for (int k = l; k <= r; k++) { vector leftTrees = generateTreesRe(l, k-1); vector rightTrees = generateTreesRe(k+1, r); for (size_t i = 0; i < leftTrees.size(); i++) { for (size_t j = 0; j < rightTrees.size(); j++) { TreeNode* root = new TreeNode(k); root->left = leftTrees[i]; root->right = rightTrees[j]; res.push_back(root); } } } return res; } // solution 2 vector generateTrees_2(int n) { vector dp[n+1]; dp[0] = vector(1, (TreeNode *)NULL); for (int i = 1; i <= n; ++i) { for (int j = 1; j <= i; ++j) { for (int m = 0; m < dp[j-1].size(); ++m) { for (int k = 0; k < dp[i-j].size(); ++k) { TreeNode *root = new TreeNode(j); CopyTree(dp[j-1][m], root->left, 0); CopyTree(dp[i-j][k], root->right, j); dp[i].push_back(root); } } } } return dp[n]; } void CopyTree(TreeNode *original, TreeNode *&newNode, int diff) { if (!original) return; newNode = new TreeNode(original->val + diff); CopyTree(original->left, newNode->left, diff); CopyTree(original->right, newNode->right, diff); } }; ================================================ FILE: UniquePaths.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Apr 8, 2013 Update: Oct 9, 2014 Problem: Unique Paths Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_62 Notes: A robot is located at the top-left corner of a m x n grid. The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). How many possible unique paths are there? Solution: 1. Use formula C(x,t) = t!/(x!*(t-x)!) (x should be large for calculation). 2. Dynamic programming. UP(i,j) = UP(i-1,j) + UP(i,j-1). */ class Solution { public: int uniquePaths_1(int m, int n) { if (m == 1 || n == 1) return 1; int t = (m-1)+(n-1); int x = (m > n) ? (m-1) : (n-1); long long res = 1; for (int i = t; i > x; i--) res *= i; for (int i = t-x; i > 1; i--) res /= i; return res; } int uniquePaths_2(int m, int n) { int dp[m][n]; for (int i = 0; i < m; i++) dp[i][0] = 1; for (int j = 0; j < n; j++) dp[0][j] = 1; for (int i = 1; i < m; i++) for (int j = 1; j < n; j++) dp[i][j] = dp[i-1][j] + dp[i][j-1]; return dp[m-1][n-1]; } int uniquePaths_3(int m, int n) { vector dp(n, 1); for (int i = 1; i < m; ++i) { for (int j = 1; j < n; ++j) { dp[j] += dp[j-1]; } } return dp[n-1]; }; ================================================ FILE: UniquePathsII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : King, higuige@gmail.com Date: Apr 9, 2013 Update: Oct 9, 2014 Problem: Unique Paths II Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_63 Notes: Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. How many unique paths would there be? An obstacle and empty space is marked as 1 and 0 respectively in the grid. For example, There is one obstacle in the middle of a 3x3 grid as illustrated below. [ [0,0,0], [0,1,0], [0,0,0] ] The total number of unique paths is 2. Note: m and n will be at most 100. Solution: Dynamic programming. */ class Solution { public: int uniquePathsWithObstacles(vector > &obstacleGrid) { int m = obstacleGrid.size(); int n = obstacleGrid[0].size(); int dp[m][n]; if (obstacleGrid[0][0] == 1) return 0; dp[0][0] = 1; for (int i = 1; i < m; i++) dp[i][0] = obstacleGrid[i][0] == 1 ? 0 : dp[i-1][0]; for (int j = 1; j < n; j++) dp[0][j] = obstacleGrid[0][j] == 1 ? 0 : dp[0][j-1]; for (int i = 1; i < m; i++) for (int j = 1; j < n; j++) dp[i][j] = obstacleGrid[i][j] == 1 ? 0: dp[i-1][j] + dp[i][j-1]; return dp[m-1][n-1]; } int uniquePathsWithObstacles_2(vector > &obstacleGrid) { int m = obstacleGrid.size(); if (m == 0) return 0; int n = obstacleGrid[0].size(); vector dp(n+1,0); if(obstacleGrid[0][0] || obstacleGrid[m-1][n-1]) return 0; dp[1] = 1; for (int i = 1; i <= m; ++i) { dp[1] = obstacleGrid[i-1][0] ? 0 : dp[1]; for(int j = 2; j <= n; ++j) { dp[j] = obstacleGrid[i - 1][j - 1] == 1 ? 0: dp[j] + dp[j-1]; } } return dp[n]; } }; ================================================ FILE: ValidNumber.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com : Andy, nkuwjg@gmail.com Date: May 25, 2013 Update: Feb 7, 2015 Problem: Valid Number Difficulty: Hard Source: https://oj.leetcode.com/problems/valid-number/ Notes: Validate if a given string is numeric. Some examples: "0" => true " 0.1 " => true "abc" => false "1 a" => false "2e10" => true Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one. Solution: This finite-state machine solution. Learn from fuwutu & snakeDling. */ class Solution { public: bool isNumber_1(const char *s) { enum InputType {INVALID, SPACE, SIGN, DIGIT, DOT, EXPONENT}; int transitionTable[][SPACEEND] = { /* 0 1 2 3 4 5 */ 0, 1, 2, 3, 4, 0, // 0: INVALID 0, 1, 2, 3, 4, 0, // 1: SPACE 0, 0, 0, 3, 4, 0, // 2: SIGN 0, 6, 0, 3, 7, 5, // 3: DIGIT 0, 0, 0, 7, 0, 0, // 4: DOT 0, 0, 2, 8, 0, 0, // 5: EXPONENT 0, 6, 0, 0, 0, 0, // 6: END WITH SPACE 0, 6, 0, 7, 0, 5, // 7: DOT AND DIGIT 0, 6, 0, 8, 0, 0, // 8: END WITH SPACE OR DIGIT }; InputType last = INVALID; while (*s != '\0') { InputType state = INVALID; if (*s == ' ') state = SPACE; else if (isdigit(*s)) state = DIGIT; else if (*s == '+' || *s == '-') state = SIGN; else if (*s == 'e') state = EXPONENT; else if (*s == '.') state = DOT; last = (InputType) transitionTable[last][state]; if (last == INVALID) return false; s++; } bool validFinal[] = {0, 0, 0, 1, 0, 0, 1, 1, 1}; return validFinal[last]; } bool isNumber_2(const char *s) { bool dot = false, digit = false, exp = false; while (*s == ' ') ++s; if (*s == '-' || *s == '+') ++s; if (*s == 0) return false; for (;*s != '\0' && *s != ' '; ++s) { if (isdigit(*s)) digit = true; else if (*s == 'e' || *s == 'E') { if (exp == true || digit == false || *(s+1) ==' ' || *(s+1) =='\0') return false; exp = true; } else if (*s == '.') { if (dot == true || exp == true) return false; if (digit == false && (*(s+1) ==' ' || *(s+1) =='\0')) return false; dot = true; } else if (*s == '-' || *s == '+') { if (*(s+1) == ' ' || *(s+1) == '\0') return false; if (*(s-1) != 'e' && *(s-1) != 'E') return false; } else return false; } while (*s == ' ') ++s; return *s == '\0'; } }; ================================================ FILE: ValidPalindrome.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 29, 2013 Update: Jul 19, 2013 Problem: Valid Palindrome Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_125 Notes: Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. For example, "A man, a plan, a canal: Panama" is a palindrome. "race a car" is not a palindrome. Note: Have you consider that the string might be empty? This is a good question to ask during an interview. For the purpose of this problem, we define empty string as valid palindrome. Solution: traverse from both side. */ #include // needed for isalnum(), isupper() and tolower(). class Solution { public: bool isPalindrome(string s) { for (int i = 0, j = s.size() - 1; i < j; ++i, --j) { while (i < j && !isalnum(s[i])) i++; while (i < j && !isalnum(s[j])) j--; if (tolower(s[i]) != tolower(s[j])) return false; } return true; } }; ================================================ FILE: ValidParentheses.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 29, 2013 Update: Jul 14, 2013 Problem: Valid Parentheses Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_20 Notes: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not. Solution: stack. */ class Solution { public: bool isValid(string s) { stack stk; for (int i = 0; i < s.size(); ++i) { if (s[i] == '(' || s[i] == '[' || s[i] == '{') { stk.push(s[i]); } else { if (stk.empty() || abs(stk.top() - s[i]) > 2) return false; stk.pop(); } } return stk.empty(); } }; ================================================ FILE: ValidSudoku.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 20, 2013 Problem: Valid Sudoku Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_36 Notes: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules (http://sudoku.com.au/TheRules.aspx). The Sudoku board could be partially filled, where empty cells are filled with the character '.'. Solution: 1. Traverse the Sudoku only once. 2. Bit manipulation. Use only one bit to represent a number. Space: sizeof(int) * (1+9+9). */ class Solution { public: bool isValidSudoku(vector> &board) { const int N = 9; int row, col[N] = {0}, box[N] = {0}; for (int i = 0; i < N; ++i) { row = 0; for (int j = 0; j < N; ++j) { if (board[i][j] == '.') continue; int bit = 1 << (board[i][j] - '1'); int box_index = i/3*3 + j/3; if (row & bit || col[j] & bit || box[box_index] & bit) return false; row |= bit; col[j] |= bit; box[box_index] |= bit; } } return true; } }; ================================================ FILE: ValidateBinarySearchTree.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 10, 2013 Update: Dec 25, 2014 Problem: Validate Binary Search Tree Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_98 Notes: Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as follows: The left subtree of a node contains only nodes with keys less than the node's key. The right subtree of a node contains only nodes with keys greater than the node's key. Both the left and right subtrees must also be binary search trees. Solution: Recursion. 1. Add lower & upper bound. O(n) 2. Inorder traversal with one additional parameter (value of predecessor). O(n) */ /** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: bool isValidBST(TreeNode *root) { return isValidBST_1(root); } // solution 1: lower bound + higher bound bool isValidBST_1(TreeNode *root) { return isValidBSTRe_1(root, INT_MIN, INT_MAX); } bool isValidBSTRe_1(TreeNode *node, int lower, int upper){ if (!node) return true; if (node->val <= lower || node->val >= upper) return false; return isValidBSTRe_1(node->left, lower, node->val) && isValidBSTRe_1(node->right, node->val, upper); } // solution 2: inorder bool isValidBST_2(TreeNode *root) { TreeNode * prev = NULL; return inorder(root, prev); } bool inorder(TreeNode * root, TreeNode*&prev) { if (root == NULL) return true; if (inorder(root->left, prev) == false) return false; if (prev && root->val <= prev->val) return false; prev = root; return inorder(root->right,prev); } }; ================================================ FILE: WildcardMatching.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Aug 20, 2013 Problem: Wildcard Matching Difficulty: Medium Source: https://oj.leetcode.com/problems/wildcard-matching/ Notes: Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any single character. '*' Matches any sequence of characters (including the empty sequence). The matching should cover the entire input string (not partial). The function prototype should be: bool isMatch(const char *s, const char *p) Some examples: isMatch("aa","a") ? false isMatch("aa","aa") ? true isMatch("aaa","aa") ? false isMatch("aa", "*") ? true isMatch("aa", "a*") ? true isMatch("ab", "?*") ? true isMatch("aab", "c*a*b") ? false Solution: ... */ class Solution { public: bool isMatch(const char *s, const char *p) { const char *sBackup = NULL, *pBackup = NULL; while (*s != '\0') { if (*p == '*') { while (*p == '*') ++p; if (*p == '\0') return true; sBackup = s; pBackup = p; } if (*p == '?' || *s == *p) { ++s, ++p; } else { if (!sBackup) return false; s = ++sBackup; p = pBackup; } } while (*p == '*') ++p; return *s == '\0' && *p == '\0'; } }; ================================================ FILE: WordBreak.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Oct 6, 2013 Problem: Word Break Difficulty: Easy Source: http://oj.leetcode.com/problems/word-break/ Notes: Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words. For example, given s = "leetcode", dict = ["leet", "code"]. Return true because "leetcode" can be segmented as "leet code". Solution: dp. */ class Solution { public: bool wordBreak(string s, unordered_set &dict) { int N = s.size(); bool canBreak[N+1]; memset(canBreak, false, sizeof(canBreak)); canBreak[0] = true; for (int i = 1; i <= N; ++i) { for (int j = i-1; j >= 0; --j) { if (canBreak[j] && dict.find(s.substr(j, i-j)) != dict.end()) { canBreak[i] = true; break; } } } return canBreak[N]; } }; ================================================ FILE: WordBreakII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Oct 7, 2013 Problem: Word Break II Difficulty: Easy Source: http://oj.leetcode.com/problems/word-break-ii/ Notes: Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word. Return all such possible sentences. For example, given s = "catsanddog", dict = ["cat", "cats", "and", "sand", "dog"]. A solution is ["cats and dog", "cat sand dog"]. Solution: check before constructing the sentences. */ class Solution { public: vector wordBreak(string s, unordered_set &dict) { vector res; if (!wordBreakPossible(s, dict)) return res; wordBreakRe(s, dict, 0, "", res); return res; } void wordBreakRe(const string &s, const unordered_set &dict, int start, string sentence, vector &res) { if (start == s.size()) { res.push_back(sentence); return; } if (start != 0) sentence.push_back(' '); for (int i = start; i < s.size(); ++i) { string word = s.substr(start, i-start+1); if (dict.find(word) == dict.end()) continue; wordBreakRe(s, dict, i+1, sentence + word, res); } } bool wordBreakPossible(const string &s, const unordered_set &dict) { int N = s.size(); bool canBreak[N+1]; memset(canBreak, false, sizeof(canBreak)); canBreak[0] = true; for (int i = 1; i <= N; ++i) { for (int j = i-1; j >= 0; --j) { if (canBreak[j] && dict.find(s.substr(j, i-j)) != dict.end()) { canBreak[i] = true; break; } } } return canBreak[N]; } }; ================================================ FILE: WordLadder.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Jun 8, 2013 Problem: Word Ladder Difficulty: High Source: http://leetcode.com/onlinejudge#question_127 Notes: Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that: Only one letter can be changed at a time Each intermediate word must exist in the dictionary For example, Given: start = "hit" end = "cog" dict = ["hot","dot","dog","lot","log"] As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", return its length 5. Note: Return 0 if there is no such transformation sequence. All words have the same length. All words contain only lowercase alphabetic characters. Solution: BFS. */ class Solution { public: int ladderLength(string start, string end, unordered_set &dict) { queue> q; q.push(make_pair(start, 1)); while (!q.empty()) { pair front = q.front(); q.pop(); string word = front.first; for (size_t i = 0; i < word.size(); i++) { char before = word[i]; for (char c = 'a'; c <= 'z'; c++) { word[i] = c; if (word == end) return front.second + 1; if (dict.find(word) != dict.end()) { q.push(make_pair(word, front.second + 1)); dict.erase(word); } } word[i] = before; } } return 0; } }; ================================================ FILE: WordLadderII.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Jul 8, 2013 Problem: Word Ladder II Difficulty: High Source: http://leetcode.com/onlinejudge#question_126 Notes: Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that: Only one letter can be changed at a time Each intermediate word must exist in the dictionary For example, Given: start = "hit" end = "cog" dict = ["hot","dot","dog","lot","log"] Return [ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ] Note: All words have the same length. All words contain only lowercase alphabetic characters. Solution: Idea is from blog: http://blog.csdn.net/niaokedaoren/article/details/8884938 */ class Solution { public: vector> findLadders(string start, string end, unordered_set &dict) { map> traces; // If A->C and B->C, then traces[C] contains A and B. // This is used for recovering the paths. vector> level(2); int cur = 0; int prev = 1; level[cur].insert(start); dict.insert(end); while (true) { prev = !prev; cur = !cur; level[cur].clear(); // remove visited words. IMPORTANT! for (unordered_set::iterator it = level[prev].begin(); it != level[prev].end(); ++it) dict.erase(*it); for (unordered_set::iterator it = level[prev].begin(); it != level[prev].end(); ++it) { string word = *it; for (size_t i = 0; i < word.size(); i++) { char before = word[i]; for (char c = 'a'; c <= 'z'; c++) { if (c == before) continue; word[i] = c; if (dict.find(word) != dict.end()) { traces[word].push_back(*it); level[cur].insert(word); } } word[i] = before; } } if (level[cur].empty() || level[cur].count(end) > 0) break; } vector> res; vector onePath; if (!traces.empty()) buildResult(traces, res, onePath, end); return res; } void buildResult(map> &traces, vector> &res, vector &onePath, string word) { if (traces.count(word) == 0) { vector copy(onePath); copy.push_back(word); reverse(copy.begin(), copy.end()); res.push_back(copy); return; } const vector &s = traces[word]; onePath.push_back(word); for (vector::const_iterator it = s.begin(); it != s.end(); ++it) buildResult(traces, res, onePath, *it); onePath.pop_back(); } }; ================================================ FILE: WordSearch.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: May 13, 2013 Update: Sep 20, 2013 Problem: Word Search Difficulty: Easy Source: http://leetcode.com/onlinejudge#question_79 Notes: Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once. For example, Given board = [ ["ABCE"], ["SFCS"], ["ADEE"] ] word = "ABCCED", -> returns true, word = "SEE", -> returns true, word = "ABCB", -> returns false. Solution: DFS. (For 'visited', using two-dimensional array will be faster than vector.[90+ms->50+ms]) */ class Solution { public: typedef vector > VECTOR2D; bool exist(VECTOR2D &board, string word) { int N = board.size(), M = board[0].size(); VECTOR2D avail(N, vector(M, 'o')); for (int i = 0; i < N; ++i) for (int j = 0; j < M; ++j) if (existRe(board, word, 0, i, j, avail)) return true; return false; } bool existRe(const VECTOR2D &board, const string &word, int deep, int i, int j, VECTOR2D &avail) { int N = board.size(), M = board[0].size(); if (deep == word.size()) return true; if (i < 0 || i >= N || j < 0 || j >= M) return false; if (board[i][j] != word[deep] || avail[i][j] == 'x') return false; avail[i][j] = 'x'; if (existRe(board, word, deep + 1, i-1, j, avail)) return true; if (existRe(board, word, deep + 1, i+1, j, avail)) return true; if (existRe(board, word, deep + 1, i, j-1, avail)) return true; if (existRe(board, word, deep + 1, i, j+1, avail)) return true; avail[i][j] = 'o'; return false; } }; ================================================ FILE: ZigZagConversion.h ================================================ /* Author: Annie Kim, anniekim.pku@gmail.com Date: Apr 7, 2013 Update: Dec 14, 2014 Problem: ZigZag Conversion Difficulty: Easy Source: https://oj.leetcode.com/problems/zigzag-conversion/ Notes: The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) P A H N A P L S I I G Y I R And then read line by line: "PAHNAPLSIIGYIR" Write the code that will take a string and make this conversion given a number of rows: string convert(string text, int nRows); convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR". Solution: ... */ class Solution { public: string convert(string s, int nRows) { if(nRows <= 1) return s; int n = s.size(); string res; for(int i = 0;i < nRows; ++i){ for (int j = 0; j + i < n; j += 2*nRows - 2) { res.push_back(s[j+i]); if (i == 0 || i == nRows - 1) continue; if (j + 2*nRows - 2 - i < n) res.push_back(s[j + 2*nRows - 2 - i]); } } return res; } };