This document is to summarize the solutions of LeetCode problems.
3Sum: sort the array first, then make three pointers -ito head,jto tail andkto pivot.if (a[i] + a[k] + a[j]) < 0, i++ else j--.3SumCloset: similar to 3Sum.4Sum: compute the sum of each pair of two elements in the array frist. for each twoSumi, check whether another twoSumjexist, wherei + j = target.AddBinary: simple problem.AddTwoNumbers: simple problem.Anagrams: simple#hashtableproblem.BalancedBinaryTree: simple#balance#treeproblem.BestTimetoBuyandSellStock: simple problem.BestTimetoBuyandSellStockII: simple problem.BestTimetoBuyandSellStockIII:tricky #dp problem.divide and conquer. find the max profit of0..iandi+1...n, each of them is in just one transaction. get the i for optimal profit.BinaryTreeInorderTraversal: simple#treebinarytreeproblem. recursive method is trival. iterative method is as follows. one stackrecsis used to store each node. if the left node is NULL, pop up the top nodeiin the stackrecs, and then traversal the nodei->right.BinaryTreeLevelOrderTraversal: simple#tree#binarytree#bstproblem.#bstthe tree level by level.BinaryTreeLevelOrderTraversalII: simple#tree#binarytree#bstproblem. the same method used inBinaryTreeLevelOrderTraversal, and then reverse the result.BinaryTreeMaximumPathSum: simple#tree#binarytreeproblem. for each nodei,max(leftPathSum+i->val, rightPathSum+i->val, leftPathSum+rightPathSum+i->val)and returnmax(leftPathSum+i->val, rightPathSum+i->val)to parent.BinaryiTreeZigzagLevelOrderTraversal: simple#tree#binarytreeproblem. use odd and even level to control whether reverse the vector.Candy: tricky problem. scan from beginning,if ratings[i] > ratings[i-1]num[i] = num[i-1] + 1. It can assign the candy to each increasing interval. Then, scan from the end, ifnum[i]is already assigned by a number, ifratings[i] > ratings[i+1], theniis at the peak, make surenum[i] > num[i+1], otherwise,num[i] = num[i+1] + 1. ifnum[i]is not assigned yet, make it to be 1.ClimbingStairs: simple#dpproblem.steps[i] = steps[i-1] +steps[i-2].CloneGraph:#hashtableproblem. use a#hashto store the nodes already created. Every time, first check whether the node is already created.CombinationSum: simple knapsack problem.#dp. The numbers can be reused. Scan from the beginning. Useunordered_map<int, <vector<int> > pathto store the previous number that can reach this number. Use recussive method to retrieve the path.CombinationSumII: simple knapsack problem.#dp. The numbers could not be reused. Scan from the end. Useunordered_map<int, <vector<int> > pathto store the previous number's index that can reach this number. Use recussive method to retrieve the path.Combinations: simple#dfsproblem.ConstructBinaryTreefromInorderandPostorderTraversal: simple#tree#binarytreeproblem. The last elemeent in postorder traversal is the root node which can be used to split the inorder traversal.ConstructBinaryTreefromPreorderandInorderTraversal: simple#tree#binarytreeproblem. The first elemeent in preorder traversal is the root node which can be used to split the inorder traversal.ContainerWithMostWater: tricky problem. Two pointers,ito the frist,jto the end. Computemax(res, min(height[i], height[j])*(j-i)), Theni++ifheight[i] < height[j], otherwise,j--.ConvertSortedArraytoBinarySearchTree: simple#tree#binarytree#binarysearch#recussiveproblem. Use element in the middle as the root each time. and build left subtree and right subtree using left section and right section in the array.ConvertSortedListtoBinarySearchTree: simple#tree#binarytree#linkedlist#recussiveproblem. The same method used inConvertSortedArraytoBinarySearchTree, but need a function to compute the length of list and find the element in list by index.CopyListwithRandomPointer:#hashtable. The same method used inCloneGraph. A#hashtableis used to store the node already created.CountandSay: simple problem. Just simple use the rule described in the problem to generate the string.DecodeWays: simple#dpproblem.opt[i] = opt[i-2] + opt[i-1]ifs[i-1]..s[i]can be decoded, otherwise,opt[i] = opt[i-1].DistinctSubsequences: simple#dpproblem.opt[i][j]represents the number of distinct subsequences forT[0]..T[i-1]andS[0]..S[j-1].opt[i+1][j+1] = opt[i][j] + opt[i+1][j]ifT[i] == S[j], otherwise,opt[i+1][j+1] = opt[i+1][j].DivideTwoIntegers: trick#bitshiftproblem.b << 1untilbis larger thanawithitimes shift and record the result after each shift ininc[i]. Then,a -= inc[i]andres += 1 << iuntila <= 0ori < 0.EditDistance: classic#dpproblem.FirstMissingPositive:trick problem. swap elements to put positive numberiinto the positioni-1. scan from the beginning, find the first positioniwherea[i] != i+1, then returni+1.FlattenBinaryTreetoLinkedList:#tree#binarytreeproblem. for each nodei, find the right most nodejfori->left, then makej->right = i->right,i->right = i->leftandi->left = NULL.GasStation:tricky problem. scan all gas stations and computetotal += gas[i] - cost[i]andtank += gas[i] - cost[i].if tank < 0, mark i and set tank = 0. after done,if total > 0, then return (i+1) % gas.size() else -1. The reason why(i+1) % gas.size()could be a starting point is that for every previous pointk,tank(k) = tank(k-1) + gas[k] - cost[k], wheretank(k-1) >= 0, it could not maketank(i) = tank(i-1) + gas[i] - cost[i] >= 0, then it would also not maketank(i) >= 0 if tank(k) = gas[k] - cost[k], which makeskto be the starting point.GenerateParentheses:#dfs#recusiveproblem. generate(frist, then genrate).GrayCode: convert a binary to the gray code byGrayCode(i) = (i>>1)^i.ImplementstrStr(): simple problem.InsertInterval: scan the whole intervals, each time get the smallest for newInterval.start and the largest for newInterval.end.InsertionSortList:#linkedlistproblem. split the list, n1->n2->n3->n4->null, into two part, a sorted part, n0->n1->n2->null, and an unsorted part, n3->n4->null. Each time go through the sorted part to find a position for the element would be inserted.IntegertoRoman: simple problem. check from the largest number represents in Roman.InterleavingString:tricky#dpproblem.opt[i+1][j+1]represents whethers1[0]...s1[i]ands2[0]...s2[j]can be interleaved to construct s3. checks1[i] == s3[i+j+1]ands2[j] == s3[i+j+1]to makeopt[i+1][j+1] = opt[i][j+1] || opt[i+1][j].JumpGame: simple problem. each time check wehther this position can be reached by previuos position.JumpGameII: find the further position for each step.LargestRectangleinHistogram:tricky problem. push each area into the stack, until the current height is lower than that of the top element in the stack. Then, pop up the areas in the stack and compute them for each top element in the stack whose height is higher or equals to current height. Then, push the new area with current height and the new width into the stack again.LengthofLastWord: simple problem.LetterCombinationsofaPhoneNumber: simple problem.LinkedListCycle: classic problem. two nodes, one moves forward one step, another moves forward two step, check wether thes two nodes would be overlapped.LinkedListCycleII: classic problem. after detect the cycle using the method inLinkedListCycle. Go through from head and the intersected node, if they meet, then return that node.LongestCommonPrefix: hash the prefix of each string.#hashtableLongestConsecutiveSequence:tricky problem. put all elements into a hash first. iterate the elements in the hash, and check the length of left and right consecutive in the hash.#hashtableLongestPalindromicSubstring: scan the index of the string, check whether palindrome when the index k is in the middle.LongestSubstringWithoutRepeatingCharacters:tricky problem. useprev[]to keep the nearest index wheres[prev[i]] = s[i]. if it is the first occurence of the element,prev[i] = -1. scan the elements,if prev[end] >= begin, begin = prev[end] + 1.LongestValidParentheses:tricky problem.more practice. use a struct to store the values[i]and the indexi. push'('into stack. each time find a match for')', compute the length byi - top(stack).indexafter the matched'('has been popped.LRUCache:#lru#hashtableproblem. a structunordered_map<int, pair(list<int>::iterator, int)>is used for cache,list<int>for keep the order of data.MaximalRectangle:tricky problem. useheight[]to indicate the number of consecutive1appearred in each column to current line. and then, the problem would be reduced to solveLargestRectangleinHistogram.MaximumDepthofBinaryTree: simple problem.MaximumSubarray: simple problem.MedianofTwoSortedArrays:tricky problem. usedivide and conquer.if A[mid] < B[mid], then the value should not in A[0]...A[mid]. Similarly,B[mid] < A[mid], then the value should not in B[0]...A[mid].MergeIntervals: similar toInsertInterval.MergekSortedLists: simply#linkedlistproblem.MergeSortedArray: do it in-space. pointerkto the last index ofA'scapacity. pointerito the last index ofA'sactual values, pointerjto the last index ofB. each time determine whetherA[i]orB[j]will be assigned toA[k].MergeTwoSortedLists: simplelinkedlistproblem.MinimumDepthofBinaryTree: simple#binarytree#treeproblem.MinimumPathSum: simple#dpproblem.MinimumWindowSubstring:tricky problem. two pointers -headandtail.tailwould be increased, until find a window (a#hashtableis used to make such a decision). Then, shrink the window by increasinghead.MultiplyStrings: multiply manually.more practice.N-Queens: simple#dfsproblem.N-QueensII: simple#dfsproblem.NextPermutation:tricky problem. First, start from the end of the sequence, find the first index i where an increasing sequence exists. Then start from the end of the sequence again, find the first indexj, wherea[i] < a[j]andi < j. swapa[i]anda[j]andreverse(a.begin()+i+1, a.end()).PalindromeNumber: simple problem.PalindromePartitioning: partition the string into two parts, if the first part is palindrome, then continue.PalindromePartitioningII:tricky #dp problem. #dp to determine whether a substring,s[i]..s[j], palindrome -recs[i][j] = s[i] == s[j] && recs[i+1][j-1]. use #dp to determine whether a cut is required -opt[j] = min(opt[j], opt[i]+1), ifs[i+1]..[j]is palindrome.PartitionList: simple#linkedlistproblem. use one#linkedlistto keep tracking the first part, use another#linkedlistto keep tracking the second part. concatenate these two parts in the end.Pascal'sTriangle: simple problem.Pascal'sTriangleII: simple problem.a[i] += a[i+1],a.insert(a.begin(), 1).PathSum: simple#tree#binarytreeproblem.PathSumII: simple#tree#birnarytreeproblem.PermutationSequence:tricky problem. The number in the1stposition, should repeate(n-1)!times. So, we could usek/(n-1)!to calcualte which number should be located in1stposition. Then,k %= (n-1)!. Use the same method to cacluate the number in2nd,3rd, ..., positions.Permutations: simple problem. swapa[i]anda[j]wherei <= jand recussively do it oni+1.PermutationsII:tricky problem. Each iteration, use the method inNextPermutationto generate the next permutation for num and then add it into the result. It wwill end when num comes to be the same value as that is at the beginning.PlusOne: simple problem.PopulatingNextRightPointersinEachNode: simple#tree#binarytreeproblem.node->left->next = node->right ? node->right : NULL.node->right->next = node->next->left.PopulatingNextRightPointersinEachNode: simple#tree#binarytreeproblem.node->left->next = node->right ? node->right : getNext(node).node->right->next = getNext(node). IngetNext(node), get the next sibling by iterating allnode = node->nextand returnnode->leftornode->right. After one node finished, go further tonode->rightfirst, since it can build the next pointer which may be used in the left node.RecoverBinarySearchTree:#treebinarytreeproblem. inorder traversal the tree. first foundprev->val > node(j)->valthenprevwould be the first node in wrong position. the second time foundprev->val > node(j)->valthenjwoudl be the second node.Pow(x, n): tricky#bitshiftproblem. say,3^5 = (3^1)*(3^4) = (3^(2^0))*(3^(2^2))and5in binary is101. makenin binary, if the bitiinnis1, then we can havex^(2^i).RegularExpressionMatching:tricky problem. one pointerito the first strings1, one pointerjto the second strings2. Each time ifs2[j+1] == '*', we need to checkisMatch(s1[i]...s1[n], s2[j+2]...s2[m])and increaseiuntils1[i] != s2[j]. Then, we need to checkisMatch(s1[i]...s1[n], s2[j+2]...s2[m])for next segment. ifs2[j+1] != '*', ifs1[i] == s2[j]then checkisMatch(s1[i+1]...s1[n], s2[j+1]...s2[m]), otherwise, return false.'.'would be treated as the same to anys1[i].RemoveDuplicatesfromSortedArray: simple problem.RemoveDuplicatesfromSortedArrayII: simple problem.RemoveDuplicatesfromSortedList: simple#linkedlistproblem. Try withdouble pointer.RemoveDuplicatesfromSortedListII: simple#linkedlistproblem. Try withdouble pointer.RemoveElement: simple problem. Two pointers,ito head,jto tail. each timeA[i] == elem,swap(A[i], A[j--]), otherwisei++.RemoveNthNodeFromEndofList: simple#linkedlistproblem. Try withdouble pointer.ReverseInteger: simple problem.ReverseLinkedListII: simple problem. try 'double pointer'. Each time change the tail node to the head.ReverseNodesink-Group: simple problem. similar toReverseLinkedListII. trydouble pointer.ReorderList:#linkedlistproblem. useemplace_back()to push all elements into avector. Use two pointersi,jto add elements fromiorj.RestoreIPAddresses: simple#dfsproblem. check0 <= each segment <= 255.RomantoInteger: simple problem.RotateImage:tricky problem. need more practice. rotate by layer. think about the swap.RotateList: simple#linkedlistproblem.SameTree: simple#tree#binarytreeproblem.ScrambleString:tricky problem.#dp. for eachs1[i1]..s1[j1]ands2[i2]..s2[j2], checkisScramble(s1[i1], s1[i1+i], s2[i2], s2[i2+i]) && isScramble(s1[i1+i+1], s1[j1], s2[i2+i+1], s2[j2])andisScramble(s1[i1], s1[i1+i], s2[j2-i+1], s2[j2]) && isScramble(s1[i1+i+1], s1[j1], s2[i2], s2[j2-i]).Searcha2DMatrix: simple problem.#binarysearch.SearchforaRange: simple problem.#binarysearch.SearchinRotatedSortedArray:tricky #binarysearch problem.more practice. ifA[mid] >= A[begin], then checkA[mid] > target && target >= A[begin]; otherwise, checkA[mid] > target || target >= A[begin].SearchinRotatedSortedArrayII:tricky #binarysearch problem.more practice. similar toSearchinRotatedSortedArray, except ifA[mid] == A[begin],begin++.SearchInsertPosition: simple#binarysearchproblem.SetMatrixZeroes:tricky problem. ifmatrix[i][j] == 0, setmatrix[i][0] = 0andmatrix[0][j] = 0. Then, checkmatrix[i][0]andmatrix[0][i]to set 0 on the whole row or column.SimplifyPath: consider the rule.more practice.SingleNumber:tricky problem.XORto all the elements.SingleNumberII:tricky problem.#bitproblem. calculate the occurrences of each number in each bit and mod3.SortColors: simple problem. three pointers,i, k, jto0, 1, 2, respectively. movekto determineswap(A[i], A[k])orswap(A[k], A[j])ork++.SpiralMatrix:tricky problem. four pointerbeginX, endX, beginY, endY. each time movebeginY++, endX--, endY--, beginX++.SpiralMatrixII: the same method as that ofSpiralMatrix.Sqrt(x):#binarysearch. uselong longto avoid overflow, since multiplication may cause overflow.StringtoInteger(atoi): consider all the possible inputs.Subsets:#dfsproblem. each time the element can be added to the subset or not.SubsetsII:#dfsproblem. for each duplicated elements, just find the end position of the duplicated element, and add them once.SubstringwithConcatenationofAllWords:tricky problem.#hashtableto record all strings in L. for each position in S, check whether it is a good start using another#hashtableto record the strings matched in S.SudokuSolver: find each'.'and try1-9on it.SumRoottoLeafNumbers: simple problem.#tree#binarytree.SurroundedRegions:#dfs. first check all'O'on the margin and mark them and'O'ssurrounded them. then modify all'O'swhich are not marked.SwapNodesinPairs:#linkedlist. trydouble pointerson it.SymmetricTree:#tree#binarytreeproblem. try recursive and iterative method. recursive method: each time check two nodes -i,j- and checkisSymmetric(i->left, j->right)andisSymmetric(i->right, j->left). iterative method, check by level.TextJustification: consider the number of space.TrappingRainWater: How mach water can be contained in indexiis determined by the heighest one on the left and right.Triangle: calculate buttom-up.TwoSum:#hashtableto record the position.UniqueBinarySearchTrees:tricky#tree#binarytreeproblem. iterate the root nodeithenresult += numTrees(left(i)) * numTrees(right(i))`.UniqueBinarySearchTreesII: The same method as that ofUniqueBinarySearchTrees. recursively generate the tree by iterating the node as root. Generate all leftChildTrees and rightChildTrees, and then generate them by making the node as root.UniquePaths: simple#recursionproblem.UniquePathsII: simple#recursionproblem. when Obstacles exists, not go through with it.ValidateBinarySearchTree:#tree#binarytreeproblem. check lower bound and upper bound for each node.ValidNumber: need more practice.ValidPalindrome: two pointers -i, j- to head and tail. just check whens[i]ands[j]are alphanumeric.ValidParentheses: simple#stackproblem.ValidSudoku: check whether valid for each row, column and square.WildcardMatching:trick#dpproblem.#recursivewill beTLE.opt[i][j]represents whethers[0]...s[i]will matchp[0]...p[j].WordBreak:#dpproblem.opt[j]represents whethers[0]...s[j]could be combined in dictionary.opt[j] = opt[i]ifsubstring(i+1, j)exists in dictionary.WordBreakII:#dpproblem. same method inWordBreak. Need a#hashtableto record the path.WordLadder:#bfsproblem. iterateatozfor each position of each word.WordLadderII:#bfsproblem. need more practice. need to handle overlapping when add path. use another#hashtableto store which values have been reached before this level.WordSearch:#dfsproblem.ZigZagConversion:j += 2*nRows-2,k = j + 2 * (nRows - i - 1).
The following problems come from #leetcode blogs.
StringReorderDistanceApart:#greadyproblem. each time check for the word with highest frequency first.Multiplicationofnumbers:tricky problem. use left to be the multiplication of all elements on the left ofi. right to be the multiplication of all elements on the right ofi.Rotatinganarrayinplace:tricky problem. rotate the string triple times.