[
  {
    "path": ".gitignore",
    "content": "*.class\n.DS_store\n.vscode\n.idea\n"
  },
  {
    "path": "README.md",
    "content": "# leetcode-java\n\n\n| Class Definition |\n|:----------------------------------------------------------------------------------:|\n| [ListNode](https://github.com/fluency03/leetcode-java/blob/master/src/ListNode.java) |\n| [TreeNode](https://github.com/fluency03/leetcode-java/blob/master/src/TreeNode.java) |\n| [Interval](https://github.com/fluency03/leetcode-java/blob/master/src/Interval.java) |\n| [TreeLinkNode](https://github.com/fluency03/leetcode-java/blob/master/src/TreeLinkNode.java) |\n| [UndirectedGraphNode](https://github.com/fluency03/leetcode-java/blob/master/src/UndirectedGraphNode.java) |\n| [Point](https://github.com/fluency03/leetcode-java/blob/master/src/Point.java) |\n\n\n# Search and Sort\n\n| Search ([*README*](https://github.com/fluency03/leetcode-java/tree/master/src/search)) | Sort ([*README*](https://github.com/fluency03/leetcode-java/tree/master/src/sort)) |\n|:-:|:-:|\n| [Linear Search](https://github.com/fluency03/leetcode-java/blob/master/src/search/LinearSearch.java) | [Selection Sort](https://github.com/fluency03/leetcode-java/blob/master/src/sort/SelectionSort.java) |\n| [Binary Search](https://github.com/fluency03/leetcode-java/blob/master/src/search/BinarySearch.java) | [Bubble Sort](https://github.com/fluency03/leetcode-java/blob/master/src/sort/BubbleSort.java) |\n| [Jump Search](https://github.com/fluency03/leetcode-java/blob/master/src/search/JumpSearch.java) | [Insertion Sort](https://github.com/fluency03/leetcode-java/blob/master/src/sort/InsertionSort.java) |\n| [Interpolation Search](https://github.com/fluency03/leetcode-java/blob/master/src/search/InterpolationSearch.java) | [Merge Sort ](https://github.com/fluency03/leetcode-java/blob/master/src/sort/MergeSort.java)|\n| [Exponential Search](https://github.com/fluency03/leetcode-java/blob/master/src/search/ExponentialSearch.java) | [Heap Sort](https://github.com/fluency03/leetcode-java/blob/master/src/sort/HeapSort.java) |\n| [Ternary Search](https://github.com/fluency03/leetcode-java/blob/master/src/search/TernarySearch.java) | [Quick Sort](https://github.com/fluency03/leetcode-java/blob/master/src/sort/QuickSort.java) |\n| [...](http://www.geeksforgeeks.org/fundamentals-of-algorithms/#SearchingandSorting) | [Radix Sort](https://github.com/fluency03/leetcode-java/blob/master/src/sort/RadixSort.java) |\n|  | [Counting Sort](https://github.com/fluency03/leetcode-java/blob/master/src/sort/CountingSort.java) |\n|  | [Bucket Sort](https://github.com/fluency03/leetcode-java/blob/master/src/sort/BucketSort.java) |\n|  | Shell Sort |\n|  | Comb Sort |\n|  | [...](http://www.geeksforgeeks.org/fundamentals-of-algorithms/#SearchingandSorting) |\n\n\n\n# [Knapsack Problem](https://github.com/fluency03/leetcode-java/tree/master/src/knapsack)\n\n| Knapsack Problem |\n|:----------------------------------------------------------------------------------:|\n| [ZeroOneKnapsack](https://github.com/fluency03/leetcode-java/blob/master/src/knapsack/ZeroOneKnapsack.java) |\n| [CompleteKnapsack](https://github.com/fluency03/leetcode-java/blob/master/src/knapsack/CompleteKnapsack.java) |\n\n\n\n# [Data Structures](https://github.com/fluency03/leetcode-java/tree/master/src/data-structures)\n\n| Data Structures |\n|:----------------------------------------------------------------------------------:|\n| [TrieNode](https://github.com/fluency03/leetcode-java/blob/master/src/data-structures/TrieNode.java) |\n| [Trie](https://github.com/fluency03/leetcode-java/blob/master/src/data-structures/Trie.java) |\n| [LRUCache](https://github.com/fluency03/leetcode-java/blob/master/src/data-structures/LRUCache.java) |\n| [LFUCache](https://github.com/fluency03/leetcode-java/blob/master/src/data-structures/LFUCache.java) |\n| [BinarySearchTree](https://github.com/fluency03/leetcode-java/blob/master/src/data-structures/BinarySearchTree.java) |\n| [BinarySearchTreeWithParent](https://github.com/fluency03/leetcode-java/blob/master/src/data-structures/BinarySearchTreeWithParent.java) |\n| [BinaryIndexedTree](https://github.com/fluency03/leetcode-java/blob/master/src/data-structures/BinaryIndexedTree.java) |\n| [MinHeap](https://github.com/fluency03/leetcode-java/blob/master/src/data-structures/MinHeap.java) |\n| [DisjointSet (Union-Find)](https://github.com/fluency03/leetcode-java/blob/master/src/data-structures/DisjointSet.java) |\n| [Graph](https://github.com/fluency03/leetcode-java/blob/master/src/graph) |\n\n\n# Total: 538\n\n|   Easy  |  Medium | Hard |  -  |\n|:-------:|:-------:|:----:|:---:|\n|   142   |   292   |  92  | 12  |\n\n\n| Question | Solution | Difficulty |\n|------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------:|:----------:|\n| [1. Two Sum](https://leetcode.com/problems/two-sum/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/TwoSum1.java) | Easy |\n| [2. Add Two Numbers](https://leetcode.com/problems/add-two-numbers/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/AddTwoNumbers2.java) | Medium |\n| [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LongestSubstringWithoutRepeatingCharacters3.java) | Medium |\n| [4. Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MedianOfTwoSortedArrays4.java) | Hard |\n| [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LongestPalindromicSubstring5.java) | Medium |\n| [9. Palindrome Number](https://leetcode.com/problems/palindrome-number/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PalindromeNumber9.java) | Easy |\n| [8. String to Integer (atoi)](https://leetcode.com/problems/string-to-integer-atoi/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/StringToInteger8.java) | Medium |\n| [10. Regular Expression Matching](https://leetcode.com/problems/regular-expression-matching/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RegularExpressionMatching10.java) | Hard |\n| [11. Container With Most Water](https://leetcode.com/problems/container-with-most-water/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ContainerWithMostWater11.java) | Medium |\n| [12. Integer to Roman](https://leetcode.com/problems/integer-to-roman/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/IntegerToRoman12.java) | Medium |\n| [13. Roman to Integer](https://leetcode.com/problems/roman-to-integer/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RomanToInteger13.java) | Easy |\n| [14. Longest Common Prefix](https://leetcode.com/problems/longest-common-prefix/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LongestCommonPrefix14.java) | Easy |\n| [15. 3Sum](https://leetcode.com/problems/3sum/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ThreeSum15.java) | Medium |\n| [16. 3Sum Closest](https://leetcode.com/problems/3sum-closest/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ThreeSumClosest16.java) | Medium |\n| [17. Letter Combinations of a Phone Number](https://leetcode.com/problems/letter-combinations-of-a-phone-number/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LetterCombinationsOfAPhoneNumber17.java) | Medium |\n| [18. 4Sum](https://leetcode.com/problems/4sum/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FourSum18.java) | Medium |\n| [19. Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LetterCombinationsOfAPhoneNumber17.java) | Medium |\n| [20. Valid Parentheses](https://leetcode.com/problems/valid-parentheses/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ValidParentheses20.java) | Easy |\n| [21. Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MergeTwoSortedLists21.java) | Easy |\n| [22. Generate Parentheses](https://leetcode.com/problems/generate-parentheses/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/GenerateParentheses22.java) | Medium |\n| [23. Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MergeKSortedLists23.java) | Hard |\n| [25. Reverse Nodes in k-Group](https://leetcode.com/problems/reverse-nodes-in-k-group/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ReverseNodesInKGroup25.java) | Hard |\n| [26. Remove Duplicates from Sorted Array](https://leetcode.com/problems/remove-duplicates-from-sorted-array/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RemoveDuplicatesFromSortedArray26.java) | Easy |\n| [28. Implement strStr()](https://leetcode.com/problems/implement-strstr/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ImplementStrStr28.java) | Easy |\n| [29. Divide Two Integers](https://leetcode.com/problems/divide-two-integers/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DivideTwoIntegers29.java) | Easy |\n| [31. Next Permutation](https://leetcode.com/problems/next-permutation/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NextPermutation31.java) | Medium |\n| [32. Longest Valid Parentheses](https://leetcode.com/problems/longest-valid-parentheses/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LongestValidParentheses32.java) | Hard |\n| [33. Search in Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SearchInRotatedSortedArray33.java) | Medium |\n| [34. Search for a Range](https://leetcode.com/problems/search-for-a-range/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SearchForARange34.java) | Medium |\n| [35. Search Insert Position](https://leetcode.com/problems/search-insert-position/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SearchInsertPosition35.java) | Easy |\n| [36. Valid Sudoku](https://leetcode.com/problems/valid-sudoku/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ValidSudoku36.java) | Medium |\n| [37. Sudoku Solver](https://leetcode.com/problems/sudoku-solver/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SudokuSolver37.java) | Hard |\n| [39. Combination Sum](https://leetcode.com/problems/combination-sum/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CombinationSum39.java) | Medium |\n| [41. First Missing Positive](https://leetcode.com/problems/first-missing-positive/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FirstMissingPositive41.java) | Hard |\n| [42. Trapping Rain Water](https://leetcode.com/problems/trapping-rain-water/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/TrappingRainWater42.java) | Hard |\n| [44. Wildcard Matching](https://leetcode.com/problems/wildcard-matching/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/WildcardMatching44.java) | Hard |\n| [45. Jump Game II](https://leetcode.com/problems/jump-game-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/JumpGameII45.java) | Hard |\n| [46. Permutations](https://leetcode.com/problems/permutations/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/Permutations46.java) | Medium |\n| [47. Permutations II](https://leetcode.com/problems/permutations-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PermutationsII47.java) | Medium |\n| [48. Rotate Image](https://leetcode.com/problems/rotate-image/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RotateImage48.java) | Medium |\n| [49. Group Anagrams](https://leetcode.com/problems/group-anagrams/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/GroupAnagrams49.java) | Medium |\n| [50. Pow(x, n)](https://leetcode.com/problems/powx-n/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PowXN50.java) | Medium |\n| [51. N-Queens](https://leetcode.com/problems/n-queens/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NQueens51.java) | Hard |\n| [52. N-Queens II](https://leetcode.com/problems/n-queens-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NQueensII52.java) | Hard |\n| [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximumSubarray53.java) | Easy |\n| [54. Spiral Matrix](https://leetcode.com/problems/spiral-matrix/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SpiralMatrix54.java) | Medium |\n| [55. Jump Game](https://leetcode.com/problems/jump-game/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/JumpGame55.java) | Medium |\n| [56. Merge Intervals](https://leetcode.com/problems/merge-intervals/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MergeIntervals56.java) | Medium |\n| [57. Insert Interval](https://leetcode.com/problems/insert-interval/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/InsertInterval57.java) | Hard |\n| [59. Spiral Matrix II](https://leetcode.com/problems/spiral-matrix-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SpiralMatrixII59.java) | Medium |\n| [60. Permutation Sequence](https://leetcode.com/problems/permutation-sequence/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PermutationSequence60.java) | Medium |\n| [61. Rotate List](https://leetcode.com/problems/rotate-list/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RotateList61.java) | Medium |\n| [62. Unique Paths](https://leetcode.com/problems/unique-paths/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/UniquePaths62.java) | Medium |\n| [63. Unique Paths II](https://leetcode.com/problems/unique-paths-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/UniquePathsII63.java) | Medium |\n| [64. Minimum Path Sum](https://leetcode.com/problems/minimum-path-sum/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MinimumPathSum64.java) | Medium |\n| [65. Valid Number](https://leetcode.com/problems/valid-number/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ValidNumber65.java) | Hard |\n| [66. Plus One](https://leetcode.com/problems/plus-one/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PlusOne66.java) | Easy |\n| [67. Add Binary](https://leetcode.com/problems/add-binary/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/AddBinary67.java) | Easy |\n| [68. Text Justification](https://leetcode.com/problems/text-justification/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/TextJustification68.java) | Hard |\n| [69. Sqrt(x)](https://leetcode.com/problems/sqrtx/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SqrtX69.java) | Easy |\n| [70. Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ClimbingStairs70.java) | Easy |\n| [71. Simplify Path](https://leetcode.com/problems/simplify-path/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SimplifyPath71.java) | Medium |\n| [72. Edit Distance](https://leetcode.com/problems/edit-distance/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/EditDistance72.java) | Hard |\n| [73. Set Matrix Zeroes](https://leetcode.com/problems/set-matrix-zeroes/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SetMatrixZeroes73.java) | Medium |\n| [74. Search a 2D Matrix](https://leetcode.com/problems/search-a-2d-matrix/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SearchA2DMatrix74.java) | Medium |\n| [75. Sort Colors](https://leetcode.com/problems/sort-colors/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SortColors75.java) | Medium |\n| [76. Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MinimumWindowSubstring76.java) | Hard |\n| [78. Subsets](https://leetcode.com/problems/subsets/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/Subsets78.java) | Medium |\n| [79. Word Search](https://leetcode.com/problems/word-search/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/WordSearch79.java) | Medium |\n| [80. Remove Duplicates from Sorted Array II](https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RemoveDuplicatesFromSortedArrayII80.java) | Medium |\n| [81. Search in Rotated Sorted Array II](https://leetcode.com/problems/search-in-rotated-sorted-array-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SearchInRotatedSortedArrayII81.java) | Medium |\n| [82. Remove Duplicates from Sorted List II](https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RemoveDuplicatesFromSortedListII82.java) | Medium |\n| [83. Remove Duplicates from Sorted List](https://leetcode.com/problems/remove-duplicates-from-sorted-list/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RemoveDuplicatesFromSortedList83.java) | Easy |\n| [84. Largest Rectangle in Histogram](https://leetcode.com/problems/largest-rectangle-in-histogram/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LargestRectangleInHistogram84.java) | Hard |\n| [85. Maximal Rectangle](https://leetcode.com/problems/maximal-rectangle/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LargestRectangleInHistogram84.java) | Hard |\n| [86. Partition List](https://leetcode.com/problems/partition-list/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PartitionList86.java) | Medium |\n| [88. Merge Sorted Array](https://leetcode.com/problems/merge-sorted-array/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MergeSortedArray88.java) | Easy |\n| [90. Subsets II](https://leetcode.com/problems/subsets-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SubsetsII90.java) | Medium |\n| [91. Decode Ways](https://leetcode.com/problems/decode-ways/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DecodeWays91.java) | Medium |\n| [92. Reverse Linked List II](https://leetcode.com/problems/reverse-linked-list-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ReverseLinkedListII92.java) | Medium |\n| [93. Restore IP Addresses](https://leetcode.com/problems/restore-ip-addresses/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RestoreIPAddresses93.java) | Medium |\n| [94. Binary Tree Inorder Traversal](https://leetcode.com/problems/binary-tree-inorder-traversal/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BinaryTreeInorderTraversal94.java) | Medium |\n| [95. Unique Binary Search Trees II](https://leetcode.com/problems/unique-binary-search-trees-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/UniqueBinarySearchTreesII95.java) | Medium |\n| [96. Unique Binary Search Trees](https://leetcode.com/problems/unique-binary-search-trees/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/UniqueBinarySearchTrees96.java) | Medium |\n| [97. Interleaving String](https://leetcode.com/problems/interleaving-string/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/InterleavingString97.java) | Hard |\n| [98. Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ValidateBinarySearchTree98.java) | Medium |\n| [100. Same Tree](https://leetcode.com/problems/same-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SameTree100.java) | Easy |\n| [101. Symmetric Tree](https://leetcode.com/problems/symmetric-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SymmetricTree101.java) | Easy |\n| [102. Binary Tree Level Order Traversal](https://leetcode.com/problems/binary-tree-level-order-traversal/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BinaryTreeLevelOrderTraversal102.java) | Medium |\n| [103. Binary Tree Zigzag Level Order Traversal](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BinaryTreeZigzagLevelOrderTraversal103.java) | Medium |\n| [104. Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximumDepthOfBinaryTree104.java) | Easy |\n| [105. Construct Binary Tree from Preorder and Inorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ConstructBinaryTreeFromPreorderAndInorderTraversal105.java) | Medium |\n| [106. Construct Binary Tree from Inorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ConstructBinaryTreeFromInorderAndPostorderTraversal106.java) | Medium |\n| [107. Binary Tree Level Order Traversal II](https://leetcode.com/problems/binary-tree-level-order-traversal-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BinaryTreeLevelOrderTraversalII107.java) | Easy |\n| [108. Convert Sorted Array to Binary Search Tree](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ConvertSortedArrayToBinarySearchTree108.java) | Easy |\n| [109. Convert Sorted List to Binary Search Tree](https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ConvertSortedListToBST109.java) | Medium |\n| [110. Balanced Binary Tree](https://leetcode.com/problems/balanced-binary-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BalancedBinaryTree110.java) | Easy |\n| [111. Minimum Depth of Binary Tree](https://leetcode.com/problems/minimum-depth-of-binary-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MinimumDepthOfBinaryTree111.java) | Easy |\n| [112. Path Sum](https://leetcode.com/problems/path-sum/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PathSum112.java) | Easy |\n| [113. Path Sum II](https://leetcode.com/problems/path-sum-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PathSumII113.java) | Medium |\n| [114. Flatten Binary Tree to Linked List](https://leetcode.com/problems/flatten-binary-tree-to-linked-list/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FlattenBinaryTreeToLinkedList114.java) | Medium |\n| [116. Populating Next Right Pointers in Each Node](https://leetcode.com/problems/populating-next-right-pointers-in-each-node/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PopulatingNextRightPointersInEachNode116.java) | Medium |\n| [117. Populating Next Right Pointers in Each Node II](https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PopulatingNextRightPointersInEachNodeII117.java) | Medium |\n| [119. Pascal's Triangle II](https://leetcode.com/problems/pascals-triangle-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PascalsTriangleII119.java) | Easy |\n| [120. Triangle](https://leetcode.com/problems/triangle/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/Triangle120.java) | Medium |\n| [121. Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BestTimeToBuyAndSellStock121.java) | Easy |\n| [122. Best Time to Buy and Sell Stock II](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BestTimeToBuyAndSellStockII122.java) | Easy |\n| [123. Best Time to Buy and Sell Stock III](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BestTimeToBuyAndSellStockIII123.java) | Hard |\n| [124. Binary Tree Maximum Path Sum](https://leetcode.com/problems/binary-tree-maximum-path-sum/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BinaryTreeMaximumPathSum124.java) | Hard |\n| [125. Valid Palindrome](https://leetcode.com/problems/valid-palindrome/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ValidPalindrome125.java) | Easy |\n| [126. Word Ladder II](https://leetcode.com/problems/word-ladder-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/WordLadderII126.java) | Hard |\n| [127. Word Ladder](https://leetcode.com/problems/word-ladder/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/WordLadder127.java) | Medium |\n| [128. Longest Consecutive Sequence](https://leetcode.com/problems/longest-consecutive-sequence/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LongestConsecutiveSequence128.java) | Hard |\n| [129. Sum Root to Leaf Numbers](https://leetcode.com/problems/sum-root-to-leaf-numbers/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SumRootToLeafNumbers129.java) | Medium |\n| [130. Surrounded Regions](https://leetcode.com/problems/surrounded-regions/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SumRootToLeafNumbers129.java) | Medium |\n| [131. Palindrome Partitioning](https://leetcode.com/problems/palindrome-partitioning/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PalindromePartitioning131.java) | Medium |\n| [133. Clone Graph](https://leetcode.com/problems/clone-graph/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CloneGraph133.java) | Medium |\n| [136. Single Number](https://leetcode.com/problems/single-number/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SingleNumber136.java) | Easy |\n| [137. Single Number II](https://leetcode.com/problems/single-number-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SingleNumberII137.java) | Medium |\n| [138. Copy List with Random Pointer](https://leetcode.com/problems/copy-list-with-random-pointer/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CopyListWithRandomPointer138.java) | Medium |\n| [139. Word Break](https://leetcode.com/problems/word-break/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/WordBreak139.java) | Medium |\n| [140. Word Break II](https://leetcode.com/problems/word-break-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/WordBreakII140.java) | Hard |\n| [141. Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LinkedListCycle141.java) | Easy |\n| [142. Linked List Cycle II](https://leetcode.com/problems/linked-list-cycle-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LinkedListCycleII142.java) | Easy |\n| [143. Reorder List](https://leetcode.com/problems/reorder-list/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ReorderList143.java) | Medium |\n| [144. Binary Tree Preorder Traversal](https://leetcode.com/problems/binary-tree-preorder-traversal/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BinaryTreePreorderTraversal144.java) | Medium |\n| [146. LRU Cache](https://leetcode.com/problems/lru-cache/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LRUCache146.java) | Hard |\n| [147. Insertion Sort List](https://leetcode.com/problems/insertion-sort-list/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/InsertionSortList147.java) | Medium |\n| [148. Sort List](https://leetcode.com/problems/sort-list/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SortList148.java) | Medium |\n| [149. Max Points on a Line](https://leetcode.com/problems/max-points-on-a-line/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/InsertionSortList147.java) | Hard |\n| [150. Evaluate Reverse Polish Notation](https://leetcode.com/problems/evaluate-reverse-polish-notation/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/EvaluateReversePolishNotation150.java) | Medium |\n| [151. Reverse Words in a String](https://leetcode.com/problems/reverse-words-in-a-string/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ReverseWordsInAString151.java) | Medium |\n| [152. Maximum Product Subarray](https://leetcode.com/problems/maximum-product-subarray/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximumProductSubarray152.java) | Medium |\n| [153. Find Minimum in Rotated Sorted Array](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindMinimumInRotatedSortedArray153.java) | Medium |\n| [154. Find Minimum in Rotated Sorted Array II](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindMinimumInRotatedSortedArrayII154.java) | Hard |\n| [155. Min Stack](https://leetcode.com/problems/min-stack/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MinStack.java) | Easy |\n| [157. Read N Characters Given Read4](https://leetcode.com/problems/read-n-characters-given-read4/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ReadNCharactersGivenReadFour157.java) | Easy |\n| [158. Read N Characters Given Read4 II - Call multiple times](https://leetcode.com/problems/read-n-characters-given-read4-ii-call-multiple-times/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ReadNCharactersGivenRead4IICallMultipleTimes158.java) | Hard |\n| [159. Longest Substring with At Most Two Distinct Characters](https://leetcode.com/problems/longest-substring-with-at-most-two-distinct-characters/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LongestSubstringWithAtMostTwoDistinctCharacters159.java) | Hard |\n| [160. Intersection of Two Linked Lists](https://leetcode.com/problems/intersection-of-two-linked-lists/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/IntersectionOfTwoLinkedLists160.java) | Easy |\n| [161. One Edit Distance](https://leetcode.com/problems/one-edit-distance/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/OneEditDistance161.java) | Medium |\n| [162. Find Peak Element](https://leetcode.com/problems/find-peak-element/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindPeakElement162.java) | Medium |\n| [163. Missing Ranges](https://leetcode.com/problems/missing-ranges/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MissingRanges163.java) | Medium |\n| [165. Compare Version Numbers](https://leetcode.com/problems/compare-version-numbers/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CompareVersionNumbers165.java) | Medium |\n| [166. Fraction to Recurring Decimal](https://leetcode.com/problems/fraction-to-recurring-decimal/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FractionToRecurringDecimal166.java) | Medium |\n| [167. Two Sum II - Input array is sorted](https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/TwoSumIIInputArrayIsSorted167.java) | Easy |\n| [169. Majority Element](https://leetcode.com/problems/majority-element/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MajorityElement169.java) | Easy |\n| [173. Binary Search Tree Iterator](https://leetcode.com/problems/binary-search-tree-iterator/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BinarySearchTreeIterator173.java) | Medium |\n| [179. Largest Number](https://leetcode.com/problems/largest-number/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LargestNumber179.java) | Medium |\n| [186. Reverse Words in a String II](https://leetcode.com/problems/reverse-words-in-a-string-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ReverseWordsInAStringII186.java) | Easy |\n| [187. Repeated DNA Sequences](https://leetcode.com/problems/repeated-dna-sequences/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RepeatedDNASequences187.java) | Medium |\n| [188. Best Time to Buy and Sell Stock IV](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BestTimeToBuyAndSellStockIV188.java) | Hard |\n| [189. Rotate Array](https://leetcode.com/problems/rotate-array/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RotateArray189.java) | Easy |\n| [198. House Robber](https://leetcode.com/problems/house-robber/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/HouseRobber198.java) | Easy |\n| [199. Binary Tree Right Side View](https://leetcode.com/problems/binary-tree-right-side-view/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BinaryTreeRightSideView199.java) | Medium |\n| [200. Number of Islands](https://leetcode.com/problems/number-of-islands/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NumberOfIslands200.java) | Medium |\n| [201. Bitwise AND of Numbers Range](https://leetcode.com/problems/bitwise-and-of-numbers-range/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BitwiseANDOfNumbersRange201.java) | Medium |\n| [202. Happy Number](https://leetcode.com/problems/happy-number/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/HappyNumber202.java) | Easy |\n| [203. Remove Linked List Elements](https://leetcode.com/problems/remove-linked-list-elements/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RemoveLinkedListElements203.java) | Easy |\n| [204. Count Primes](https://leetcode.com/problems/count-primes/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CountPrimes204.java) | Easy |\n| [205. Isomorphic Strings](https://leetcode.com/problems/isomorphic-strings/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/IsomorphicStrings205.java) | Easy |\n| [206. Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ReverseLinkedList206.java) | Easy |\n| [207. Course Schedule](https://leetcode.com/problems/course-schedule/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CourseSchedule207.java) | Medium |\n| [208. Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ImplementTriePrefixTree208.java) | Medium |\n| [209. Minimum Size Subarray Sum](https://leetcode.com/problems/minimum-size-subarray-sum/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MinimumSizeSubarraySum209.java) | Medium |\n| [210. Course Schedule II](https://leetcode.com/problems/course-schedule-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CourseScheduleII210.java) | Medium |\n| [211. Add and Search Word - Data structure design](https://leetcode.com/problems/add-and-search-word-data-structure-design/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/WordDictionary.java) | Medium |\n| [212. Word Search II](https://leetcode.com/problems/word-search-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/WordSearchII212.java) | Hard |\n| [213. House Robber II](https://leetcode.com/problems/house-robber-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/HouseRobberII213.java) | Medium |\n| [214. Shortest Palindrome](https://leetcode.com/problems/shortest-palindrome/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ShortestPalindrome214.java) | Medium |\n| [215. Kth Largest Element in an Array](https://leetcode.com/problems/kth-largest-element-in-an-array/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/KthLargestElementInAnArray215.java) | Medium |\n| [216. Combination Sum III](https://leetcode.com/problems/combination-sum-iii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CombinationSumIII216.java) | Medium |\n| [217. Contains Duplicate](https://leetcode.com/problems/contains-duplicate/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ContainsDuplicate217.java) | Easy |\n| [218. The Skyline Problem](https://leetcode.com/problems/the-skyline-problem/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/TheSkylineProblem218.java) | Hard |\n| [219. Contains Duplicate II](https://leetcode.com/problems/contains-duplicate-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ContainsDuplicatesII219.java) | Easy |\n| [220. Contains Duplicate III](https://leetcode.com/problems/contains-duplicate-iii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ContainsDuplicateIII220.java) | Medium |\n| [221. Maximal Square](https://leetcode.com/problems/maximal-square/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximalSquare221.java) | Medium |\n| [223. Rectangle Area](https://leetcode.com/problems/rectangle-area/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximalSquare221.java) | Medium |\n| [224. Basic Calculator](https://leetcode.com/problems/basic-calculator/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BasicCalculator224.java) | Hard |\n| [225. Implement Stack using Queues](https://leetcode.com/problems/implement-stack-using-queues/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ImplementStackUsingQueues225.java) | Easy |\n| [226. Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/InvertBinaryTree226.java) | Easy |\n| [227. Basic Calculator II](https://leetcode.com/problems/basic-calculator-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BasicCalculatorII227.java) | Medium |\n| [228. Summary Ranges](https://leetcode.com/problems/summary-ranges/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SummaryRanges228.java) | Medium |\n| [230. Kth Smallest Element in a BST](https://leetcode.com/problems/kth-smallest-element-in-a-bst/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/KthSmallestElementInABST230.java) | Medium |\n| [231. Power of Two](https://leetcode.com/problems/power-of-two/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PowerOfTwo231.java) | Easy |\n| [232. Implement Queue using Stacks](https://leetcode.com/problems/implement-queue-using-stacks/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ImplementQueueUsingStacks232.java) | Easy |\n| [233. Number of Digit One](https://leetcode.com/problems/number-of-digit-one/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NumberOfDigitOne233.java) | Hard |\n| [234. Palindrome Linked List](https://leetcode.com/problems/palindrome-linked-list/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PalindromeLinkedList234.java) | Easy |\n| [235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LowestCommonAncestorOfABinarySearchTree235.java) | Easy |\n| [236. Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LowestCommonAncestorOfABinaryTree236.java) | Medium |\n| [237. Delete Node in a Linked List](https://leetcode.com/problems/delete-node-in-a-linked-list/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DeleteNodeInALinkedList237.java) | Easy |\n| [238. Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ProductOfArrayExceptSelf238.java) | Medium |\n| [239. Sliding Window Maximum](https://leetcode.com/problems/sliding-window-maximum/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SlidingWindowMaximum239.java) | Hard |\n| [240. Search a 2D Matrix II](https://leetcode.com/problems/search-a-2d-matrix-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SearchA2DMatrixII240.java) | Medium |\n| [241. Different Ways to Add Parentheses](https://leetcode.com/problems/different-ways-to-add-parentheses/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DifferentWaysToAddParentheses241.java) | Medium |\n| [242. Valid Anagram](https://leetcode.com/problems/valid-anagram/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ValidAnagram242.java) | Easy |\n| [243. Shortest Word Distance](https://leetcode.com/problems/shortest-word-distance/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ShortestWordDistance243.java) | Easy |\n| [246. Strobogrammatic Number](https://leetcode.com/problems/strobogrammatic-number/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/StrobogrammaticNumber246.java) | Easy |\n| [247. Strobogrammatic Number II](https://leetcode.com/problems/strobogrammatic-number-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/StrobogrammaticNumberII247.java) | Medium |\n| [249. Group Shifted Strings](https://leetcode.com/problems/group-shifted-strings/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/GroupShiftedStrings249.java) | Medium |\n| [251. Flatten 2D Vector](https://leetcode.com/problems/flatten-2d-vector/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/Flatten2DVector251.java) | Medium |\n| [252. Meeting Rooms](https://leetcode.com/problems/meeting-rooms/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MeetingRooms252.java) | Easy |\n| [253. Meeting Rooms II](https://leetcode.com/problems/meeting-rooms-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MeetingRoomsII253.java) | Medium |\n| [255. Verify Preorder Sequence in Binary Search Tree](https://leetcode.com/problems/verify-preorder-sequence-in-binary-search-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/VerifyPreorderSequenceInBinarySearchTree255.java) | Medium |\n| [256. Paint House](https://leetcode.com/problems/paint-house/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PaintHouse256.java) | Easy |\n| [257. Binary Tree Paths](https://leetcode.com/problems/binary-tree-paths/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BinaryTreePaths257.java) | Easy |\n| [259. 3Sum Smaller](https://leetcode.com/problems/3sum-smaller/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ThreeSumSmaller259.java) | Medium |\n| [261. Graph Valid Tree](https://leetcode.com/problems/graph-valid-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/GraphValidTree261.java) | Medium |\n| [263. Ugly Number](https://leetcode.com/problems/ugly-number/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/UglyNumber263.java) | Easy |\n| [264. Ugly Number II](https://leetcode.com/problems/ugly-number-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/UglyNumberII264.java) | Medium |\n| [265. Paint House II](https://leetcode.com/problems/paint-house-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PaintHouseII265.java) | Hard |\n| [267. Palindrome Permutation II](https://leetcode.com/problems/palindrome-permutation-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PalindromePermutationII267.java) | Medium |\n| [268. Missing Number](https://leetcode.com/problems/missing-number/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MissingNumber268.java) | Easy |\n| [269. Alien Dictionary](https://leetcode.com/problems/alien-dictionary/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/AlienDictionary269.java) | Hard |\n| [270. Closest Binary Search Tree Value](https://leetcode.com/problems/closest-binary-search-tree-value/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ClosestBinarySearchTreeValue270.java) | Easy |\n| [271. Encode and Decode Strings](https://leetcode.com/problems/encode-and-decode-strings/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/EncodeAndDecodeStrings271.java) | Medium |\n| [272. Closest Binary Search Tree Value II](https://leetcode.com/problems/closest-binary-search-tree-value-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ClosestBinarySearchTreeValueII272.java) | Medium |\n| [273. Integer to English Words](https://leetcode.com/problems/integer-to-english-words/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/IntegerToEnglishWords273.java) | Hard |\n| [274. H-Index](https://leetcode.com/problems/h-index/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/IntegerToEnglishWords273.java) | Medium |\n| [276. Paint Fence](https://leetcode.com/problems/paint-fence/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PaintFence276.java) | Easy |\n| [277. Find the Celebrity](https://leetcode.com/problems/find-the-celebrity/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindTheCelebrity277.java) | Medium |\n| [278. First Bad Version](https://leetcode.com/problems/first-bad-version/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FirstBadVersion278.java) | Easy |\n| [279. Perfect Squares](https://leetcode.com/problems/perfect-squares/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PerfectSquares279.java) | Medium |\n| [280. Wiggle Sort](https://leetcode.com/problems/wiggle-sort/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/WiggleSort280.java) | Medium |\n| [281. Zigzag Iterator](https://leetcode.com/problems/zigzag-iterator/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ZigzagIterator281.java) | Medium |\n| [282. Expression Add Operators](https://leetcode.com/problems/expression-add-operators/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ExpressionAddOperators282.java) | Hard |\n| [283. Move Zeroes](https://leetcode.com/problems/move-zeroes/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MoveZeroes283.java) | Easy |\n| [284. Peeking Iterator](https://leetcode.com/problems/peeking-iterator/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PeekingIterator284.java) | Medium |\n| [285. Inorder Successor in BST](https://leetcode.com/problems/inorder-successor-in-bst/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/InorderSuccessorInBST285.java) | Medium |\n| [286. Walls and Gates](https://leetcode.com/problems/walls-and-gates/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/WallsAndGates286.java) | Medium |\n| [287. Find the Duplicate Number](https://leetcode.com/problems/find-the-duplicate-number/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindTheDuplicateNumber287.java) | Medium |\n| [288. Unique Word Abbreviation](https://leetcode.com/problems/unique-word-abbreviation/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/UniqueWordAbbreviation288.java) | Medium |\n| [289. Game of Life](https://leetcode.com/problems/game-of-life/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/GameOfLife289.java) | Medium |\n| [290. Word Pattern](https://leetcode.com/problems/word-pattern/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/WordPattern290.java) | Easy |\n| [291. Word Pattern II](https://leetcode.com/problems/word-pattern-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/WordPatternII291.java) | Hard |\n| [293. Flip Game](https://leetcode.com/problems/flip-game/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FlipGame293.java) | Easy |\n| [295. Find Median from Data Stream](https://leetcode.com/problems/find-median-from-data-stream/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindMedianFromDataStream295.java) | Hard |\n| [296. Best Meeting Point](https://leetcode.com/problems/best-meeting-point/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BestMeetingPoint296.java) | Hard |\n| [297. Serialize and Deserialize Binary Tree](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SerializeAndDeserializeBinaryTree297.java) | Hard |\n| [298. Binary Tree Longest Consecutive Sequence](https://leetcode.com/problems/binary-tree-longest-consecutive-sequence/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BinaryTreeLongestConsecutiveSequence298.java) | Medium |\n| [299. Bulls and Cows](https://leetcode.com/problems/bulls-and-cows/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BullsAndCows299.java) | Medium |\n| [300. Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LongestIncreasingSubsequence300.java) | Medium |\n| [301. Remove Invalid Parentheses](https://leetcode.com/problems/remove-invalid-parentheses/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RemoveInvalidParentheses301.java) | Hard |\n| [303. Range Sum Query - Immutable](https://leetcode.com/problems/range-sum-query-immutable/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RangeSumQueryImmutable303.java) | Easy |\n| [304. Range Sum Query 2D - Immutable](https://leetcode.com/problems/range-sum-query-2d-immutable/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RangeSumQuery2DImmutable304.java) | Medium |\n| [305. Number of Islands II](https://leetcode.com/problems/number-of-islands-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NumberOfIslandsII305.java) | Hard |\n| [307. Range Sum Query - Mutable](https://leetcode.com/problems/range-sum-query-mutable/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RangeSumQueryMutable307.java) | Medium |\n| [308. Range Sum Query 2D - Mutable](https://leetcode.com/problems/range-sum-query-2d-mutable/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RangeSumQuery2DMutable308.java) | Hard |\n| [309. Best Time to Buy and Sell Stock with Cooldown](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BestTimeToBuyAndSellStockWithCooldown309.java) | Medium |\n| [310. Minimum Height Trees](https://leetcode.com/problems/minimum-height-trees/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MinimumHeightTrees310.java) | Medium |\n| [311. Sparse Matrix Multiplication](https://leetcode.com/problems/sparse-matrix-multiplication/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SparseMatrixMultiplication311.java) | Medium |\n| [312. Burst Balloons](https://leetcode.com/problems/burst-balloons/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BurstBalloons312.java) | Hard |\n| [313. Super Ugly Number](https://leetcode.com/problems/super-ugly-number/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SuperUglyNumber313.java) | Medium |\n| [314. Binary Tree Vertical Order Traversal](https://leetcode.com/problems/binary-tree-vertical-order-traversal/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BinaryTreeVerticalOrderTraversal314.java) | Medium |\n| [315. Count of Smaller Numbers After Self](https://leetcode.com/problems/count-of-smaller-numbers-after-self/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CountOfSmallerNumbersAfterSelf315.java) | Hard |\n| [317. Shortest Distance from All Buildings](https://leetcode.com/problems/shortest-distance-from-all-buildings/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ShortestDistanceFromAllBuildings317.java) | Hard |\n| [318. Maximum Product of Word Lengths](https://leetcode.com/problems/maximum-product-of-word-lengths/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximumProductOfWordLengths318.java) | Medium |\n| [320. Generalized Abbreviation](https://leetcode.com/problems/generalized-abbreviation/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/GeneralizedAbbreviation320.java) | Medium |\n| [322. Coin Change](https://leetcode.com/problems/coin-change/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CountOfSmallerNumbersAfterSelf315.java) | Medium |\n| [323. Number of Connected Components in an Undirected Graph](https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NumberOfConnectedComponentsInAnUndirectedGraph323.java) | Medium |\n| [324. Wiggle Sort II](https://leetcode.com/problems/wiggle-sort-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/WiggleSortII324.java) | Medium |\n| [325. Maximum Size Subarray Sum Equals k](https://leetcode.com/problems/maximum-size-subarray-sum-equals-k/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximumSizeSubarraySumEqualsK325.java) | Medium |\n| [327. Count of Range Sum](https://leetcode.com/problems/count-of-range-sum/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CountOfRangeSum327.java) | Hard |\n| [328. Odd Even Linked List](https://leetcode.com/problems/odd-even-linked-list/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/OddEvenLinkedList328.java) | Medium |\n| [332. Reconstruct Itinerary](https://leetcode.com/problems/reconstruct-itinerary/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ReconstructItinerary332.java) | Medium |\n| [333. Largest BST Subtree](https://leetcode.com/problems/largest-bst-subtree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LargestBSTSubtree333.java) | Medium |\n| [334. Increasing Triplet Subsequence](https://leetcode.com/problems/increasing-triplet-subsequence/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/IncreasingTripletSubsequence334.java) | Medium |\n| [336. Palindrome Pairs](https://leetcode.com/problems/palindrome-pairs/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PalindromePairs336.java) | Hard |\n| [337. House Robber III](https://leetcode.com/problems/house-robber-iii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/HouseRobberIII337.java) | Medium |\n| [338. Counting Bits](https://leetcode.com/problems/counting-bits/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CountingBits338.java) | Medium |\n| [339. Nested List Weight Sum](https://leetcode.com/problems/nested-list-weight-sum/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NestedListWeightSum339.java) | Easy |\n| [340. Longest Substring with At Most K Distinct Characters](https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LongestSubstringWithAtMostKDistinctCharacters340.java) | Hard |\n| [341. Flatten Nested List Iterator](https://leetcode.com/problems/flatten-nested-list-iterator/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NestedIterator.java) | Medium |\n| [343. Integer Break](https://leetcode.com/problems/integer-break/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/IntegerBreak343.java) | Medium |\n| [344. Reverse String](https://leetcode.com/problems/reverse-string/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ReverseString344.java) | Easy |\n| [345. Reverse Vowels of a String](https://leetcode.com/problems/reverse-vowels-of-a-string/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ReverseVowelsOfAString345.java) | Easy |\n| [346. Moving Average from Data Stream](https://leetcode.com/problems/moving-average-from-data-stream/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MovingAverageFromDataStream346.java) | Easy |\n| [347. Top K Frequent Elements](https://leetcode.com/problems/top-k-frequent-elements/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/TopKFrequentElements347.java) | Medium |\n| [348. Design Tic-Tac-Toe](https://leetcode.com/problems/design-tic-tac-toe/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DesignTicTacToe348.java) | Medium |\n| [349. Intersection of Two Arrays](https://leetcode.com/problems/intersection-of-two-arrays/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/IntersectionOfTwoArrays349.java) | Easy |\n| [350. Intersection of Two Arrays II](https://leetcode.com/problems/intersection-of-two-arrays-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/IntersectionOfTwoArraysII350.java) | Easy |\n| [351. Android Unlock Patterns](https://leetcode.com/problems/android-unlock-patterns/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/AndroidUnlockPatterns351.java) | Medium |\n| [352. Data Stream as Disjoint Intervals](https://leetcode.com/problems/data-stream-as-disjoint-intervals/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DataStreamAsDisjointIntervals352.java) | Hard |\n| [353. Design Snake Game](https://leetcode.com/problems/design-snake-game/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DesignSnakeGame353.java) | Medium |\n| [354. Russian Doll Envelopes](https://leetcode.com/problems/russian-doll-envelopes/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RussianDollEnvelopes354.java) | Hard |\n| [355. Design Twitter](https://leetcode.com/problems/design-twitter/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DesignTwitter355.java) | Medium |\n| [357. Count Numbers with Unique Digits](https://leetcode.com/problems/count-numbers-with-unique-digits/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CountNumbersWithUniqueDigits357.java) | Medium |\n| [358. Rearrange String k Distance Apart](https://leetcode.com/problems/rearrange-string-k-distance-apart/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RearrangeStringKDistanceApart358.java) | Hard |\n| [359. Logger Rate Limiter](https://leetcode.com/problems/logger-rate-limiter/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LoggerRateLimiter359.java) | Easy |\n| [360. Sort Transformed Array](https://leetcode.com/problems/sort-transformed-array/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SortTransformedArray360.java) | Medium |\n| [361. Bomb Enemy](https://leetcode.com/problems/bomb-enemy/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BombEnemy361.java) | Medium |\n| [362. Design Hit Counter](https://leetcode.com/problems/design-hit-counter/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DesignHitCounter362.java) | Medium |\n| [363. Max Sum of Rectangle No Larger Than K](https://leetcode.com/problems/max-sum-of-rectangle-no-larger-than-k/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaxSumOfRectangleNoLargerThanK363.java) | Hard |\n| [365. Water and Jug Problem](https://leetcode.com/problems/water-and-jug-problem/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/WaterAndJugProblem365.java) | Medium |\n| [368. Largest Divisible Subset](https://leetcode.com/problems/largest-divisible-subset/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LargestDivisibleSubset368.java) | Medium |\n| [369. Plus One Linked List](https://leetcode.com/problems/plus-one-linked-list/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PlusOneLinkedList369.java) | Medium |\n| [370. Range Addition](https://leetcode.com/problems/range-addition/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RangeAddition370.java) | Medium |\n| [373. Find K Pairs with Smallest Sums](https://leetcode.com/problems/find-k-pairs-with-smallest-sums/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindKPairsWithSmallestSums373.java) | Medium |\n| [375. Guess Number Higher or Lower II](https://leetcode.com/problems/guess-number-higher-or-lower-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/GuessNumberHigherOrLowerII375.java) | Medium |\n| [377. Combination Sum IV](https://leetcode.com/problems/combination-sum-iv/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CombinationSumIV377.java) | Medium |\n| [378. Kth Smallest Element in a Sorted Matrix](https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/KthSmallestElementInASortedMatrix378.java) | Medium |\n| [380. Insert Delete GetRandom O(1)](https://leetcode.com/problems/insert-delete-getrandom-o1/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/InsertDeleteGetRandomOOne380.java) | Medium |\n| [382. Linked List Random Node](https://leetcode.com/problems/linked-list-random-node/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LinkedListRandomNode382.java) | Medium |\n| [383. Ransom Note](https://leetcode.com/problems/ransom-note/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RansomNote383.java) | Easy |\n| [384. Shuffle an Array](https://leetcode.com/problems/shuffle-an-array/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ShuffleAnArray384.java) | Medium |\n| [386. Lexicographical Numbers](https://leetcode.com/problems/lexicographical-numbers/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LexicographicalNumbers386.java) | Medium |\n| [387. First Unique Character in a String](https://leetcode.com/problems/first-unique-character-in-a-string/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FirstUniqueCharacterInAString387.java) | Easy |\n| [388. Longest Absolute File Path](https://leetcode.com/problems/longest-absolute-file-path/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LongestAbsoluteFilePath388.java) | Medium |\n| [392. Is Subsequence](https://leetcode.com/problems/is-subsequence/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/IsSubsequence392.java) | Medium |\n| [393. UTF-8 Validation](https://leetcode.com/problems/utf-8-validation/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/UTF8Validation393.java) | Medium |\n| [394. Decode String](https://leetcode.com/problems/decode-string/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DecodeString394.java) | Medium |\n| [396. Rotate Function](https://leetcode.com/problems/rotate-function/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RotateFunction396.java) | Medium |\n| [399. Evaluate Division](https://leetcode.com/problems/evaluate-division/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/EvaluateDivision399.java) | Medium |\n| [403. Frog Jump](https://leetcode.com/problems/frog-jump/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FrogJump403.java) | Hard |\n| [405. Convert a Number to Hexadecimal](https://leetcode.com/problems/convert-a-number-to-hexadecimal/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ConvertANumberToHexadecimal405.java) | Easy |\n| [406. Queue Reconstruction by Height](https://leetcode.com/problems/queue-reconstruction-by-height/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/QueueReconstructionByHeight406.java) | Medium |\n| [407. Trapping Rain Water II](https://leetcode.com/problems/trapping-rain-water-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/TrappingRainWaterII407.java) | Medium |\n| [408. Valid Word Abbreviation](https://leetcode.com/problems/valid-word-abbreviation/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ValidWordAbbreviation408.java) | Easy |\n| [409. Longest Palindrome](https://leetcode.com/problems/longest-palindrome/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LongestPalindrome409.java) | Easy |\n| [410. Split Array Largest Sum](https://leetcode.com/problems/split-array-largest-sum/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SplitArrayLargestSum410.java) | Hard |\n| [412. Fizz Buzz](https://leetcode.com/problems/fizz-buzz/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FizzBuzz412.java) | Easy |\n| [414. Third Maximum Number](https://leetcode.com/problems/third-maximum-number/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ThirdMaximumNumber414.java) | Easy |\n| [415. Add Strings](https://leetcode.com/problems/add-strings/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/AddStrings415.java) | Easy |\n| [416. Partition Equal Subset Sum](https://leetcode.com/problems/partition-equal-subset-sum/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PartitionEqualSubsetSum416.java) | Medium |\n| [417. Pacific Atlantic Water Flow](https://leetcode.com/problems/pacific-atlantic-water-flow/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PacificAtlanticWaterFlow417.java) | Medium |\n| [418. Sentence Screen Fitting](https://leetcode.com/problems/sentence-screen-fitting/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SentenceScreenFitting418.java) | Medium |\n| [421. Maximum XOR of Two Numbers in an Array](https://leetcode.com/problems/maximum-xor-of-two-numbers-in-an-array/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximumXOROfTwoNumbersInAnArray421.java) | Medium |\n| [423. Reconstruct Original Digits from English](https://leetcode.com/problems/reconstruct-original-digits-from-english/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ReconstructOriginalDigitsFromEnglish423.java) | Medium |\n| [424. Longest Repeating Character Replacement](https://leetcode.com/problems/longest-repeating-character-replacement/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LongestRepeatingCharacterReplacement424.java) | Medium |\n| [425. Word Squares](https://leetcode.com/problems/word-squares/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/WordSquares425.java) | Hard |\n| [427. Construct Quad Tree](https://leetcode.com/problems/construct-quad-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ConstructQuadTree427.java) | Easy |\n| [429. N-ary Tree Level Order Traversal](https://leetcode.com/problems/n-ary-tree-level-order-traversal/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NaryTreeLevelOrderTraversal429.java) | Easy |\n| [432. All O`one Data Structure](https://leetcode.com/problems/all-oone-data-structure/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/AllOOneDataStructure432.java) | Hard |\n| [433. Minimum Genetic Mutation](https://leetcode.com/problems/minimum-genetic-mutation/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MinimumGeneticMutation433.java) | Medium |\n| [435. Non-overlapping Intervals](https://leetcode.com/problems/non-overlapping-intervals/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NonOverlappingIntervals435.java) | Medium |\n| [437. Path Sum III](https://leetcode.com/problems/path-sum-iii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PathSumIII437.java) | Easy |\n| [438. Find All Anagrams in a String](https://leetcode.com/problems/find-all-anagrams-in-a-string/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindAllAnagramsInAString438.java) | Easy |\n| [443. String Compression](https://leetcode.com/problems/string-compression/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/StringCompression443.java) | Easy |\n| [445. Add Two Numbers II](https://leetcode.com/problems/add-two-numbers-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/AddTwoNumbersII445.java) | Medium |\n| [448. Find All Numbers Disappeared in an Array](https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindAllNumbersDisappearedInAnArray448.java) | Easy |\n| [449. Serialize and Deserialize BST](https://leetcode.com/problems/serialize-and-deserialize-bst/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SerializeAndDeserializeBST449.java) | Medium |\n| [450. Delete Node in a BST](https://leetcode.com/problems/delete-node-in-a-bst/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DeleteNodeInABST450.java) | Medium |\n| [454. 4Sum II](https://leetcode.com/problems/4sum-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FourSumII454.java) | Medium |\n| [451. Sort Characters By Frequency](https://leetcode.com/problems/sort-characters-by-frequency/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SortCharactersByFrequency451.java) | Medium |\n| [459. Repeated Substring Pattern](https://leetcode.com/problems/repeated-substring-pattern/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RepeatedSubstringPattern459.java) | Easy |\n| [460. LFU Cache](https://leetcode.com/problems/lfu-cache/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LFUCache460.java) | Hard |\n| [462. Minimum Moves to Equal Array Elements II](https://leetcode.com/problems/minimum-moves-to-equal-array-elements-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MinimumMovesToEqualArrayElementsII462.java) | Medium |\n| [463. Island Perimeter](https://leetcode.com/problems/island-perimeter/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/IslandPerimeter463.java) | Easy |\n| [464. Can I Win](https://leetcode.com/problems/can-i-win/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CanIWin464.java) | Medium |\n| [465. Optimal Account Balancing](https://leetcode.com/problems/optimal-account-balancing/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/OptimalAccountBalancing465.java) | Hard |\n| [472. Concatenated Words](https://leetcode.com/problems/concatenated-words/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ConcatenatedWords472.java) | Hard |\n| [473. Matchsticks to Square](https://leetcode.com/problems/matchsticks-to-square/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MatchsticksToSquare473.java) | Medium |\n| [474. Ones and Zeroes](https://leetcode.com/problems/ones-and-zeroes/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/OnesAndZeroes474.java) | Medium |\n| [477. Total Hamming Distance](https://leetcode.com/problems/total-hamming-distance) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/TotalHammingDistance477.java) | Medium |\n| [480. Sliding Window Median](https://leetcode.com/problems/sliding-window-median/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SlidingWindowMedian480.java) | Hard |\n| [481. Magical String](https://leetcode.com/problems/magical-string/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MagicalString481.java) | Medium |\n| [482. License Key Formatting](https://leetcode.com/problems/license-key-formatting/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LicenseKeyFormatting482.java) | Easy |\n| [485. Max Consecutive Ones](https://leetcode.com/problems/max-consecutive-ones/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaxConsecutiveOnes485.java) | Easy |\n| [486. Predict the Winner](https://leetcode.com/problems/predict-the-winner/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PredictTheWinner486.java) | Medium |\n| [487. Max Consecutive Ones II](https://leetcode.com/problems/max-consecutive-ones-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaxConsecutiveOnesII487.java) | Medium |\n| [490. The Maze](https://leetcode.com/problems/the-maze/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/TheMaze490.java) | Medium |\n| [491. Increasing Subsequences](https://leetcode.com/problems/increasing-subsequences/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/IncreasingSubsequences491.java) | Medium |\n| [494. Target Sum](https://leetcode.com/problems/target-sum/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/TargetSum494.java) | Medium |\n| [496. Next Greater Element I](https://leetcode.com/problems/next-greater-element-i/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NextGreaterElementI496.java) | Easy |\n| [498. Diagonal Traverse](https://leetcode.com/problems/diagonal-traverse/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DiagonalTraverse498.java) | Medium |\n| [499. The Maze III](https://leetcode.com/problems/the-maze-iii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/TheMazeIII499.java) | Hard |\n| [503. Next Greater Element II](https://leetcode.com/problems/next-greater-element-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NextGreaterElementII503.java) | Medium |\n| [505. The Maze II](https://leetcode.com/problems/the-maze-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/TheMazeII505.java) | Hard |\n| [508. Most Frequent Subtree Sum](https://leetcode.com/problems/most-frequent-subtree-sum/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MostFrequentSubtreeSum508.java) | Medium |\n| [513. Find Bottom Left Tree Value](https://leetcode.com/problems/find-bottom-left-tree-value/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindBottomLeftTreeValue513.java) | Medium |\n| [515. Find Largest Value in Each Tree Row](https://leetcode.com/problems/find-largest-value-in-each-tree-row/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindLargestValueInEachTreeRow515.java) | Medium |\n| [516. Longest Palindromic Subsequence](https://leetcode.com/problems/longest-palindromic-subsequence/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LongestPalindromicSubsequence516.java) | Medium |\n| [518. Coin Change 2](https://leetcode.com/problems/coin-change-2/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CoinChangeII518.java) | Medium |\n| [519. Random Flip Matrix](https://leetcode.com/problems/random-flip-matrix/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RandomFlipMatrix519.java) | Medium |\n| [523. Continuous Subarray Sum](https://leetcode.com/problems/continuous-subarray-sum/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ContinuousSubarraySum523.java) | Medium |\n| [525. Contiguous Array](https://leetcode.com/problems/contiguous-array/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ContiguousArray525.java) | Medium |\n| [527. Word Abbreviation](https://leetcode.com/problems/word-abbreviation/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/WordAbbreviation527.java) | Hard |\n| [529. Minesweeper](https://leetcode.com/problems/minesweeper/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/Minesweeper529.java) | Medium |\n| [530. Minimum Absolute Difference in BST](https://leetcode.com/problems/minimum-absolute-difference-in-bst/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MinimumAbsoluteDifferenceInBST530.java) | Easy |\n| [531. Lonely Pixel I](https://leetcode.com/problems/lonely-pixel-i/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LonelyPixelI531.java) | Medium |\n| [535. Encode and Decode TinyURL](https://leetcode.com/problems/encode-and-decode-tinyurl/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/EncodeAndDecodeTinyURL535.java) | Medium |\n| [536. Construct Binary Tree from String](https://leetcode.com/problems/construct-binary-tree-from-string/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ConstructBinaryTreeFromString536.java) | Medium |\n| [538. Convert BST to Greater Tree](https://leetcode.com/problems/convert-bst-to-greater-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ConvertBSTToGreaterTree538.java) | Easy |\n| [540. Single Element in a Sorted Array](https://leetcode.com/problems/single-element-in-a-sorted-array/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SingleElementInASortedArray540.java) | Medium |\n| [541. Reverse String II](https://leetcode.com/problems/reverse-string-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ReverseStringII541.java) | Easy |\n| [542. 01 Matrix](https://leetcode.com/problems/01-matrix/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ZeroOneMatrix542.java) | Medium |\n| [543. Diameter of Binary Tree](https://leetcode.com/problems/diameter-of-binary-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DiameterOfBinaryTree543.java) | Easy |\n| [544. Output Contest Matches](https://leetcode.com/problems/output-contest-matches/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/OutputContestMatches544.java) | Medium |\n| [545. Boundary of Binary Tree](https://leetcode.com/problems/boundary-of-binary-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BoundaryOfBinaryTree545.java) | Medium |\n| [547. Friend Circles](https://leetcode.com/problems/friend-circles/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FriendCircles547.java) | Medium |\n| [554. Brick Wall](https://leetcode.com/problems/brick-wall/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BrickWall554.java) | Medium |\n| [556. Next Greater Element III](https://leetcode.com/problems/next-greater-element-iii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NextGreaterElementIII556.java) | Medium |\n| [557. Reverse Words in a String III](https://leetcode.com/problems/reverse-words-in-a-string-iii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ReverseWordsInAStringIII557.java) | Easy |\n| [558. Quad Tree Intersection](https://leetcode.com/problems/quad-tree-intersection/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/QuadTreeIntersection558.java) | Easy |\n| [560. Subarray Sum Equals K](https://leetcode.com/problems/subarray-sum-equals-k/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SubarraySumEqualsK560.java) | Medium |\n| [567. Permutation in String](https://leetcode.com/problems/permutation-in-string/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PermutationInString567.java) | Easy |\n| [568. Maximum Vacation Days](https://leetcode.com/problems/maximum-vacation-days/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximumVacationDays568.java) | Hard |\n| [572. Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SubtreeOfAnotherTree572.java) | Easy |\n| [582. Kill Process](https://leetcode.com/problems/kill-process/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/KillProcess582.java) | Medium |\n| [588. Design In-Memory File System](https://leetcode.com/problems/design-in-memory-file-system/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DesignInMemoryFileSystem588.java) | Hard |\n| [590. N-ary Tree Postorder Traversal](https://leetcode.com/problems/n-ary-tree-postorder-traversal/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NaryTreePostorderTraversal590.java) | Easy |\n| [594. Longest Harmonious Subsequence](https://leetcode.com/problems/longest-harmonious-subsequence/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LongestHarmoniousSubsequence594.java) | Easy |\n| [604. Design Compressed String Iterator](https://leetcode.com/problems/design-compressed-string-iterator/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DesignCompressedStringIterator604.java) | Easy |\n| [611. Valid Triangle Number](https://leetcode.com/problems/valid-triangle-number/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ValidTriangleNumber611.java) | Medium |\n| [616. Add Bold Tag in String](https://leetcode.com/problems/add-bold-tag-in-string/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/AddBoldTagInString616.java) | Medium |\n| [621. Task Scheduler](https://leetcode.com/problems/task-scheduler/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/TaskScheduler621.java) | Medium |\n| [622. Design Circular Queue](https://leetcode.com/problems/design-circular-queue/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DesignCircularQueue622.java) | Medium |\n| [623. Add One Row to Tree](https://leetcode.com/problems/add-one-row-to-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/AddOneRowToTree623.java) | Medium |\n| [628. Maximum Product of Three Numbers](https://leetcode.com/problems/maximum-product-of-three-numbers/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximumProductOfThreeNumbers628.java) | Easy |\n| [632. Smallest Range](https://leetcode.com/problems/smallest-range/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SmallestRange632.java) | Hard |\n| [633. Sum of Square Numbers](https://leetcode.com/problems/sum-of-square-numbers/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SumOfSquareNumbers633.java) | Easy |\n| [635. Design Log Storage System](https://leetcode.com/problems/design-log-storage-system/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DesignLogStorageSystem635.java) | Hard |\n| [636. Exclusive Time of Functions](https://leetcode.com/problems/exclusive-time-of-functions/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ExclusiveTimeOfFunctions636.java) | Medium |\n| [637. Average of Levels in Binary Tree](https://leetcode.com/problems/average-of-levels-in-binary-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/AverageOfLevelsInBinaryTree637.java) | Easy |\n| [639. Decode Ways II](https://leetcode.com/problems/decode-ways-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DecodeWaysII639.java) | Hard |\n| [640. Solve the Equation](https://leetcode.com/problems/solve-the-equation/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SolveTheEquation640.java) | Medium |\n| [641. Design Circular Deque](https://leetcode.com/problems/design-circular-deque/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DesignCircularDeque641.java) | Medium |\n| [642. Design Search Autocomplete System](https://leetcode.com/problems/design-search-autocomplete-system/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DesignSearchAutocompleteSystem642.java) | Hard |\n| [643. Maximum Average Subarray I](https://leetcode.com/problems/maximum-average-subarray-i/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximumAverageSubarrayI643.java) | Easy |\n| [646. Maximum Length of Pair Chain](https://leetcode.com/problems/maximum-length-of-pair-chain/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximumLengthOfPairChain646.java) | Medium |\n| [647. Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PalindromicSubstrings647.java) | Medium |\n| [648. Replace Words](https://leetcode.com/problems/replace-words/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ReplaceWords648.java) | Medium |\n| [652. Find Duplicate Subtrees](https://leetcode.com/problems/find-duplicate-subtrees/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindDuplicateSubtrees652.java) | Medium |\n| [653. Two Sum IV - Input is a BST](https://leetcode.com/problems/two-sum-iv-input-is-a-bst/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/TwoSumIVInputIsABST653.java) | Easy |\n| [654. Maximum Binary Tree](https://leetcode.com/problems/maximum-binary-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximumBinaryTree654.java) | Medium |\n| [657. Judge Route Circle](https://leetcode.com/problems/judge-route-circle/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/JudgeRouteCircle657.java) | Easy |\n| [658. Find K Closest Elements](https://leetcode.com/problems/find-k-closest-elements//) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindKClosestElements658.java) | Medium |\n| [659. Split Array into Consecutive Subsequences](https://leetcode.com/problems/split-array-into-consecutive-subsequences/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SplitArrayIntoConsecutiveSubsequences659.java) | Medium |\n| [661. Image Smoother](https://leetcode.com/problems/image-smoother/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ImageSmoother661.java) | Easy |\n| [662. Maximum Width of Binary Tree](https://leetcode.com/problems/maximum-width-of-binary-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximumWidthOfBinaryTree662.java) | Medium |\n| [663. Equal Tree Partition](https://leetcode.com/problems/equal-tree-partition/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/EqualTreePartition663.java) | Medium |\n| [665. Non-decreasing Array](https://leetcode.com/problems/non-decreasing-array/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NonDecreasingArray665.java) | Easy |\n| [669. Trim a Binary Search Tree](https://leetcode.com/problems/trim-a-binary-search-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/TrimABinarySearchTree669.java) | Easy |\n| [671. Second Minimum Node In a Binary Tree](https://leetcode.com/problems/second-minimum-node-in-a-binary-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SecondMinimumNodeInABinaryTree671.java) | Easy |\n| [673. Number of Longest Increasing Subsequence](https://leetcode.com/problems/number-of-longest-increasing-subsequence/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NumberOfLongestIncreasingSubsequence673.java) | Medium |\n| [674. Longest Continuous Increasing Subsequence](https://leetcode.com/problems/longest-continuous-increasing-subsequence/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LongestContinuousIncreasingSubsequence674.java) | Easy |\n| [675. Cut Off Trees for Golf Event](https://leetcode.com/problems/cut-off-trees-for-golf-event/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CutOffTreesForGolfEvent675.java) | Hard |\n| [676. Implement Magic Dictionary](https://leetcode.com/problems/implement-magic-dictionary/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ImplementMagicDictionary676.java) | Medium |\n| [677. Map Sum Pairs](https://leetcode.com/problems/map-sum-pairs/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MapSumPairs677.java) | Medium |\n| [678. Valid Parenthesis String](https://leetcode.com/problems/valid-parenthesis-string/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ValidParenthesisString678.java) | Medium |\n| [680. Valid Palindrome II](https://leetcode.com/problems/valid-palindrome-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ValidPalindromeII680.java) | Easy |\n| [681. Next Closest Time](https://leetcode.com/problems/next-closest-time/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NextClosestTime681.java) | Medium |\n| [682. Baseball Game](https://leetcode.com/problems/baseball-game/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BaseballGame682.java) | Easy |\n| [683. K Empty Slots](https://leetcode.com/problems/k-empty-slots/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/KEmptySlots683.java) | Hard |\n| [684. Redundant Connection](https://leetcode.com/problems/redundant-connection/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RedundantConnection684.java) | Medium |\n| [685. Redundant Connection II](https://leetcode.com/problems/redundant-connection-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RedundantConnectionII685.java) | Hard |\n| [686. Repeated String Match](https://leetcode.com/problems/repeated-string-match/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RepeatedStringMatch686.java) | Easy |\n| [687. Longest Univalue Path](https://leetcode.com/problems/longest-univalue-path/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LongestUnivaluePath687.java) | Easy |\n| [689. Maximum Sum of 3 Non-Overlapping Subarrays](https://leetcode.com/problems/maximum-sum-of-3-non-overlapping-subarrays/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximumSumOf3NonOverlappingSubarrays689.java) | Hard |\n| [692. Top K Frequent Words](https://leetcode.com/problems/top-k-frequent-words/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/TopKFrequentWords692.java) | Medium |\n| [695. Max Area of Island](https://leetcode.com/problems/max-area-of-island/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaxAreaOfIsland695.java) | Medium |\n| [698. Partition to K Equal Sum Subsets](https://leetcode.com/problems/partition-to-k-equal-sum-subsets/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PartitionToKEqualSumSubsets698.java) | Medium |\n| [702. Search in a Sorted Array of Unknown Size](https://leetcode.com/problems/search-in-a-sorted-array-of-unknown-size/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SearchInASortedArrayOfUnknownSize702.java) | Medium |\n| [705. Design HashSet](https://leetcode.com/problems/design-hashset/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DesignHashSet705.java) | Easy |\n| [706. Design HashMap](https://leetcode.com/problems/design-hashmap/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DesignHashMap706.java) | Easy |\n| [707. Design Linked List](https://leetcode.com/problems/design-linked-list/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DesignLinkedList707.java) | Easy |\n| [709. To Lower Case](https://leetcode.com/problems/to-lower-case/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ToLowerCase709.java) | Easy |\n| [712. Minimum ASCII Delete Sum for Two Strings](https://leetcode.com/problems/minimum-ascii-delete-sum-for-two-strings/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MinimumASCIIDeleteSumForTwoStrings712.java) | Medium |\n| [713. Subarray Product Less Than K](https://leetcode.com/problems/subarray-product-less-than-k/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SubarrayProductLessThanK713.java) | Medium |\n| [714. Best Time to Buy and Sell Stock with Transaction Fee](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BestTimeToBuyAndSellStockWithTransactionFee714.java) | Medium |\n| [715. Range Module](https://leetcode.com/problems/range-module/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RangeModule715.java) | Hard |\n| [716. Max Stack](https://leetcode.com/problems/max-stack/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaxStack716.java) | Hard |\n| [718. Maximum Length of Repeated Subarray](https://leetcode.com/problems/maximum-length-of-repeated-subarray/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximumLengthOfRepeatedSubarray718.java) | Medium |\n| [719. Find K-th Smallest Pair Distance](https://leetcode.com/problems/find-k-th-smallest-pair-distance/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindKthSmallestPairDistance719.java) | Hard |\n| [720. Longest Word in Dictionary](https://leetcode.com/problems/longest-word-in-dictionary/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LongestWordInDictionary720.java) | Easy |\n| [721. Accounts Merge](https://leetcode.com/problems/accounts-merge/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/AccountsMerge721.java) | Medium |\n| [727. Minimum Window Subsequence](https://leetcode.com/problems/minimum-window-subsequence/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MinimumWindowSubsequence727.java) | Hard |\n| [729. My Calendar I](https://leetcode.com/problems/my-calendar-i/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MyCalendarI729.java) | Medium |\n| [731. My Calendar II](https://leetcode.com/problems/my-calendar-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MyCalendarII731.java) | Medium |\n| [734. Sentence Similarity](https://leetcode.com/problems/sentence-similarity/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SentenceSimilarity734.java) | Easy |\n| [737. Sentence Similarity II](https://leetcode.com/problems/sentence-similarity-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SentenceSimilarityII737.java) | Medium |\n| [738. Monotone Increasing Digits](https://leetcode.com/problems/monotone-increasing-digits/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MonotoneIncreasingDigits738.java) | Medium |\n| [739. Daily Temperatures](https://leetcode.com/problems/daily-temperatures/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DailyTemperatures739.java) | Medium |\n| [740. Delete and Earn](https://leetcode.com/problems/delete-and-earn/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DeleteAndEarn740.java) | Medium |\n| [746. Min Cost Climbing Stairs](https://leetcode.com/problems/min-cost-climbing-stairs/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MinCostClimbingStairs746.java) | Easy |\n| [748. Shortest Completing Word](https://leetcode.com/problems/shortest-completing-word/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ShortestCompletingWord748.java) | Medium |\n| [750. Number Of Corner Rectangles](https://leetcode.com/problems/number-of-corner-rectangles/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NumberOfCornerRectangles750.java) | Medium |\n| [752. Open the Lock](https://leetcode.com/problems/open-the-lock/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/OpenTheLock752.java) | Medium |\n| [759. Employee Free Time](https://leetcode.com/problems/employee-free-time/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/EmployeeFreeTime759.java) | Hard |\n| [760. Find Anagram Mappings](https://leetcode.com/problems/find-anagram-mappings/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindAnagramMappings760.java) | Easy |\n| [763. Partition Labels](https://leetcode.com/problems/partition-labels/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PartitionLabels763.java) | Medium |\n| [765. Couples Holding Hands](https://leetcode.com/problems/couples-holding-hands/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CouplesHoldingHands765.java) | Hard |\n| [767. Reorganize String](https://leetcode.com/problems/reorganize-string/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ReorganizeString767.java) | Medium |\n| [768. Max Chunks To Make Sorted II](https://leetcode.com/problems/max-chunks-to-make-sorted-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaxChunksToMakeSortedII768.java) | Hard |\n| [769. Max Chunks To Make Sorted](https://leetcode.com/problems/max-chunks-to-make-sorted/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaxChunksToMakeSorted769.java) | Medium |\n| [771. Jewels and Stones](https://leetcode.com/problems/jewels-and-stones/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/JewelsAndStones771.java) | Easy |\n| [777. Swap Adjacent in LR String](https://leetcode.com/problems/swap-adjacent-in-lr-string/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SwapAdjacentInLRString777.java) | Medium |\n| [779. K-th Symbol in Grammar](https://leetcode.com/problems/k-th-symbol-in-grammar/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/KthSymbolInGrammar779.java) | Medium |\n| [785. Is Graph Bipartite?](https://leetcode.com/problems/is-graph-bipartite) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/IsGraphBipartite785.java) | Medium |\n| [787. Cheapest Flights Within K Stops](https://leetcode.com/problems/cheapest-flights-within-k-stops/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CheapestFlightsWithinKStops787.java) | Medium |\n| [790. Domino and Tromino Tiling](https://leetcode.com/problems/domino-and-tromino-tiling/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DominoAndTrominoTiling790.java) | Medium |\n| [792. Number of Matching Subsequences](https://leetcode.com/problems/number-of-matching-subsequences/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/NumberOfMatchingSubsequences792.java) | Medium |\n| [797. All Paths From Source to Target](https://leetcode.com/problems/all-paths-from-source-to-target/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/AllPathsFromSourceToTarget797.java) | Medium |\n| [783. Minimum Distance Between BST Nodes](https://leetcode.com/problems/minimum-distance-between-bst-nodes/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MinimumDistanceBetweenBSTNodes783.java) | Easy |\n| [802. Find Eventual Safe States](https://leetcode.com/problems/find-eventual-safe-states/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindEventualSafeStates802.java) | Medium |\n| [803. Bricks Falling When Hit](https://leetcode.com/problems/bricks-falling-when-hit/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BricksFallingWhenHit803.java) | Hard |\n| [804. Unique Morse Code Words](https://leetcode.com/problems/unique-morse-code-words/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/UniqueMorseCodeWords804.java) | Easy |\n| [807. Max Increase to Keep City Skyline](https://leetcode.com/problems/max-increase-to-keep-city-skyline/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaxIncreaseToKeepCitySkyline807.java) | Medium |\n| [819. Most Common Word](https://leetcode.com/problems/most-common-word/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MostCommonWord819.java) | Easy |\n| [826. Most Profit Assigning Work](https://leetcode.com/problems/most-profit-assigning-work/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MostProfitAssigningWork826.java) | Medium |\n| [832. Flipping an Image](https://leetcode.com/problems/flipping-an-image/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FlippingAnImage832.java) | Easy |\n| [836. Rectangle Overlap](https://leetcode.com/problems/rectangle-overlap/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RectangleOverlap863.java) | Easy |\n| [841. Keys and Rooms](https://leetcode.com/problems/keys-and-rooms/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/KeysAndRooms841.java) | Medium |\n| [842. Split Array into Fibonacci Sequence](https://leetcode.com/problems/split-array-into-fibonacci-sequence/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/SplitArrayIntoFibonacciSequence842.java) | Medium |\n| [843. Guess the Word](https://leetcode.com/problems/guess-the-word/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/GuessTheWord843.java) | Hard |\n| [844. Backspace String Compare](https://leetcode.com/problems/backspace-string-compare/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BackspaceStringCompare844.java) | Easy |\n| [845. Longest Mountain in Array](https://leetcode.com/problems/longest-mountain-in-array/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LongestMountainInArray845.java) | Medium |\n| [846. Hand of Straights](https://leetcode.com/problems/hand-of-straights/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/HandOfStraights846.java) | Medium |\n| [849. Maximize Distance to Closest Person](https://leetcode.com/problems/maximize-distance-to-closest-person/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximizeDistanceToClosestPerson849.java) | Easy |\n| [850. Rectangle Area II](https://leetcode.com/problems/rectangle-area-ii/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RectangleAreaII850.java) | Hard |\n| [855. Exam Room](https://leetcode.com/problems/exam-room/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ExamRoom855.java) | Medium |\n| [859. Buddy Strings](https://leetcode.com/problems/buddy-strings/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BuddyStrings859.java) | Easy |\n| [860. Lemonade Change](https://leetcode.com/problems/lemonade-change/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LemonadeChange860.java) | Easy |\n| [862. Shortest Subarray with Sum at Least K](https://leetcode.com/problems/shortest-subarray-with-sum-at-least-k/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ShortestSubarrayWithSumAtLeastK862.java) | Hard |\n| [863. All Nodes Distance K in Binary Tree](https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/AllNodesDistanceKInBinaryTree863.java) | Medium |\n| [864. Shortest Path to Get All Keys](https://leetcode.com/problems/shortest-path-to-get-all-keys/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ShortestPathToGetAllKeys864.java) | Hard |\n| [873. Length of Longest Fibonacci Subsequence](https://leetcode.com/problems/length-of-longest-fibonacci-subsequence/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/LengthOfLongestFibonacciSubsequence873.java) | Medium |\n| [875. Koko Eating Bananas](https://leetcode.com/problems/koko-eating-bananas/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/KokoEatingBananas875.java) | Easy |\n| [876. Middle of the Linked List](https://leetcode.com/problems/middle-of-the-linked-list/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MiddleOfTheLinkedList876.java) | Easy |\n| [877. Stone Game](https://leetcode.com/problems/stone-game/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/StoneGame877.java) | Medium |\n| [879. Profitable Schemes](https://leetcode.com/problems/profitable-schemes/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ProfitableSchemes879.java) | Hard |\n| [884. Decoded String at Index](https://leetcode.com/problems/decoded-string-at-index/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/DecodedStringAtIndex884.java) | Medium |\n| [885. Boats to Save People](https://leetcode.com/problems/boats-to-save-people/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/BoatsToSavePeople885.java) | Medium |\n| [886. Possible Bipartition](https://leetcode.com/problems/possible-bipartition) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/PossibleBipartition886.java) | Medium |\n| [887. Projection Area of 3D Shapes](https://leetcode.com/problems/projection-area-of-3d-shapes/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ProjectionAreaOf3DShapes887.java) | Easy |\n| [890. Find and Replace Pattern](https://leetcode.com/problems/find-and-replace-pattern/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindAndReplacePattern890.java) | Medium \n| [895. Maximum Frequency Stack](https://leetcode.com/problems/maximum-frequency-stack/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/MaximumFrequencyStack895.java) | Hard |\n| [Convert Binary Search Tree to Sorted Doubly Linked List](https://leetcode.com/explore/interview/card/facebook/5/round-1-phone-interview/283/) | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/ConvertBinarySearchTreeToSortedDoublyLinkedList.java) | - |\n| HighestPopulationYear | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/HighestPopulationYear.java) | - |\n| Insert into a Cyclic Sorted List | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/InsertIntoACyclicSortedList.java) | - |\n| Robot Room Cleaner | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/RobotRoomCleaner.java) | - |\n| AsyncJobMonitor | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/AsyncJobMonitor.java) | - |\n| Bench | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/Bench.java) | - |\n| FindCenterOfMassInA2DArray | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/FindCenterOfMassInA2DArray.java) | - |\n| OneEditDistance | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/OneEditDistance.java) | - |\n| CollatzConjecture | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/CollatzConjecture.java) | - |\n| Subsequence | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/Subsequence.java) | - |\n| TreeToForestByErasingNodes | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/TreeToForestByErasingNodes.java) | - |\n| KMP | [Solution](https://github.com/fluency03/leetcode-java/blob/master/src/KMP.java) | - |\n"
  },
  {
    "path": "src/.gitignore",
    "content": "*.class\n.DS_store\n"
  },
  {
    "path": "src/AccountsMerge721.java",
    "content": "/**\n * Given a list accounts, each element accounts[i] is a list of strings, where\n * the first element accounts[i][0] is a name, and the rest of the elements are\n * emails representing emails of the account.\n *\n * Now, we would like to merge these accounts. Two accounts definitely belong\n * to the same person if there is some email that is common to both accounts.\n * Note that even if two accounts have the same name, they may belong to\n * different people as people could have the same name. A person can have any\n * number of accounts initially, but all of their accounts definitely have the\n * same name.\n *\n * After merging the accounts, return the accounts in the following format:\n * the first element of each account is the name, and the rest of the elements\n * are emails in sorted order. The accounts themselves can be returned in any\n * order.\n *\n * Example 1:\n * Input:\n * accounts = [[\"John\", \"johnsmith@mail.com\", \"john00@mail.com\"], [\"John\", \"johnnybravo@mail.com\"], [\"John\", \"johnsmith@mail.com\", \"john_newyork@mail.com\"], [\"Mary\", \"mary@mail.com\"]]\n * Output: [[\"John\", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'],  [\"John\", \"johnnybravo@mail.com\"], [\"Mary\", \"mary@mail.com\"]]\n *\n * Explanation:\n * The first and third John's are the same person as they have the common email \"johnsmith@mail.com\".\n * The second John and Mary are different people as none of their email addresses are used by other accounts.\n * We could return these lists in any order, for example the answer [['Mary', 'mary@mail.com'], ['John', 'johnnybravo@mail.com'],\n * ['John', 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com']] would still be accepted.\n *\n * Note:\n *\n * The length of accounts will be in the range [1, 1000].\n * The length of accounts[i] will be in the range [1, 10].\n * The length of accounts[i][j] will be in the range [1, 30].\n *\n */\n\n\npublic class AccountsMerge721 {\n    public List<List<String>> accountsMerge(List<List<String>> accounts) {\n        List<List<String>> res = new ArrayList<>();\n\n        Map<String, Set<Set<String>>> map = new HashMap<>();\n\n        for (List<String> acc: accounts) {\n            String name = acc.get(0);\n            if (!map.containsKey(name)) {\n                Set<String> set = new HashSet<>(acc);\n                set.remove(name);\n                Set<Set<String>> setOfSet = new HashSet<>();\n                setOfSet.add(set);\n                map.put(name, setOfSet);\n            } else {\n                Set<Set<String>> toBeMerged = new HashSet<>();\n                Set<Set<String>> setOfSet = map.get(name);\n                Set<String> curr = new HashSet<>(acc);\n                curr.remove(name);\n                for (String email: curr) {\n                    Set<String> found = null;\n                    for (Set<String> e: setOfSet) {\n                        if (e.contains(email)) {\n                            found = e;\n                            break;\n                        }\n                    }\n                    if (found != null) {\n                        setOfSet.remove(found);\n                        toBeMerged.add(found);\n                    }\n                }\n                for (Set<String> s: toBeMerged) {\n                    curr.addAll(s);\n                }\n                setOfSet.add(curr);\n            }\n        }\n\n        for (Map.Entry<String, Set<Set<String>>> en: map.entrySet()) {\n            for (Set<String> es: en.getValue()) {\n                List<String> list = new ArrayList<>(es);\n                java.util.Collections.sort(list);\n                list.add(0, en.getKey());\n                res.add(list);\n            }\n        }\n\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/accounts-merge/solution/\n     */\n    int MAX_VAL = 10000;\n    public List<List<String>> accountsMerge(List<List<String>> accounts) {\n\n        Map<String, String> emailToName = new HashMap<>();\n        Map<String, Integer> emailToId = new HashMap<>();\n\n        DSU dsu = initDSU(accounts, emailToName, emailToId);\n\n        Map<Integer, List<String>> res = new HashMap();\n        for (String email: emailToName.keySet()) {\n            int id = dsu.find(emailToId.get(email));\n            res.computeIfAbsent(id, x -> new ArrayList()).add(email);\n        }\n\n        for (List<String> emails: res.values()) {\n            Collections.sort(emails);\n            emails.add(0, emailToName.get(emails.get(0)));\n        }\n\n        return new ArrayList(res.values());\n    }\n\n\n    private DSU initDSU(List<List<String>> accounts, Map<String, String> emailToName, Map<String, Integer> emailToId) {\n        DSU dsu = new DSU(MAX_VAL+1);\n\n        int id = 0;\n        for (List<String> acc: accounts) {\n            String name = acc.get(0);\n\n            for (int i=1; i<acc.size(); i++) {\n                String email = acc.get(i);\n                emailToName.putIfAbsent(email, name);\n                if (!emailToId.containsKey(email)) {\n                    emailToId.put(email, id);\n                    id++;\n                }\n\n                dsu.union(emailToId.get(acc.get(1)), emailToId.get(email));\n            }\n        }\n\n        return dsu;\n    }\n\n\n    class DSU {\n        int[] parent;\n\n        public DSU(int size) {\n            parent = new int[size];\n            for (int i = 0; i < size; i++) parent[i] = i;\n        }\n\n        public int find(int x) {\n            if (parent[x] != x) parent[x] = find(parent[x]);\n            return parent[x];\n        }\n\n        public void union(int x, int y) {\n            parent[find(x)] = find(y);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/accounts-merge/discuss/109158/Java-Solution-(Build-graph-+-DFS-search)\n     */\n    public List<List<String>> accountsMerge3(List<List<String>> accounts) {\n        Map<String, String> emailToName = new HashMap<>();\n        Map<String, Set<String>> graph = initGraph(accounts, emailToName);\n\n        Set<String> visited = new HashSet<>();\n        List<List<String>> res = new LinkedList<>();\n\n        for (String email: emailToName.keySet()) {\n            List<String> list = new LinkedList<>();\n            if (visited.add(email)) {\n                dfs(graph, email, visited, list);\n                Collections.sort(list);\n                list.add(0, emailToName.get(email));\n                res.add(list);\n            }\n        }\n\n        return res;\n    }\n\n    private Map<String, Set<String>> initGraph(List<List<String>> accounts, Map<String, String> emailToName) {\n        Map<String, Set<String>> graph = new HashMap<>();\n\n        for (List<String> acc : accounts) {\n            String name = acc.get(0);\n            for (int i = 1; i < acc.size(); i++) {\n                String email = acc.get(i);\n                if (!graph.containsKey(acc.get(i))) {\n                    graph.put(email, new HashSet<>());\n                }\n\n                emailToName.put(email, name);\n\n                if (i == 1) continue;\n                graph.get(email).add(acc.get(i-1));\n                graph.get(acc.get(i-1)).add(email);\n            }\n        }\n        return graph;\n    }\n\n    private void dfs(Map<String, Set<String>> graph, String email, Set<String> visited, List<String> list) {\n        list.add(email);\n        for (String l: graph.get(email)) {\n            if (visited.add(l)) dfs(graph, l, visited, list);\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "src/AddBinary67.java",
    "content": "/**\n * Given two binary strings, return their sum (also a binary string).\n *\n * For example,\n * a = \"11\"\n * b = \"1\"\n * Return \"100\".\n */\n\n\npublic class AddBinary67 {\n    public String addBinary(String a, String b) {\n        return addBinary(a, b, a.length()-1, b.length()-1, 0) ;\n    }\n\n    private String addBinary(String a, String b, int i, int j, int carry) {\n        if (i < 0 && j < 0) return (carry == 0) ? \"\" : \"1\";\n\n        int sum = carry;\n        if (i >= 0 && a.charAt(i) == '1') sum++;\n        if (j >= 0 && b.charAt(j) == '1') sum++;\n\n        return addBinary(a, b, i-1, j-1, (sum < 2) ? 0 : 1) + ((sum%2 == 0) ? \"0\" : \"1\");\n    }\n\n\n\n    public String addBinary2(String a, String b) {\n        StringBuilder sb = new StringBuilder();\n        addBinary(a, b, a.length()-1, b.length()-1, 0, sb) ;\n        return sb.toString();\n    }\n\n    private void addBinary(String a, String b, int i, int j, int carry, StringBuilder sb) {\n        if (i < 0 && j < 0) {\n            sb.append((carry == 0) ? \"\" : \"1\");\n            return;\n        }\n\n        int sum = carry;\n        if (i >= 0 && a.charAt(i) == '1') sum++;\n        if (j >= 0 && b.charAt(j) == '1') sum++;\n        addBinary(a, b, i-1, j-1, (sum < 2) ? 0 : 1, sb);\n\n        sb.append((sum%2 == 0) ? '0' : '1');\n    }\n\n\n    public String addBinary3(String a, String b) {\n        StringBuilder sb = new StringBuilder();\n        int carry = 0;\n        int i = a.length()-1;\n        int j = b.length()-1;\n        while (i >= 0 && j >= 0) {\n            int sum = carry;\n            if (a.charAt(i) == '1') sum++;\n            if (b.charAt(j) == '1') sum++;\n            carry = (sum < 2) ? 0 : 1;\n            sb.insert(0, (sum%2 == 0) ? '0' : '1');\n            i--;\n            j--;\n        }\n\n        while (i >= 0) {\n            int sum = carry;\n            if (a.charAt(i) == '1') sum++;\n            carry = (sum < 2) ? 0 : 1;\n            sb.insert(0, (sum%2 == 0) ? '0' : '1');\n            i--;\n        }\n\n        while (j >= 0) {\n            int sum = carry;\n            if (b.charAt(j) == '1') sum++;\n            carry = (sum < 2) ? 0 : 1;\n            sb.insert(0, (sum%2 == 0) ? '0' : '1');\n            j--;\n        }\n\n        if (carry == 1) sb.insert(0, '1');\n\n        return sb.toString();\n    }\n\n    public String addBinary4(String a, String b) {\n        char[] intToChar = new char[]{'0', '1'};\n        int len = Math.max(a.length(), b.length());\n        char[] res = new char[len + 1];\n        int carry = 0;\n        int s = len;\n        int i = a.length() - 1;\n        int j = b.length() - 1;\n        while (i >= 0 && j >= 0) {\n            int sum = charToInt(a.charAt(i--)) + charToInt(b.charAt(j--)) + carry;\n            carry = sum >> 1;\n            res[s--] = intToChar[sum & 1];\n        }\n        while (i >= 0) {\n            int sum = charToInt(a.charAt(i--)) + carry;\n            carry = sum >> 1;\n            res[s--] = intToChar[sum & 1];\n        }\n        while (j >= 0) {\n            int sum = charToInt(b.charAt(j--)) + carry;\n            carry = sum >> 1;\n            res[s--] = intToChar[sum & 1];\n        }\n        res[0] = intToChar[carry];\n        return res[0] == '0' ? (new String(res)).substring(1) : new String(res);\n    }\n    \n    private int charToInt(char c) {\n        return c - '0';\n    }\n\n}\n"
  },
  {
    "path": "src/AddBoldTagInString616.java",
    "content": "/**\n * Given a string s and a list of strings dict, you need to add a closed pair\n * of bold tag <b> and </b> to wrap the substrings in s that exist in dict. If\n * two such substrings overlap, you need to wrap them together by only one pair\n * of closed bold tag. Also, if two substrings wrapped by bold tags are\n * consecutive, you need to combine them.\n * \n * Example 1:\n * \n * Input: \n * s = \"abcxyz123\"\n * dict = [\"abc\",\"123\"]\n * Output:\n * \"<b>abc</b>xyz<b>123</b>\"\n * \n * Example 2:\n * Input: \n * s = \"aaabbcc\"\n * dict = [\"aaa\",\"aab\",\"bc\"]\n * Output:\n * \"<b>aaabbc</b>c\"\n * \n * Note:\n * The given dict won't contain duplicates, and its length won't exceed 100.\n * All the strings in input have length in range [1, 1000].\n */\n\npublic class AddBoldTagInString616 {\n    public String addBoldTag(String s, String[] dict) {\n        Trie trie = constructTrie(dict);        \n        StringBuilder sb = new StringBuilder();\n        int l = 0;\n        int r = 0;\n        char[] chars = s.toCharArray();\n        for (int i=0; i<s.length(); i++) {\n            int len = trie.search(chars, i);\n            if (len == 0) {\n                if (i >= r) {\n                    if (r > l) {\n                        sb.append(\"<b>\");\n                        sb.append(s.substring(l, r));\n                        sb.append(\"</b>\");\n                    }\n                    r = i + 1;\n                    l = r;\n                    sb.append(s.charAt(i));\n                }\n            } else {\n                r = Math.max(r, i+len);\n            }\n        }\n\n        if (r > l) {\n            sb.append(\"<b>\");\n            sb.append(s.substring(l, r));\n            sb.append(\"</b>\");\n        }\n\n        return sb.toString();\n    }\n    \n    private Trie constructTrie(String[] dict) {\n        Trie res = new Trie();\n        for (String word: dict) {\n            res.addWord(word);\n        }\n        return res;\n    }\n\n    public String addBoldTag2(String s, String[] dict) {\n        StringBuilder sb = new StringBuilder();\n        int l = 0;\n        int r = 0;\n        for (int i=0; i<s.length(); i++) {\n            int len = 0;\n            for (String word: dict) {\n                if (s.startsWith(word, i) && word.length() > len) {\n                    len = word.length();\n                }\n            }\n            if (len == 0) {\n                if (i >= r) {\n                    if (r > l) {\n                        sb.append(\"<b>\");\n                        sb.append(s.substring(l, r));\n                        sb.append(\"</b>\");\n                    }\n                    r = i + 1;\n                    l = r;\n                    sb.append(s.charAt(i));\n                }\n            } else {\n                r = Math.max(r, i+len);\n            }\n        }\n\n        if (r > l) {\n            sb.append(\"<b>\");\n            sb.append(s.substring(l, r));\n            sb.append(\"</b>\");\n        }\n\n        return sb.toString();\n    }\n\n\n    /**\n     * https://leetcode.com/problems/add-bold-tag-in-string/discuss/104262/short-java-solution\n     */\n    public String addBoldTag3(String s, String[] dict) {\n        int n = s.length();\n        int[] mark = new int[n+1];\n        for(String d : dict) {\n            int i = -1;\n            while((i = s.indexOf(d, i+1)) >= 0) {\n                mark[i]++;\n                mark[i + d.length()]--;\n            }\n        }\n        StringBuilder sb = new StringBuilder();\n        int sum = 0;\n        for(int i = 0; i <= n; i++) {\n            int cur = sum + mark[i];\n            if (cur > 0 && sum == 0) sb.append(\"<b>\");\n            if (cur == 0 && sum > 0) sb.append(\"</b>\");\n            if (i == n) break;\n            sb.append(s.charAt(i));\n            sum = cur;\n        }\n        return sb.toString();\n    }\n\n\n    /**\n     * https://leetcode.com/problems/add-bold-tag-in-string/discuss/104263/Java-solution-Same-as-Merge-Interval.\n     */\n    public String addBoldTag4(String s, String[] dict) {\n        List<Interval> intervals = new ArrayList<>();\n        for (String str : dict) {\n            int index = -1;\n            index = s.indexOf(str, index);\n            while (index != -1) {\n                intervals.add(new Interval(index, index + str.length()));\n                index +=1;\n                index = s.indexOf(str, index);\n            }\n        }\n        intervals = merge(intervals);\n        int prev = 0;\n        StringBuilder sb = new StringBuilder();\n        for (Interval interval : intervals) {\n            sb.append(s.substring(prev, interval.start));\n            sb.append(\"<b>\");\n            sb.append(s.substring(interval.start, interval.end));\n            sb.append(\"</b>\");\n            prev = interval.end;\n        }\n        if (prev < s.length()) {\n        \tsb.append(s.substring(prev));\n        }\n        return sb.toString();\n    }\n\n    class Interval {\n        int start, end;\n        public Interval(int s, int e) {\n            start = s;\n            end = e;\n        }\n        \n        public String toString() {\n            return \"[\" + start + \", \" + end + \"]\" ;\n        }\n    }\n\n    public List<Interval> merge(List<Interval> intervals) {\n        if (intervals == null || intervals.size() <= 1) {\n            return intervals;\n        }\n        Collections.sort(intervals, new Comparator<Interval>(){\n            public int compare(Interval a, Interval b) {\n                return a.start - b.start;\n            }\n        });\n        \n        int start = intervals.get(0).start;\n        int end = intervals.get(0).end;\n        List<Interval> res = new ArrayList<>();\n        for (Interval i : intervals) {\n            if (i.start <= end) {\n                end = Math.max(end, i.end);\n            } else {\n                res.add(new Interval(start, end));\n                start = i.start;\n                end = i.end;\n            }\n        }\n        res.add(new Interval(start, end));\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/add-bold-tag-in-string/discuss/104262/short-java-solution\n     */\n    public String addBoldTag5(String s, String[] dict) {\n        int n = s.length();\n        int[] mark = new int[n+1];\n        for(String d : dict) {\n            int i = -1;\n            while((i = s.indexOf(d, i+1)) >= 0) {\n                mark[i]++;\n                mark[i + d.length()]--;\n            }\n        }\n        StringBuilder sb = new StringBuilder();\n        int sum = 0;\n        for(int i = 0; i <= n; i++) {\n            int cur = sum + mark[i];\n            if (cur > 0 && sum == 0) sb.append(\"<b>\");\n            if (cur == 0 && sum > 0) sb.append(\"</b>\");\n            if (i == n) break;\n            sb.append(s.charAt(i));\n            sum = cur;\n        }\n        return sb.toString();\n    }\n\n\n    public String addBoldTag6(String s, String[] dict) {\n        if (s == null || s.length() == 0) return s;\n        StringBuilder sb = new StringBuilder();\n        int l = 0;\n        int r = 0;\n        int len = s.length();\n        for (int i=0; i<len; i++) {\n            for (String word: dict) {\n                if (s.startsWith(word, i)) {\n                    r = Math.max(r, i+word.length());\n                }\n            }\n            if (i < r) continue;\n            if (l != r) {\n                sb.append(\"<b>\").append(s.substring(l, r)).append(\"</b>\");\n            }\n            sb.append(s.charAt(i));\n            l = i+1;\n            r = i+1;\n        }\n        if (l != r) {\n            sb.append(\"<b>\").append(s.substring(l, r)).append(\"</b>\");\n        }\n        return sb.toString();\n    }\n\n}\n\nclass Trie {\n    Map<Character, Trie> children = new HashMap<>();\n    boolean end = false;\n\n    public void addWord(String word) {\n        addWord(word.toCharArray(), 0);\n    }\n\n    public void addWord(char[] chars, int i) {\n        if (i == chars.length) {\n            end = true;\n            return;\n        }\n        char c = chars[i];\n        if (children.containsKey(c)) {\n            children.get(c).addWord(chars, i+1);\n        } else {\n            Trie child = new Trie();\n            children.put(c, child);\n            child.addWord(chars, i+1);\n        }\n    }\n\n    public int search(char[] chars, int i) {\n        return search(chars, i, i, 0);\n    }\n\n    private int search(char[] chars, int i, int x, int len) {\n        if (x >= chars.length) return end ? x-i : len;\n        char c = chars[x];\n        if (!children.containsKey(c)) return end ? x-i : len;\n        return children.get(c).search(chars, i, x+1, len);\n    }\n\n    // public void print() {\n    //     for (char c: children.keySet()) {\n    //         System.out.println(c);\n    //         children.get(c).print();\n    //     }\n    // }\n    \n}\n"
  },
  {
    "path": "src/AddOneRowToTree623.java",
    "content": "/**\n * Given the root of a binary tree, then value v and depth d, you need to add a\n * row of nodes with value v at the given depth d. The root node is at depth 1.\n *\n * The adding rule is: given a positive integer depth d, for each NOT null tree\n * nodes N in depth d-1, create two tree nodes with value v as N's left subtree\n * root and right subtree root. And N's original left subtree should be the left\n * subtree of the new left subtree root, its original right subtree should be\n * the right subtree of the new right subtree root. If depth d is 1 that means\n * there is no depth d-1 at all, then create a tree node with value v as the\n * new root of the whole original tree, and the original tree is the new root's\n * left subtree.\n *\n * Example 1:\n * Input:\n * A binary tree as following:\n *        4\n *      /   \\\n *     2     6\n *    / \\   /\n *   3   1 5\n *\n * v = 1\n *\n * d = 2\n *\n * Output:\n *        4\n *       / \\\n *      1   1\n *     /     \\\n *    2       6\n *   / \\     /\n *  3   1   5\n *\n * ---------------------------------------------------\n *\n * Example 2:\n * Input:\n * A binary tree as following:\n *       4\n *      /\n *     2\n *    / \\\n *   3   1\n *\n * v = 1\n *\n * d = 3\n *\n * Output:\n *       4\n *      /\n *     2\n *    / \\\n *   1   1\n *  /     \\\n * 3       1\n *\n *\n * Note:\n * The given d is in range [1, maximum depth of the given tree + 1].\n * The given binary tree has at least one tree node.\n */\n\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\n\npublic class AddOneRowToTree623 {\n    public TreeNode addOneRow(TreeNode root, int v, int d) {\n        if (d == 1) {\n            TreeNode newNode = new TreeNode(v);\n            newNode.left = root;\n            return newNode;\n        }\n\n        insert(root, v, d);\n\n        return root;\n    }\n\n    private void insert(TreeNode root, int v, int d) {\n        if (root == null) {\n            return;\n        }\n        if (d == 2) {\n            TreeNode t = root.left;\n            root.left = new TreeNode(v);\n            root.left.left = t;\n            t = root.right;\n            root.right = new TreeNode(v);\n            root.right.right = t;\n        } else {\n            addOneRow(root.left, v, d-1);\n            addOneRow(root.right, v, d-1);\n        }\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/92964/java-three-methods-one-bfs-and-two-dfs\n     */\n    public TreeNode addOneRow3(TreeNode root, int v, int d) {\n        if (d == 1) {\n            TreeNode newroot = new TreeNode(v);\n            newroot.left = root;\n            return newroot;\n        }\n        LinkedList<TreeNode> queue = new LinkedList<>();\n        queue.add(root);\n        for (int i = 0; i < d-2; i++) {\n            int size = queue.size();\n            for (int j = 0; j < size; j++) {\n                TreeNode t = queue.poll();\n                if (t.left != null) queue.add(t.left);\n                if (t.right != null) queue.add(t.right);\n            }\n        }\n        while (!queue.isEmpty()) {\n            TreeNode t = queue.poll();\n            TreeNode tmp = t.left;\n            t.left = new TreeNode(v);\n            t.left.left = tmp;\n            tmp = t.right;\n            t.right = new TreeNode(v);\n            t.right.right = tmp;\n        }\n        return root;\n    }\n\n\n\n\n}\n"
  },
  {
    "path": "src/AddStrings415.java",
    "content": "/**\n * Given two non-negative integers num1 and num2 represented as string, return\n * the sum of num1 and num2.\n * \n * Note:\n * The length of both num1 and num2 is < 5100.\n * Both num1 and num2 contains only digits 0-9.\n * Both num1 and num2 does not contain any leading zero.\n * You must not use any built-in BigInteger library or convert the inputs to\n * integer directly.\n */\n\npublic class AddStrings415 {\n    public String addStrings(String num1, String num2) {\n        int carry = 0;\n        char[] chars1 = num1.toCharArray();\n        char[] chars2 = num2.toCharArray();\n        int len1 = num1.length();\n        int len2 = num2.length();\n        int len = Math.max(len1, len2);\n        StringBuilder sb = new StringBuilder();\n        int i = 0;\n        while (i < len) {\n            int a = (len1 - i - 1 < 0) ? 0 : chars1[len1 - i - 1] - '0';\n            int b = (len2 - i - 1 < 0) ? 0 : chars2[len2 - i - 1] - '0';\n            int sum = a + b + carry;\n            sb.insert(0, sum % 10);\n            carry = sum / 10;\n            i++;\n        }\n        if (carry > 0) sb.insert(0, Integer.toString(carry)); \n        return sb.toString();\n    }\n\n\n    /**\n     * https://leetcode.com/problems/add-strings/\n     */\n    public String addStrings2(String num1, String num2) {\n        char[] temp = new char[Math.max(num1.length(), num2.length())];\n        int i = num1.length() - 1, j = num2.length() - 1;\n        int index = temp.length - 1;\n        int carry = 0;\n        while (i >= 0 || j >= 0) {\n            int a = i >= 0 ? num1.charAt(i--) - '0' : 0;\n            int b = j >= 0 ? num2.charAt(j--) - '0' : 0;\n            int sum = a + b + carry;\n            temp[index--] = (char)(sum % 10 + '0');\n            carry = sum / 10;\n        }\n        \n        return carry == 0 ? new String(temp) : \"1\" + new String(temp);\n    }\n\n}\n"
  },
  {
    "path": "src/AddTwoNumbers2.java",
    "content": "/**\n * You are given two non-empty linked lists representing two non-negative\n * integers. The digits are stored in reverse order and each of their nodes\n * contain a single digit. Add the two numbers and return it as a linked list.\n *\n * You may assume the two numbers do not contain any leading zero, except the\n * number 0 itself.\n *\n * Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)\n * Output: 7 -> 0 -> 8\n */\n\n\npublic class AddTwoNumbers2 {\n    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {\n        ListNode dummy = new ListNode(0);\n        ListNode p = dummy;\n        int carry = 0;\n        while (l1 != null || l2 != null) {\n            int a = l1 == null ? 0 : l1.val;\n            int b = l2 == null ? 0 : l2.val;\n            int sum = a + b + carry;\n            ListNode n = new ListNode(sum%10);\n            p.next = n;\n            p = p.next;\n            carry = sum/10;\n            l1 = l1 == null ? null : l1.next;\n            l2 = l2 == null ? null : l2.next;\n        }\n\n        if (carry != 0) p.next = new ListNode(carry);\n\n        return dummy.next;\n    }\n\n    public ListNode addTwoNumbers2(ListNode l1, ListNode l2) {\n        ListNode dummy = new ListNode(0);\n        ListNode p = dummy;\n        int carry = 0;\n        while (l1 != null && l2 != null) {\n            int sum = l1.val + l2.val + carry;\n            p.next = new ListNode(sum % 10);\n            p = p.next;\n            carry = sum / 10;\n            l1 = l1.next;\n            l2 = l2.next;\n        }\n        \n        while (l1 != null) {\n            int sum = l1.val + carry;\n            p.next = new ListNode(sum % 10);\n            p = p.next;\n            carry = sum / 10;\n            l1 = l1.next;\n        }\n        while (l2 != null) {\n            int sum = l2.val + carry;\n            p.next = new ListNode(sum % 10);\n            p = p.next;\n            carry = sum / 10;\n            l2 = l2.next;\n        }\n        if (carry != 0) p.next =  new ListNode(carry);\n        \n        return dummy.next;\n    }\n\n}\n"
  },
  {
    "path": "src/AddTwoNumbersII445.java",
    "content": "/**\n * You are given two non-empty linked lists representing two non-negative\n * integers. The most significant digit comes first and each of their nodes\n * contain a single digit. Add the two numbers and return it as a linked list.\n * \n * You may assume the two numbers do not contain any leading zero, except the\n * number 0 itself.\n * \n * Follow up:\n * What if you cannot modify the input lists? In other words, reversing the\n * lists is not allowed.\n * \n * Example:\n * \n * Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)\n * Output: 7 -> 8 -> 0 -> 7\n */\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\npublic class AddTwoNumbersII445 {\n    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {\n        Stack<Integer> s1 = new Stack<>();\n        Stack<Integer> s2 = new Stack<>();\n        \n        while (l1 != null && l2 != null) {\n            s1.push(l1.val);\n            l1 = l1.next;\n            s2.push(l2.val);\n            l2 = l2.next;\n        }\n        while (l1 != null) {\n            s1.push(l1.val);\n            l1 = l1.next;\n        }\n        while (l2 != null) {\n            s2.push(l2.val);\n            l2 = l2.next;\n        }\n\n        ListNode dummy = new ListNode(0);\n        ListNode p = dummy;\n        int carry = 0;\n        while (!s1.isEmpty() && !s2.isEmpty()) {\n            int sum = s1.pop() + s2.pop() + carry;\n            ListNode curr = new ListNode(sum % 10);\n            curr.next = p.next;\n            p.next = curr;\n            carry = sum / 10;\n        }\n        while (!s1.isEmpty()) {\n            int sum = s1.pop() + carry;\n            ListNode curr = new ListNode(sum % 10);\n            curr.next = p.next;\n            p.next = curr;\n            carry = sum / 10;\n        }\n        while (!s2.isEmpty()) {\n            int sum = s2.pop() + carry;\n            ListNode curr = new ListNode(sum % 10);\n            curr.next = p.next;\n            p.next = curr;\n            carry = sum / 10;\n        }\n        if (carry != 0) {\n            ListNode curr = new ListNode(carry);\n            curr.next = p.next;\n            p.next = curr;\n        }\n\n        return dummy.next;\n    }\n\n\n    public ListNode addTwoNumbers2(ListNode l1, ListNode l2) {\n      ListNode ll1 = reverseList(l1);\n      ListNode ll2 = reverseList(l2);\n\n      return reverseList(addTwoNumbers0(ll1, ll2));\n    } \n\n    public ListNode addTwoNumbers0(ListNode l1, ListNode l2) {\n        ListNode dummy = new ListNode(0);\n        ListNode p = dummy;\n        int carry = 0;\n        while (l1 != null || l2 != null) {\n            int a = l1 == null ? 0 : l1.val;\n            int b = l2 == null ? 0 : l2.val;\n            int sum = a + b + carry;\n            ListNode n = new ListNode(sum%10);\n            p.next = n;\n            p = p.next;\n            carry = sum/10;\n            l1 = l1 == null ? null : l1.next;\n            l2 = l2 == null ? null : l2.next;\n        }\n\n        if (carry != 0) p.next = new ListNode(carry);\n\n        return dummy.next;\n    }\n\n    public ListNode reverseList(ListNode head) {\n        if (head == null || head.next == null) return head;\n\n        ListNode dummy = new ListNode(0);\n        ListNode tail = null;\n\n        while (head != null) {\n            ListNode t = head;\n            head = head.next;\n            tail = dummy.next;\n            dummy.next = t;\n            dummy.next.next = tail;\n        }\n\n        return dummy.next;\n    }\n\n}\n"
  },
  {
    "path": "src/AlienDictionary269.java",
    "content": "/**\n * There is a new alien language which uses the latin alphabet. However, the\n * order among letters are unknown to you. You receive a list of non-empty words\n * from the dictionary, where words are sorted lexicographically by the rules of\n * this new language. Derive the order of letters in this language.\n * \n * Example 1:\n * \n * Input:\n * [\n *   \"wrt\",\n *   \"wrf\",\n *   \"er\",\n *   \"ett\",\n *   \"rftt\"\n * ]\n * \n * Output: \"wertf\"\n * Example 2:\n * \n * Input:\n * [\n *   \"z\",\n *   \"x\"\n * ]\n * \n * Output: \"zx\"\n * Example 3:\n * \n * Input:\n * [\n *   \"z\",\n *   \"x\",\n *   \"z\"\n * ] \n * \n * Output: \"\" \n * \n * Explanation: The order is invalid, so return \"\".\n * \n * Note:\n * \n * You may assume all letters are in lowercase.\n * You may assume that if a is a prefix of b, then a must appear before b in\n * the given dictionary.\n * If the order is invalid, return an empty string.\n * There may be multiple valid order of letters, return any one of them is fine.\n */\n\n\npublic class AlienDictionary269 {\n    \n    private Set<Character> vertices = new HashSet<>();\n    private Set<Character>[] graph = new Set[26];\n\n    /**\n     * DFS based topological sort\n     */\n    public String alienOrder(String[] words) {\n        initMap(words);\n        updateOrderMap(words);\n        \n        StringBuilder sb = new StringBuilder();\n        boolean[] visited = new boolean[26];\n        for (char key: vertices) {\n            if (!visited[key - 'a']) {\n                if (!helper(key, new HashSet<Character>(), visited, sb)) return \"\";\n            }\n        }\n\n        return sb.reverse().toString();\n    }\n\n    private boolean helper(Character key, Set<Character> path, boolean[] visited, StringBuilder sb) {\n        visited[key - 'a'] = true;\n        path.add(key);\n        for (Character c: graph[key - 'a']) {\n            if (path.contains(c)) return false;\n            if (!visited[c - 'a']) {\n                if (!helper(c, path, visited, sb)) return false;\n            }\n        }\n        sb.append(key);\n        path.remove(key);\n        return true;\n    }\n    \n    private void initMap(String[] words) {    \n        for (String word: words) {\n            for (char c: word.toCharArray()) {\n                if (!vertices.contains(c)) {\n                    vertices.add(c);\n                    graph[c - 'a'] = new HashSet<Character>();\n                }\n            }\n        }\n    }\n\n    private void updateOn(String word1, String word2) {\n        int len = Math.min(word1.length(), word2.length());\n        for (int i=0; i<len; i++) {\n            if (word1.charAt(i) != word2.charAt(i)) {\n                graph[word1.charAt(i) - 'a'].add(word2.charAt(i));\n                return;\n            }\n        }\n    }\n\n    private void updateOrderMap(String[] dicts) {\n        initMap(dicts);\n        for (int i=0; i<dicts.length-1; i++) {\n            updateOn(dicts[i], dicts[i+1]);\n        }\n    }\n\n\n    /**\n     * Kahn’s algorithm for Topological Sorting\n     */\n    private int[] incomming = new int[26];\n    public String alienOrder2(String[] words) {\n        initMap(words);\n        updateOrderMap(words);\n\n        for (Character v: vertices) {\n            Set<Character> adjs = graph[v - 'a'];\n            if (adjs != null) {\n                for (Character c: adjs) {\n                    incomming[c - 'a']++;\n                }\n            }\n        }\n        \n        Queue<Character> q = new LinkedList<>();\n        for (Character c: vertices) {\n            if (incomming[c - 'a'] == 0) {\n                q.add(c);\n            }\n        }\n\n        int visited = 0;\n        StringBuilder sb = new StringBuilder();\n        while (!q.isEmpty()) {\n            char c = q.remove();\n            sb.append(c);\n            for (Character next: graph[c - 'a']) {\n                incomming[next - 'a']--;\n                if (incomming[next - 'a'] == 0) {\n                    q.add(next);\n                }\n            }\n            visited++;\n        }\n        if (visited != vertices.size()) return \"\";\n        \n        return sb.toString();\n    }\n\n\n    /**\n     * https://leetcode.com/problems/alien-dictionary/discuss/70115/3ms-Clean-Java-Solution-(DFS)\n     */\n    private final int N = 26;\n    public String alienOrder3(String[] words) {\n        boolean[][] adj = new boolean[N][N];\n        int[] visited = new int[N];\n        buildGraph(words, adj, visited);\n    \n        StringBuilder sb = new StringBuilder();\n        for(int i = 0; i < N; i++) {\n            if(visited[i] == 0) {                 // unvisited\n                if(!dfs(adj, visited, sb, i)) return \"\";\n            }\n        }\n        return sb.reverse().toString();\n    }\n    \n    public boolean dfs(boolean[][] adj, int[] visited, StringBuilder sb, int i) {\n        visited[i] = 1;                            // 1 = visiting\n        for(int j = 0; j < N; j++) {\n            if(adj[i][j]) {                        // connected\n                if(visited[j] == 1) return false;  // 1 => 1, cycle   \n                if(visited[j] == 0) {              // 0 = unvisited\n                    if(!dfs(adj, visited, sb, j)) return false;\n                }\n            }\n        }\n        visited[i] = 2;                           // 2 = visited\n        sb.append((char) (i + 'a'));\n        return true;\n    }\n    \n    public void buildGraph(String[] words, boolean[][] adj, int[] visited) {\n        Arrays.fill(visited, -1);                 // -1 = not even existed\n        for(int i = 0; i < words.length; i++) {\n            for(char c : words[i].toCharArray()) visited[c - 'a'] = 0;\n            if(i > 0) {\n                String w1 = words[i - 1], w2 = words[i];\n                int len = Math.min(w1.length(), w2.length());\n                for(int j = 0; j < len; j++) {\n                    char c1 = w1.charAt(j), c2 = w2.charAt(j);\n                    if(c1 != c2) {\n                        adj[c1 - 'a'][c2 - 'a'] = true;\n                        break;\n                    }\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/AllNodesDistanceKInBinaryTree863.java",
    "content": "/**\n * We are given a binary tree (with root node root), a target node, and an\n * integer value K.\n * \n * Return a list of the values of all nodes that have a distance K from the\n * target node.  The answer can be returned in any order.\n * \n * Example 1:\n * Input: root = [3,5,1,6,2,0,8,null,null,7,4], target = 5, K = 2\n * Output: [7,4,1]\n * \n * Explanation: \n * The nodes that are a distance 2 from the target node (with value 5)\n * have values 7, 4, and 1.\n * \n * https://s3-lc-upload.s3.amazonaws.com/uploads/2018/06/28/sketch0.png\n * \n * Note that the inputs \"root\" and \"target\" are actually TreeNodes.\n * The descriptions of the inputs above are just serializations of these objects.\n * \n * Note:\n * The given tree is non-empty.\n * Each node in the tree has unique values 0 <= node.val <= 500.\n * The target node is a node in the tree.\n * 0 <= K <= 1000.\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class AllNodesDistanceKInBinaryTree863 {\n    public List<Integer> distanceK(TreeNode root, TreeNode target, int K) {\n        List<Integer> res = new ArrayList<>();\n        if (root == null) return res;\n        if (K == 0) {\n            res.add(target.val);\n            return res;\n        }\n        distanceToRoot(root, target, K, res, 0);\n        return res;\n    }\n\n    private int distanceToRoot(TreeNode root, TreeNode target, int K, List<Integer> res, int level) {\n        if (root == null) return -1;\n        if (root.val == target.val) {\n            distanceKChildren(root, K, res);\n            return level;\n        }\n        int leftFlag = distanceToRoot(root.left, target, K, res, level + 1);\n        if (leftFlag != -1) {\n            if (leftFlag - level == K) {\n                res.add(root.val);\n            } else if (leftFlag - level < K) {\n                distanceKChildren(root.right, K - (leftFlag - level) - 1, res);\n            }\n        }\n        int rightFlag = distanceToRoot(root.right, target, K, res, level + 1);\n        if (rightFlag != -1) {\n            if (rightFlag - level == K) {\n                res.add(root.val);\n            } else if (rightFlag - level < K) {\n                distanceKChildren(root.left, K - (rightFlag - level) - 1, res);\n            }\n        }\n        return leftFlag != -1 ? leftFlag : rightFlag;\n    }\n\n    private void distanceKChildren(TreeNode root, int K, List<Integer> res) {\n        if (root == null) return;\n        Queue<TreeNode> q = new LinkedList<>();\n        q.add(root);\n        int i = 0;\n        while (!q.isEmpty() && i < K) {\n            int size = q.size();\n            for (int j=0; j<size; j++) {\n                TreeNode curr = q.poll();\n                if (curr.left != null) q.add(curr.left);\n                if (curr.right != null) q.add(curr.right);\n            }\n            i++;\n        }\n        while (!q.isEmpty()) {\n            res.add(q.poll().val);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/solution/\n     */\n    Map<TreeNode, TreeNode> parent;\n    public List<Integer> distanceK2(TreeNode root, TreeNode target, int K) {\n        parent = new HashMap();\n        dfs(root, null);\n\n        Queue<TreeNode> queue = new LinkedList();\n        queue.add(null);\n        queue.add(target);\n\n        Set<TreeNode> seen = new HashSet();\n        seen.add(target);\n        seen.add(null);\n\n        int dist = 0;\n        while (!queue.isEmpty()) {\n            TreeNode node = queue.poll();\n            if (node == null) {\n                if (dist == K) {\n                    List<Integer> ans = new ArrayList();\n                    for (TreeNode n: queue)\n                        ans.add(n.val);\n                    return ans;\n                }\n                queue.offer(null);\n                dist++;\n            } else {\n                if (!seen.contains(node.left)) {\n                    seen.add(node.left);\n                    queue.offer(node.left);\n                }\n                if (!seen.contains(node.right)) {\n                    seen.add(node.right);\n                    queue.offer(node.right);\n                }\n                TreeNode par = parent.get(node);\n                if (!seen.contains(par)) {\n                    seen.add(par);\n                    queue.offer(par);\n                }\n            }\n        }\n\n        return new ArrayList<Integer>();\n    }\n\n    public void dfs(TreeNode node, TreeNode par) {\n        if (node != null) {\n            parent.put(node, par);\n            dfs(node.left, node);\n            dfs(node.right, node);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/solution/\n     */\n    List<Integer> ans;\n    TreeNode target;\n    int K;\n    public List<Integer> distanceK3(TreeNode root, TreeNode target, int K) {\n        ans = new LinkedList();\n        this.target = target;\n        this.K = K;\n        dfs(root);\n        return ans;\n    }\n\n    // Return distance from node to target if exists, else -1\n    public int dfs(TreeNode node) {\n        if (node == null)\n            return -1;\n        else if (node == target) {\n            subtree_add(node, 0);\n            return 1;\n        } else {\n            int L = dfs(node.left), R = dfs(node.right);\n            if (L != -1) {\n                if (L == K) ans.add(node.val);\n                subtree_add(node.right, L + 1);\n                return L + 1;\n            } else if (R != -1) {\n                if (R == K) ans.add(node.val);\n                subtree_add(node.left, R + 1);\n                return R + 1;\n            } else {\n                return -1;\n            }\n        }\n    }\n\n    // Add all nodes 'K - dist' from the node to answer.\n    public void subtree_add(TreeNode node, int dist) {\n        if (node == null) return;\n        if (dist == K)\n            ans.add(node.val);\n        else {\n            subtree_add(node.left, dist + 1);\n            subtree_add(node.right, dist + 1);\n        }\n    }\n\n\n    Map<TreeNode, Integer> map = new HashMap<>();\n    public List<Integer> distanceK4(TreeNode root, TreeNode target, int K) {\n        List<Integer> res = new LinkedList<>();\n        find(root, target, K);\n        dfs(root, target, K, map.get(root), res);\n        return res;\n    }\n\n    // find target node first and store the distance in that path that we could use it later directly\n    private int find(TreeNode root, TreeNode target, int K) {\n        if (root == null) return -1;\n        if (root == target) {\n            map.put(root, 0);\n            return 0;\n        }\n        int left = find(root.left, target, K);\n        if (left >= 0) {\n            map.put(root, left + 1);\n            return left + 1;\n        }\n        int right = find(root.right, target, K);\n        if (right >= 0) {\n            map.put(root, right + 1);\n            return right + 1;\n        }\n        return -1;\n    }\n\n    private void dfs(TreeNode root, TreeNode target, int K, int length, List<Integer> res) {\n        if (root == null) return;\n        if (map.containsKey(root)) length = map.get(root);\n        if (length == K) res.add(root.val);\n        dfs(root.left, target, K, length + 1, res);\n        dfs(root.right, target, K, length + 1, res);\n    }\n\n}\n"
  },
  {
    "path": "src/AllOOneDataStructure432.java",
    "content": "/**\n * Implement a data structure supporting the following operations:\n * \n * Inc(Key) - Inserts a new key with value 1. Or increments an existing key\n * by 1. Key is guaranteed to be a non-empty string.\n * Dec(Key) - If Key's value is 1, remove it from the data structure. Otherwise\n * decrements an existing key by 1. If the key does not exist, this function\n * does nothing. Key is guaranteed to be a non-empty string.\n * GetMaxKey() - Returns one of the keys with maximal value. If no element\n * exists, return an empty string \"\".\n * GetMinKey() - Returns one of the keys with minimal value. If no element\n * exists, return an empty string \"\".\n * \n * Challenge: Perform all these in O(1) time complexity.\n */\n\n\npublic class AllOOneDataStructure432 {\n\n    class AllOne {\n        private Map<String, KeyNode> keyMap;\n        private Map<Integer, FreqNode> freqMap;\n        private FreqNode head;\n\n        /** Initialize your data structure here. */\n        public AllOne() {\n            this.keyMap = new HashMap<>();\n            this.freqMap = new HashMap<>();\n            this.head = new FreqNode();\n            this.head.next = this.head;\n            this.head.prev = this.head;\n        }\n\n        /** Inserts a new key <Key> with value 1. Or increments an existing key by 1. */\n        public void inc(String key) {\n            KeyNode node = keyMap.get(key);\n            if (node == null) {\n                node = new KeyNode(key);\n                FreqNode freqNode = freqMap.get(node.freq);\n                if (freqNode == null) {\n                    freqNode = new FreqNode(node.freq);\n                    this.freqMap.put(freqNode.freq, freqNode);\n                    addAfter(this.head, freqNode);\n                }\n                addAfter(freqNode.keyHead, node);\n                this.keyMap.put(node.key, node);\n            } else {\n                dislink(node);\n                FreqNode preFreqNode = freqMap.get(node.freq);\n                node.freq++;\n                FreqNode nextFreqNode = freqMap.get(node.freq);\n                if (nextFreqNode == null) {\n                    nextFreqNode = new FreqNode(node.freq);\n                    this.freqMap.put(nextFreqNode.freq, nextFreqNode);\n                    addAfter(preFreqNode, nextFreqNode);\n                }\n                addAfter(nextFreqNode.keyHead, node);\n                if (isEmpty(preFreqNode.keyHead)) {\n                    dislink(preFreqNode);\n                    this.freqMap.remove(preFreqNode.freq);\n                }\n            }\n        }\n\n        private void dislink(KeyNode node) {\n            node.next.prev = node.prev;\n            node.prev.next = node.next;\n        }\n\n        private void dislink(FreqNode node) {\n            node.next.prev = node.prev;\n            node.prev.next = node.next;\n        }\n\n        private void addAfter(KeyNode node, KeyNode newNode) {\n            newNode.next = node.next;\n            newNode.prev = node;\n            node.next.prev = newNode;\n            node.next = newNode;\n        }\n\n        private void addAfter(FreqNode node, FreqNode newNode) {\n            newNode.next = node.next;\n            newNode.prev = node;\n            node.next.prev = newNode;\n            node.next = newNode;\n        }\n\n        /** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */\n        public void dec(String key) {\n            KeyNode node = keyMap.get(key);\n            if (node == null) return;\n\n            dislink(node);\n            FreqNode preFreqNode = freqMap.get(node.freq);\n            node.freq--;\n            if (node.freq > 0) {\n                FreqNode nextFreqNode = freqMap.get(node.freq);\n                if (nextFreqNode == null) {\n                    nextFreqNode = new FreqNode(node.freq);\n                    this.freqMap.put(nextFreqNode.freq, nextFreqNode);\n                    addBefore(preFreqNode, nextFreqNode);\n                }\n                addAfter(nextFreqNode.keyHead, node);\n            } else {\n                this.keyMap.remove(node.key);\n            }\n            if (isEmpty(preFreqNode.keyHead)) {\n                dislink(preFreqNode);\n                this.freqMap.remove(preFreqNode.freq);\n            }\n        }\n\n        private void addBefore(FreqNode node, FreqNode newNode) {\n            newNode.next = node;\n            newNode.prev = node.prev;\n            node.prev.next = newNode;\n            node.prev = newNode;\n        }\n\n        /** Returns one of the keys with maximal value. */\n        public String getMaxKey() {\n            if (isEmpty()) return \"\";\n            return this.head.prev.keyHead.next.key;\n        }\n\n        /** Returns one of the keys with Minimal value. */\n        public String getMinKey() {\n            if (isEmpty()) return \"\";\n            return this.head.next.keyHead.next.key;\n        }\n\n        private boolean isEmpty() {\n            return isEmpty(this.head);\n        }\n\n        private boolean isEmpty(KeyNode node) {\n            return node.next == node;\n        }\n\n        private boolean isEmpty(FreqNode node) {\n            return node.next == node;\n        }\n\n        class KeyNode {\n            KeyNode prev;\n            KeyNode next;\n            String key;\n            int freq;\n            KeyNode() {\n            }\n            KeyNode(String key) {\n                this.key = key;\n                this.freq = 1;\n            }\n            KeyNode(String key, int freq) {\n                this.key = key;\n                this.freq = freq;\n            }\n        }\n\n        class FreqNode {\n            FreqNode prev;\n            FreqNode next;\n            int freq;\n            KeyNode keyHead;\n            FreqNode () {\n            }\n            FreqNode (int freq) {\n                this.freq = freq;\n                this.keyHead = new KeyNode();\n                this.keyHead.next = this.keyHead;\n                this.keyHead.prev = this.keyHead;\n            }\n        }\n    }\n\n/**\n * Your AllOne object will be instantiated and called as such:\n * AllOne obj = new AllOne();\n * obj.inc(key);\n * obj.dec(key);\n * String param_3 = obj.getMaxKey();\n * String param_4 = obj.getMinKey();\n */\n\n}\n\n"
  },
  {
    "path": "src/AllPathsFromSourceToTarget797.java",
    "content": "/**\n * Given a directed, acyclic graph of N nodes.  Find all possible paths from\n * node 0 to node N-1, and return them in any order.\n * \n * The graph is given as follows:  the nodes are0, 1, ..., graph.length - 1.\n * graph[i] is a list of all nodes j for which the edge (i, j) exists.\n * \n * Example:\n * Input: [[1,2], [3], [3], []] \n * Output: [[0,1,3],[0,2,3]] \n * Explanation: The graph looks like this:\n * 0--->1\n * |    |\n * v    v\n * 2--->3\n * There are two paths: 0 -> 1 -> 3 and 0 -> 2 -> 3.\n * \n * Note:\n * The number of nodes in the graph will be in the range [2, 15].\n * You can print different paths in any order, but you should keep the order\n * of nodes inside one path.\n */\n\npublic class AllPathsFromSourceToTarget797 {\n    public List<List<Integer>> allPathsSourceTarget(int[][] graph) {\n        List<List<Integer>> res = new ArrayList<>();\n        if (graph == null || graph.length == 0) return res;\n        int N = graph.length;\n        backtrace(graph, 0, N-1, new ArrayList<>(), res, N);\n        return res;\n    }\n\n    private void backtrace(int[][] graph, int current, int dest, List<Integer> path, List<List<Integer>> res, int N) {\n        if (current == dest) {\n            path.add(current);\n            res.add(new ArrayList<>(path));\n            path.remove(path.size() - 1);\n            return;\n        }\n        \n        path.add(current);\n        for (int child: graph[current]) {\n            backtrace(graph, child, N-1, path, res, N);\n        }\n        path.remove(path.size() - 1);\n    }\n\n\n    public List<List<Integer>> allPathsSourceTarget2(int[][] graph) {\n        List<List<Integer>> res = new ArrayList<>();\n        if (graph == null || graph.length == 0) return res;\n        int N = graph.length;\n        List<Integer> path = new ArrayList<>();\n        path.add(0);\n        backtrace2(graph, 0, N-1, path, res, N);\n        return res;\n    }\n\n    private void backtrace2(int[][] graph, int current, int dest, List<Integer> path, List<List<Integer>> res, int N) {\n        if (current == dest) {\n            res.add(new ArrayList<>(path));\n            return;\n        }\n\n        for (int child: graph[current]) {\n            path.add(child);\n            backtrace2(graph, child, N-1, path, res, N);\n            path.remove(path.size() - 1);\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/AndroidUnlockPatterns351.java",
    "content": "/**\n * Given an Android 3x3 key lock screen and two integers m and n, where\n * 1 ≤ m ≤ n ≤ 9, count the total number of unlock patterns of the Android\n * lock screen, which consist of minimum of m keys and maximum n keys.\n * \n * Rules for a valid pattern:\n * - Each pattern must connect at least m keys and at most n keys.\n * - All the keys must be distinct.\n * - If the line connecting two consecutive keys in the pattern passes through\n * any other keys, the other keys must have previously selected in the pattern.\n * No jumps through non selected key is allowed.\n * - The order of keys used matters.\n * \n * Explanation:\n * | 1 | 2 | 3 |\n * | 4 | 5 | 6 |\n * | 7 | 8 | 9 |\n * Invalid move: 4 - 1 - 3 - 6 \n * Line 1 - 3 passes through key 2 which had not been selected in the pattern.\n * \n * Invalid move: 4 - 1 - 9 - 2\n * Line 1 - 9 passes through key 5 which had not been selected in the pattern.\n * \n * Valid move: 2 - 4 - 1 - 3 - 6\n * Line 1 - 3 is valid because it passes through key 2, which had been selected in the pattern\n * \n * Valid move: 6 - 5 - 4 - 1 - 9 - 2\n * Line 1 - 9 is valid because it passes through key 5, which had been selected in the pattern.\n * \n * Example:\n * Given m = 1, n = 1, return 9.\n */\n\npublic class AndroidUnlockPatterns351 {\n    private int[][] points = new int[][]{{0,0}, {0,1}, {0,2}, {1,0}, {1,1}, {1,2}, {2,0}, {2,1}, {2,2}};\n    \n    public int numberOfPatterns(int m, int n) {\n        boolean[][] visited = new boolean[3][3];\n        // corner\n        int[] res0 = new int[1];\n        dfs(visited, 0, 0, m, n, 1, res0);\n    \n        // edge\n        int[] res1 = new int[1];\n        dfs(visited, 0, 1, m, n, 1, res1);\n    \n        // center\n        int[] res2 = new int[1];\n        dfs(visited, 1, 1, m, n, 1, res2);\n    \n        return res0[0] * 4 + res1[0] * 4 + res2[0];\n    }\n    \n    \n    private void dfs(boolean[][] visited, int i, int j, int m, int n, int level, int[] res) {\n        if (level > n) return;\n        if (level >= m && level <=n) res[0]++;\n        visited[i][j] = true;\n        for (int[] p: points) {\n            if (!visited[p[0]][p[1]] && canGo(i, j, p[0], p[1], visited)) {\n                dfs(visited, p[0], p[1], m, n, level+1, res);\n            }\n        }\n        visited[i][j] = false;\n    }\n    \n    private boolean canGo(int i1, int j1, int i2, int j2, boolean[][] visited) {\n        if (!isJumping(i1, j1, i2, j2)) return true;\n        return visited[(i1+i2)/2][(j1+j2)/2];\n    }\n    \n    private boolean isJumping(int i1, int j1, int i2, int j2) {\n        return (i1 == i2 && Math.abs(j1-j2) == 2) ||\n                (j1 == j2 && Math.abs(i1-i2) == 2) ||\n                (Math.abs(i1-i2) == 2 && Math.abs(j1-j2) == 2);\n    }\n\n\n    public int numberOfPatterns2(int m, int n) {\n        // Skip array represents number to skip between two pairs\n        int skip[][] = new int[10][10];\n        skip[1][3] = skip[3][1] = 2;\n        skip[1][7] = skip[7][1] = 4;\n        skip[3][9] = skip[9][3] = 6;\n        skip[7][9] = skip[9][7] = 8;\n        skip[1][9] = skip[9][1] = skip[2][8] = skip[8][2] = skip[3][7] = skip[7][3] = skip[4][6] = skip[6][4] = 5;\n        boolean vis[] = new boolean[10];\n        int rst = 0;\n        // DFS search each length from m to n\n        for(int i = m; i <= n; ++i) {\n            rst += DFS(vis, skip, 1, i - 1) * 4;    // 1, 3, 7, 9 are symmetric\n            rst += DFS(vis, skip, 2, i - 1) * 4;    // 2, 4, 6, 8 are symmetric\n            rst += DFS(vis, skip, 5, i - 1);        // 5\n        }\n        return rst;\n    }\n\n    // cur: the current position\n    // remain: the steps remaining\n    int DFS(boolean vis[], int[][] skip, int cur, int remain) {\n        if(remain < 0) return 0;\n        if(remain == 0) return 1;\n        vis[cur] = true;\n        int rst = 0;\n        for(int i = 1; i <= 9; ++i) {\n            // If vis[i] is not visited and (two numbers are adjacent or skip number is already visited)\n            if(!vis[i] && (skip[cur][i] == 0 || (vis[skip[cur][i]]))) {\n                rst += DFS(vis, skip, i, remain - 1);\n            }\n        }\n        vis[cur] = false;\n        return rst;\n    }\n\n\n    public int numberOfPatterns3(int m, int n) {\n        boolean[][] visited = new boolean[3][3];\n        int[] res = new int[1];\n        \n        for (int i=0; i<3; i++) {\n            for (int j=0; j<3; j++) {\n                dfs(i, j, visited, m, n, 1, res);\n            }\n        }\n        return res[0];\n    }\n    \n    private void dfs(int i, int j, boolean[][] visited, int m, int n, int len, int[] res) {\n        if (visited[i][j] || len > n) return;\n        if (len >= m) res[0]++;\n        visited[i][j] = true;\n        for (int ii=0; ii<3; ii++) {\n            int di = Math.abs(i - ii);\n            for (int jj=0; jj<3; jj++) {\n                int dj = Math.abs(j - jj);\n                if (di == 0 && dj == 0) continue;\n                if ((di == 2 && dj != 1) || (dj == 2 && di != 1)) {\n                    if (!visited[(i+ii)/2][(j+jj)/2]) continue;\n                }\n                dfs(ii, jj, visited, m, n, len+1, res);\n            }\n        }\n        visited[i][j] = false;\n    }\n\n}\n"
  },
  {
    "path": "src/AsyncJobMonitor.java",
    "content": "/**\n * \n */\n\nimport java.util.Map;\nimport java.util.Queue;\nimport java.util.concurrent.ConcurrentLinkedQueue;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.TimeUnit;\n\npublic class AsyncJobMonitor {\n\n    private static final long INIT_TIME = System.currentTimeMillis();\n\n    private Queue<Job> queue = new ConcurrentLinkedQueue<>();\n    private Map<String, Long> endMap = new ConcurrentHashMap<>();\n\n    public void start(Job job) {\n        queue.add(job);\n    }\n\n    public void end(String id, long end) {\n        endMap.put(id, end);\n        cleanQueue();\n    }\n\n    private void cleanQueue() {\n        while (!queue.isEmpty() && endMap.containsKey(queue.peek().id)) {\n            Job curr = queue.poll();\n            curr.end = endMap.get(curr.id);\n            endMap.remove(curr.id);\n            printJob(curr);\n        }\n    }\n\n    private void printJob(Job job) {\n        System.out.println(String.format(\"now: %s, job: %s, start: %s, end: %s\",\n                System.currentTimeMillis() - INIT_TIME,\n                job.id,\n                job.start - INIT_TIME,\n                job.end - INIT_TIME));\n    }\n\n    static class Job {\n        String id;\n        long start;\n        long end;\n        Job(String id, long start) {\n           this.id = id;\n           this.start = start;\n        }\n    }\n\n    public static void main(String[] args) {\n        AsyncJobMonitor monitor = new AsyncJobMonitor();\n\n        ExecutorService executorService = Executors.newFixedThreadPool(5);\n        String[] ids = new String[]{\"a\", \"b\", \"c\", \"d\", \"e\"};\n        long[] times = new long[]{5, 2, 5, 4, 1};\n        for (int i=0; i<5; i++) {\n            String id = ids[i];\n            long time = times[i];\n            executorService.execute(() -> {\n                Job job = new Job(id, System.currentTimeMillis());\n                monitor.start(job);\n                try {\n                    TimeUnit.SECONDS.sleep(time);\n                } catch (InterruptedException ex) {\n                    ex.printStackTrace();\n                }\n                monitor.end(id, System.currentTimeMillis());\n            });\n            try {\n                TimeUnit.SECONDS.sleep(1);\n            } catch (InterruptedException ex) {\n                ex.printStackTrace();\n            }\n        }\n\n        executorService.shutdown();\n    }\n\n}\n"
  },
  {
    "path": "src/AverageOfLevelsInBinaryTree637.java",
    "content": "/**\n * Given a non-empty binary tree, return the average value of the nodes on each\n * level in the form of an array.\n * \n * Example 1:\n * Input:\n *     3\n *    / \\\n *   9  20\n *     /  \\\n *    15   7\n * Output: [3, 14.5, 11]\n * Explanation:\n * The average value of nodes on level 0 is 3,  on level 1 is 14.5, and on\n * level 2 is 11. Hence return [3, 14.5, 11].\n * \n * Note:\n * The range of node's value is in the range of 32-bit signed integer.\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class AverageOfLevelsInBinaryTree637 {\n    public List<Double> averageOfLevels(TreeNode root) {\n        List<Double> res = new ArrayList<>();        \n        Queue<TreeNode> q = new LinkedList<>();\n        q.add(root);\n        while (!q.isEmpty()) {\n            int size = q.size();\n            long sum = 0L;\n            for (int i=0; i<size; i++) {\n                TreeNode curr = q.poll();\n                if (curr.left != null) q.add(curr.left);\n                if (curr.right != null) q.add(curr.right);\n                sum += curr.val;\n            }\n            res.add(sum * 1.0 / size);\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/BackspaceStringCompare844.java",
    "content": "/**\n * Given two strings S and T, return if they are equal when both are typed into\n * empty text editors. # means a backspace character.\n * \n * Example 1:\n * Input: S = \"ab#c\", T = \"ad#c\"\n * Output: true\n * Explanation: Both S and T become \"ac\".\n * \n * Example 2:\n * Input: S = \"ab##\", T = \"c#d#\"\n * Output: true\n * Explanation: Both S and T become \"\".\n * \n * Example 3:\n * Input: S = \"a##c\", T = \"#a#c\"\n * Output: true\n * Explanation: Both S and T become \"c\".\n * \n * Example 4:\n * Input: S = \"a#c\", T = \"b\"\n * Output: false\n * Explanation: S becomes \"c\" while T becomes \"b\".\n * \n * Note:\n * 1 <= S.length <= 200\n * 1 <= T.length <= 200\n * S and T only contain lowercase letters and '#' characters.\n * \n * Follow up:\n * Can you solve it in O(N) time and O(1) space?\n */\n\npublic class BackspaceStringCompare844 {\n    public boolean backspaceCompare(String S, String T) {\n        int lenS = S.length();\n        int lenT = T.length();\n    \n        int indexS = lenS-1;\n        int countS = 0;\n        int indexT = lenT-1;\n        int countT = 0;\n        while (indexS >= 0 && indexT >= 0) {\n            char charS = S.charAt(indexS);\n            char charT = T.charAt(indexT);\n    \n            if (charS != '#' && charT != '#' && countS == 0 && countT == 0) {\n                if (charS != charT) return false;\n                indexS--;\n                indexT--;\n            } else {\n                if (charS == '#') {\n                    countS++;\n                    indexS--;\n                } else {\n                    if (countS != 0) {\n                        countS--;\n                        indexS--;\n                    }\n                }\n                if (charT == '#') {\n                    countT++;\n                    indexT--;\n                } else {\n                    if (countT != 0) {\n                        countT--;\n                        indexT--;\n                    }\n                }\n            }\n        }\n    \n        while (indexS >= 0) {\n            if (S.charAt(indexS) == '#') {\n                countS++;\n            } else {\n                if (countS == 0) return false;\n                countS--;\n            }\n            indexS--;\n        }\n        while (indexT >= 0) {\n            if (T.charAt(indexT) == '#') {\n                countT++;\n            } else {\n                if (countT == 0) return false;\n                countT--;\n            }\n            indexT--;\n        }\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/backspace-string-compare/solution/\n     */\n    public boolean backspaceCompare2(String S, String T) {\n        return build(S).equals(build(T));\n    }\n\n    public String build(String S) {\n        Stack<Character> ans = new Stack();\n        for (char c: S.toCharArray()) {\n            if (c != '#')\n                ans.push(c);\n            else if (!ans.empty())\n                ans.pop();\n        }\n        return String.valueOf(ans);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/backspace-string-compare/solution/\n     */\n    public boolean backspaceCompare3(String S, String T) {\n      int i = S.length() - 1, j = T.length() - 1;\n      int skipS = 0, skipT = 0;\n\n      while (i >= 0 || j >= 0) { // While there may be chars in build(S) or build (T)\n          while (i >= 0) { // Find position of next possible char in build(S)\n              if (S.charAt(i) == '#') {skipS++; i--;}\n              else if (skipS > 0) {skipS--; i--;}\n              else break;\n          }\n          while (j >= 0) { // Find position of next possible char in build(T)\n              if (T.charAt(j) == '#') {skipT++; j--;}\n              else if (skipT > 0) {skipT--; j--;}\n              else break;\n          }\n          // If two actual characters are different\n          if (i >= 0 && j >= 0 && S.charAt(i) != T.charAt(j))\n              return false;\n          // If expecting to compare char vs nothing\n          if ((i >= 0) != (j >= 0))\n              return false;\n          i--; j--;\n      }\n      return true;\n  }\n\n}\n"
  },
  {
    "path": "src/BalancedBinaryTree110.java",
    "content": "/**\n * Given a binary tree, determine if it is height-balanced.\n *\n * For this problem, a height-balanced binary tree is defined as a binary tree\n * in which the depth of the two subtrees of every node never differ by\n * more than 1.\n */\n\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\n\npublic class BalancedBinaryTree110 {\n\n    public boolean isBalanced(TreeNode root) {\n        if (root == null) {\n            return true;\n        }\n\n        int depthL = depth(root.left);\n        int depthR = depth(root.right);\n\n        return Math.abs(depthL - depthR) <= 1 && isBalanced(root.left) && isBalanced(root.right);\n\n    }\n\n    private int depth(TreeNode node) {\n        if (node == null) {\n            return 0;\n        }\n\n        int depthL = depth(node.left);\n        int depthR = depth(node.right);\n\n        return Math.max(depthL, depthR) + 1;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/11007/java-solution-based-on-height-check-left-and-right-node-in-every-recursion-to-avoid-further-useless-search\n     */\n    public boolean isBalanced2(TreeNode root) {\n        if (root == null) {\n            return true;\n        }\n        return height(root) != -1;\n\n    }\n\n    public int height(TreeNode node){\n        if (node == null) {\n            return 0;\n        }\n\n        int lH = height(node.left);\n        if (lH == -1) {\n            return -1;\n        }\n\n        int rH = height(node.right);\n        if (rH == -1) {\n            return -1;\n        }\n\n        if (lH-rH < -1 || lH-rH > 1) {\n            return -1;\n        }\n\n        return Math.max(lH,rH) + 1;\n    }\n\n\n    public static void main(String[] args) {\n        BalancedBinaryTree110 bbt = new BalancedBinaryTree110();\n\n        TreeNode root1 = new TreeNode(2);\n        root1.left = new TreeNode(1);\n        root1.right = new TreeNode(3);\n\n        TreeNode root3 = new TreeNode(2);\n        root3.left = new TreeNode(1);\n\n        TreeNode root2 = new TreeNode(2);\n        root2.left = root3;\n\n\n        TreeNode n1 = new TreeNode(1);\n        TreeNode n2 = new TreeNode(2);\n        TreeNode n3 = new TreeNode(3);\n        TreeNode n4 = new TreeNode(4);\n        TreeNode n5 = new TreeNode(5);\n        TreeNode n6 = new TreeNode(6);\n        TreeNode n7 = new TreeNode(7);\n        TreeNode n8 = new TreeNode(8);\n\n        n4.left = n7;\n        n2.left = n4;\n        n2.right = n5;\n        n1.left = n2;\n\n        n6.right = n8;\n        n3.right = n6;\n        n1.right = n3;\n\n\n        System.out.println(\"-------- 1\");\n        System.out.println(bbt.isBalanced(root1));\n        System.out.println(\"-------- 2\");\n        System.out.println(bbt.isBalanced(root2));\n        System.out.println(\"-------- 3\");\n        System.out.println(bbt.isBalanced(root3));\n        System.out.println(\"-------- 4\");\n        System.out.println(bbt.isBalanced(n1));\n    }\n}\n"
  },
  {
    "path": "src/BaseballGame682.java",
    "content": "/**\n * You're now a baseball game point recorder.\n * \n * Given a list of strings, each string can be one of the 4 following types:\n * \n * Integer (one round's score): Directly represents the number of points you get in this round.\n * \"+\" (one round's score): Represents that the points you get in this round are the sum of the last two valid round's points.\n * \"D\" (one round's score): Represents that the points you get in this round are the doubled data of the last valid round's points.\n * \"C\" (an operation, which isn't a round's score): Represents the last valid round's points you get were invalid and should be removed.\n * Each round's operation is permanent and could have an impact on the round before and the round after.\n * \n * You need to return the sum of the points you could get in all the rounds.\n * \n * Example 1:\n * Input: [\"5\",\"2\",\"C\",\"D\",\"+\"]\n * Output: 30\n * Explanation: \n * Round 1: You could get 5 points. The sum is: 5.\n * Round 2: You could get 2 points. The sum is: 7.\n * Operation 1: The round 2's data was invalid. The sum is: 5.  \n * Round 3: You could get 10 points (the round 2's data has been removed). The sum is: 15.\n * Round 4: You could get 5 + 10 = 15 points. The sum is: 30.\n * \n * Example 2:\n * Input: [\"5\",\"-2\",\"4\",\"C\",\"D\",\"9\",\"+\",\"+\"]\n * Output: 27\n * Explanation: \n * Round 1: You could get 5 points. The sum is: 5.\n * Round 2: You could get -2 points. The sum is: 3.\n * Round 3: You could get 4 points. The sum is: 7.\n * Operation 1: The round 3's data is invalid. The sum is: 3.  \n * Round 4: You could get -4 points (the round 3's data has been removed). The sum is: -1.\n * Round 5: You could get 9 points. The sum is: 8.\n * Round 6: You could get -4 + 9 = 5 points. The sum is 13.\n * Round 7: You could get 9 + 5 = 14 points. The sum is 27.\n * \n * Note:\n * The size of the input list will be between 1 and 1000.\n * Every integer represented in the list will be between -30000 and 30000.\n */\n\npublic class BaseballGame682 {\n    public int calPoints(String[] ops) {\n        if (ops == null || ops.length == 0) return 0;\n        Stack<Integer> stack = new Stack<>();\n        int sum = 0;\n        for (String op: ops) {\n            if (op.equals(\"+\")) {\n                if (stack.size() >= 2) {\n                    int e1 = stack.pop();\n                    int e2 = stack.peek();\n                    int twoSum = e1 + e2;\n                    sum += twoSum;\n                    stack.push(e1);\n                    stack.push(twoSum);\n                }\n            } else if (op.equals(\"D\")) {\n                if (!stack.isEmpty()) {\n                    int doubledScore = stack.peek() * 2;\n                    sum += doubledScore;\n                    stack.push(doubledScore);\n                }\n            } else if (op.equals(\"C\")) {\n                if (!stack.isEmpty()) {\n                    int lastScore = stack.pop();\n                    sum -= lastScore;\n                }\n            } else {\n                int now = Integer.parseInt(op);\n                sum += now;\n                stack.push(now);\n            }\n        }\n        \n        return sum;\n    }\n\n}\n"
  },
  {
    "path": "src/BasicCalculator224.java",
    "content": "/**\n * Implement a basic calculator to evaluate a simple expression string.\n *\n * The expression string may contain open ( and closing parentheses ), the\n * plus + or minus sign -, non-negative integers and empty spaces .\n *\n * You may assume that the given expression is always valid.\n *\n * Some examples:\n * \"1 + 1\" = 2\n * \" 2-1 + 2 \" = 3\n * \"(1+(4+5+2)-3)+(6+8)\" = 23\n * Note: Do not use the eval built-in library function.\n *\n */\n\n\npublic class BasicCalculator224 {\n    public int calculate(String s) {\n        int L = s.length();\n        int result = 0;\n        int start = 0;\n        boolean isNum = false;\n        boolean doPlus = true;\n        for (int i=0; i<L; i++) {\n            char c = s.charAt(i);\n            if (isDigit(c) && !isNum) {\n                start = i;\n                isNum = true;\n                continue;\n            }\n            if (isDigit(c)) continue;\n\n            if (isNum) {\n                result = doCal(s, result, start, i, doPlus);\n                isNum = false;\n            }\n            if (isPlus(c)) {\n                doPlus = true;\n            } else if (isMunis(c)) {\n                doPlus = false;\n            } else if (isOpen(c)) {\n                List<Integer> l = calculate(s, i+1, L);\n                result = doCal(result, l.get(0), doPlus);\n                i = l.get(1);\n            }\n        }\n        if (isNum) {\n            return doCal(s, result, start, L, doPlus);\n        }\n\n        return result;\n    }\n\n    private List<Integer> calculate(String s, int from, int L) {\n        int result = 0;\n        int start = from;\n        int to = from;\n        boolean isNum = false;\n        boolean doPlus = true;\n        for (int i=from; i<L; i++) {\n            char c = s.charAt(i);\n            if (isDigit(c) && !isNum) {\n                start = i;\n                isNum = true;\n                continue;\n            }\n            if (isDigit(c)) continue;\n\n            if (isNum) {\n                result = doCal(s, result, start, i, doPlus);\n                isNum = false;\n            }\n            if (isPlus(c)) {\n                doPlus = true;\n            } else if (isMunis(c)) {\n                doPlus = false;\n            } else if (isOpen(c)) {\n                List<Integer> l = calculate(s, i+1, L);\n                result = doCal(result, l.get(0), doPlus);\n                i = l.get(1);\n            } else {\n                to = i;\n                break;\n            }\n        }\n        if (isNum) {\n            return Arrays.asList(doCal(s, result, start, to, doPlus), to);\n        }\n\n        return Arrays.asList(result, to);\n    }\n\n    private int doCal(String s, int previous, int start, int end, boolean doPlus) {\n        int num = Integer.parseInt(s.substring(start, end));\n        return doCal(previous, num, doPlus);\n    }\n\n    private int doCal(int previous, int num, boolean doPlus) {\n        if (doPlus) {\n            return previous + num;\n        } else {\n            return previous - num;\n        }\n    }\n\n    private boolean isPlus(char c) {\n        return c == '+';\n    }\n    private boolean isMunis(char c) {\n        return c == '-';\n    }\n    private boolean isOpen(char c) {\n        return c == '(';\n    }\n    private boolean isClose(char c) {\n        return c == ')';\n    }\n    private boolean isDigit(char c) {\n        return c >= '0' && c <= '9';\n    }\n    private boolean isSpace(char c) {\n        return c == ' ';\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/15816/iterative-java-solution-with-stack\n     */\n    public int calculate2(String s) {\n        Stack<Integer> stack = new Stack<Integer>();\n        int result = 0;\n        int number = 0;\n        int sign = 1;\n        for(int i = 0; i < s.length(); i++){\n            char c = s.charAt(i);\n            if(Character.isDigit(c)){\n                number = 10 * number + (int)(c - '0');\n            }else if(c == '+'){\n                result += sign * number;\n                number = 0;\n                sign = 1;\n            }else if(c == '-'){\n                result += sign * number;\n                number = 0;\n                sign = -1;\n            }else if(c == '('){\n                //we push the result first, then sign;\n                stack.push(result);\n                stack.push(sign);\n                //reset the sign and result for the value in the parenthesis\n                sign = 1;\n                result = 0;\n            }else if(c == ')'){\n                result += sign * number;\n                number = 0;\n                result *= stack.pop();    //stack.pop() is the sign before the parenthesis\n                result += stack.pop();   //stack.pop() now is the result calculated before the parenthesis\n            }\n        }\n        if(number != 0) result += sign * number;\n        return result;\n    }\n\n\n    public int calculate3(String s) {\n        char[] chars = s.toCharArray();\n        int i = 0;\n        int N = chars.length;\n        int sign = 1;\n        Stack<String> stack = new Stack<>();\n        while (i < N) {\n            char ch = chars[i];\n            if (ch == ' ') {\n                i++;\n            } else if (ch == '+') {\n                sign = 1;\n                i++;\n            } else if (ch == '-') {\n                sign = -1;\n                i++;\n            } else if (ch == '(') {\n                stack.push((sign == 1 ? \"+\" : \"-\") + Character.toString(ch));\n                sign = 1;\n                i++;\n            } else if (ch == ')') {\n                int local = 0;\n                while (!stack.isEmpty() && !stack.peek().endsWith(\"(\")) {\n                    local += Integer.valueOf(stack.pop());\n                }\n                if (stack.isEmpty()) {\n                    stack.push(Integer.toString(local));\n                } else {\n                    String op = stack.pop();\n                    if (op.startsWith(\"+\")) {\n                        stack.push(Integer.toString(local));\n                    } else {\n                        stack.push(Integer.toString(-local));\n                    }\n                }\n                i++;\n            } else {\n                int j = getNum(chars, i);\n                stack.push((sign == 1 ? \"+\" : \"-\") + s.substring(i, j));\n                i = j;\n            }\n            \n        }\n        int res = 0;\n        while (!stack.isEmpty()) res += Integer.valueOf(stack.pop());\n        return res;\n    }\n\n    private int getNum(char[] chars, int i) {\n        int j = i;\n        while (j < chars.length && Character.isDigit(chars[j])) j++;\n        return j;\n    }\n\n    /**\n     * https://leetcode.com/problems/basic-calculator-ii/discuss/63088/Explanation-for-Java-O(n)-time-and-O(1)-space-solution\n     */\n    public int calculate4(String s) {\n        int pre = 0, curr = 0, sign = 1, op = 0, num = 0;\n        \n        for (int i = 0; i < s.length(); i++) {\n            if (Character.isDigit(s.charAt(i))) {\n                num = num * 10 + (s.charAt(i) - '0');\n                if (i == s.length() - 1 || !Character.isDigit(s.charAt(i + 1))) {\n                    curr = (op == 0 ? num : (op == 1 ? curr * num : curr / num));\n                }\n                \n            } else if (s.charAt(i) == '*' || s.charAt(i) == '/') {\n                op = (s.charAt(i) == '*' ? 1 : -1);\n                num = 0;\n                \n            } else if (s.charAt(i) == '+' || s.charAt(i) == '-') {\n                pre += sign * curr;\n                sign = (s.charAt(i) == '+' ? 1 : -1);\n                op = 0;\n                num = 0;\n            }\n        }\n        \n        return pre + sign * curr;\n    }\n\n}\n"
  },
  {
    "path": "src/BasicCalculatorII227.java",
    "content": "/**\n * Implement a basic calculator to evaluate a simple expression string.\n * \n * The expression string contains only non-negative integers, +, -, *, /\n * operators and empty spaces . The integer division should truncate toward\n * zero.\n * \n * Example 1:\n * Input: \"3+2*2\"\n * Output: 7\n * \n * Example 2:\n * Input: \" 3/2 \"\n * Output: 1\n * \n * Example 3:\n * Input: \" 3+5 / 2 \"\n * Output: 5\n * \n * Note:\n * You may assume that the given expression is always valid.\n * Do not use the eval built-in library function.\n */\n\npublic class BasicCalculatorII227 {\n    public int calculate(String s) {\n        char[] chars = s.toCharArray();\n        int N = s.length();\n        int res = 0;\n        int i = 0;\n        while (i < N && chars[i] == ' ') i++;\n        int j = getNum(chars, i);\n        int num = Integer.valueOf(s.substring(i, j));\n        i = j;\n        while (i < N) {\n            while (i < N && chars[i] == ' ') i++;\n            if (i == N) break;\n            char op = chars[i];\n            i++;\n            while (i < N && chars[i] == ' ') i++;\n            if (i == N) break;\n            j = getNum(chars, i);\n            int curr = Integer.valueOf(s.substring(i, j));\n            i = j;\n            if (op == '+') {\n                res += num;\n                num = curr;\n            } else if (op == '-') {\n                res += num;\n                num = -curr;\n            } else if (op == '*') {\n                num *= curr;\n            } else {\n                num /= curr;\n            }\n        }\n        return res + num;\n    }\n\n    private int getNum(char[] chars, int i) {\n        int j = i;\n        while (j < chars.length && Character.isDigit(chars[j])) {\n            j++;\n        }\n        return j;\n    }\n\n\n\n\n\n}\n\n"
  },
  {
    "path": "src/Bench.java",
    "content": "/**\n * https://www.careercup.com/question?id=6204431937830912\n */\n\nimport java.util.Arrays;\nimport java.util.PriorityQueue;\nimport java.util.Comparator;\n\npublic class Bench {\n    public static void sitFarestFromPeople(boolean[] bench, int k) {\n        if (bench == null || bench.length == 0 || k <= 0) return;\n        Comparator<Range> comp = (r1, r2) -> Integer.compare(r2.right - r2.left, r1.right - r1.left);\n        PriorityQueue<Range> pq = new PriorityQueue<>(1, comp);\n        int L = bench.length;\n        int pre = -1;\n        for (int i=0; i<L; i++) {\n            if (!bench[i]) continue;\n            if (pre == -1) {\n                pq.add(new Range(-i, i));\n            } else if (pre + 1 < i) {\n                pq.add(new Range(pre, i));\n            }\n            pre = i;\n        }\n        if (pre != -1) {\n            pq.add(new Range(pre, (L-1-pre)*2+pre));\n        } else {\n            pq.add(new Range(-(L-1), L-1));\n        }\n\n        for (int j=0; j<k; j++) {\n            if (pq.isEmpty()) return;\n            Range curr = pq.poll();\n            int mid = (curr.right - curr.left) / 2 + curr.left;\n            bench[mid] = true;\n            if (curr.left >= 0 && curr.left + 1 < mid) {\n                pq.add(new Range(curr.left, mid));\n            }\n            if (curr.right < L && mid + 1 < curr.right) {\n                pq.add(new Range(mid, curr.right));\n            }\n        }\n    }\n\n    static class Range {\n        int left;\n        int right;\n        Range (int l, int r) {\n            this.left = l;\n            this.right = r;\n        }\n    }\n\n\n    public static void main(String[] args) {\n        boolean[] bench1 = new boolean[]{true, false, false, false, true, false, true};\n        sitFarestFromPeople(bench1, 1);\n        System.out.println(Arrays.toString(bench1));\n\n        boolean[] bench2 = new boolean[]{true, false, false, false, false, true, false, true};\n        sitFarestFromPeople(bench2, 2);\n        System.out.println(Arrays.toString(bench2));\n\n        boolean[] bench3 = new boolean[]{false, false, false, true, false, true};\n        sitFarestFromPeople(bench3, 2);\n        System.out.println(Arrays.toString(bench3));\n    }\n\n}\n"
  },
  {
    "path": "src/BestMeetingPoint296.java",
    "content": "/**\n * A group of two or more people wants to meet and minimize the total travel\n * distance. You are given a 2D grid of values 0 or 1, where each 1 marks the\n * home of someone in the group. The distance is calculated using\n * Manhattan Distance (http://en.wikipedia.org/wiki/Taxicab_geometry), where\n * distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|.\n * \n * Example:\n * \n * Input:\n * 1 - 0 - 0 - 0 - 1\n * |   |   |   |   |\n * 0 - 0 - 0 - 0 - 0\n * |   |   |   |   |\n * 0 - 0 - 1 - 0 - 0\n * \n * Output: 6\n * \n * Explanation: Given three people living at (0,0), (0,4), and (2,2):\n * The point (0,2) is an ideal meeting point, as the total travel distance\n * of 2+2+2=6 is minimal. So return 6.\n */\n\npublic class BestMeetingPoint296 {\n    /**\n     * https://leetcode.com/problems/best-meeting-point/discuss/74186/14ms-java-solution\n     */\n    public int minTotalDistance(int[][] grid) {\n        int m = grid.length;\n        int n = grid[0].length;\n        List<Integer> I = new ArrayList<>(m);\n        List<Integer> J = new ArrayList<>(n);\n        for(int i = 0; i < m; i++){\n            for(int j = 0; j < n; j++){\n                if(grid[i][j] == 1){\n                    I.add(i);\n                    J.add(j);\n                }\n            }\n        }\n        return getMin(I) + getMin(J);\n    }\n\n    private int getMin(List<Integer> list){\n        int ret = 0;\n        Collections.sort(list);\n        int i = 0;\n        int j = list.size() - 1;\n        while(i < j){\n            ret += list.get(j--) - list.get(i++);\n        }\n        return ret;\n    }\n\n}\n"
  },
  {
    "path": "src/BestTimeToBuyAndSellStock121.java",
    "content": "/**\n * Say you have an array for which the ith element is the price of a given\n * stock on day i.\n *\n * If you were only permitted to complete at most one transaction (ie, buy one\n * and sell one share of the stock), design an algorithm to find the maximum\n * profit.\n *\n * Example 1:\n * Input: [7, 1, 5, 3, 6, 4]\n * Output: 5\n *\n * max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price)\n *\n * Example 2:\n * Input: [7, 6, 4, 3, 1]\n * Output: 0\n *\n * In this case, no transaction is done, i.e. max profit = 0.\n *\n */\n\n\npublic class BestTimeToBuyAndSellStock121 {\n    public int maxProfit(int[] prices) {\n        if (prices == null || prices.length <= 1) return 0;\n\n        int minSoFar = Integer.MAX_VALUE;\n        int res = 0;\n\n        for (int p: prices) {\n            if (p > minSoFar) {\n                res = Math.max(res, p - minSoFar);\n            } else {\n                minSoFar = p;\n            }\n        }\n\n        return res;\n    }\n\n    public int maxProfit2(int[] prices) {\n        int buy = Integer.MIN_VALUE;\n        int sell = 0;\n        for (int p: prices) {\n            int oldBuy = buy;\n            buy = Math.max(buy, - p);\n            sell = Math.max(sell, oldBuy + p);\n        }\n        return sell;\n    }\n\n}\n"
  },
  {
    "path": "src/BestTimeToBuyAndSellStockII122.java",
    "content": "/**\n * Say you have an array for which the ith element is the price of a given stock\n * on day i.\n *\n * Design an algorithm to find the maximum profit. You may complete as many\n * transactions as you like (ie, buy one and sell one share of the stock\n * multiple times). However, you may not engage in multiple transactions at\n * the same time (ie, you must sell the stock before you buy again).\n *\n */\n\n\npublic class BestTimeToBuyAndSellStockII122 {\n    public int maxProfit(int[] prices) {\n        if (prices == null || prices.length <= 1) return 0;\n\n        int[] buy = new int[prices.length];\n        int[] sell = new int[prices.length];\n\n        buy[0] = -prices[0];\n\n        for (int i=1; i<prices.length; i++) {\n            buy[i] = Math.max(buy[i-1], sell[i-1]-prices[i]);\n            sell[i] = Math.max(sell[i-1], buy[i-1]+prices[i]);\n        }\n\n        return sell[prices.length-1];\n    }\n\n\n    public int maxProfit2(int[] prices) {\n        if (prices == null || prices.length <= 1) return 0;\n\n        int buy = -prices[0];\n        int preBuy = -prices[0];\n        int sell = 0;\n        int preSell = 0;\n\n        for (int i=1; i<prices.length; i++) {\n            preBuy = buy;\n            preSell = sell;\n            buy = Math.max(preBuy, preSell - prices[i]);\n            sell = Math.max(preSell, preBuy + prices[i]);\n        }\n\n        return sell;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/solution/\n     */\n    public int maxProfit3(int[] prices) {\n        int profit=0;\n\n        for(int i=1;i<prices.length;i++){\n            if(prices[i]>prices[i-1]){\n                profit+= prices[i]-prices[i-1];\n            }\n        }\n        return profit;\n    }\n\n\n}\n"
  },
  {
    "path": "src/BestTimeToBuyAndSellStockIII123.java",
    "content": "/**\n * Say you have an array for which the ith element is the price of a given\n * stock on day i.\n *\n * Design an algorithm to find the maximum profit. You may complete at most\n * two transactions.\n *\n * Note:\n * You may not engage in multiple transactions at the same time (ie, you must\n * sell the stock before you buy again).\n *\n */\n\npublic class BestTimeToBuyAndSellStockIII123 {\n    public int maxProfit(int[] prices) {\n        if (prices == null || prices.length <= 1) return 0;\n\n        int buy = Integer.MIN_VALUE;\n        int preBuy = Integer.MIN_VALUE;\n        int sell = 0;\n        int preSell = 0;\n\n        for (int p: prices) {\n            sell = Math.max(sell, buy + p);\n            buy = Math.max(buy, preSell - p);\n            preSell = Math.max(preSell, preBuy + p);\n            preBuy = Math.max(preBuy, - p);\n        }\n        return sell;\n    }\n\n\n    public int maxProfit2(int[] prices) {\n        return maxProfit(2, prices);\n    }\n\n    public int maxProfit(int k, int[] prices) {\n        if (prices == null || prices.length <= 1 || k <= 0) return 0;\n        \n        if (k >= prices.length >>> 1) {\n            int profit = 0;\n            for(int i=1; i<prices.length; i++){\n                if(prices[i] > prices[i-1]){\n                    profit += prices[i] - prices[i-1];\n                }\n            }\n            return profit;\n        }\n        \n        int[] buy = new int[k+1];\n        int[] sell = new int[k+1];\n        for (int j=0; j<=k; j++) {\n            buy[j] = Integer.MIN_VALUE;\n        }\n        for (int price : prices) {\n            for (int j=1; j<=k; j++) {\n                buy[j] = Math.max(buy[j], sell[j-1] - price);\n                sell[j] = Math.max(sell[j], buy[j] + price);\n            }\n        }\n        return sell[k];\n    }\n\n\n\n}\n"
  },
  {
    "path": "src/BestTimeToBuyAndSellStockIV188.java",
    "content": "/**\n * Say you have an array for which the ith element is the price of a given\n * stock on day i.\n * \n * Design an algorithm to find the maximum profit. You may complete at most\n * k transactions.\n * \n * Note:\n * You may not engage in multiple transactions at the same time (ie, you must\n * sell the stock before you buy again).\n * \n * Example 1:\n * \n * Input: [2,4,1], k = 2\n * Output: 2\n * Explanation:\n * Buy on day 1 (price = 2) and sell on day 2 (price = 4), profit = 4-2 = 2.\n * \n * Example 2:\n * \n * Input: [3,2,6,5,0,3], k = 2\n * Output: 7\n * Explanation:\n * Buy on day 2 (price = 2) and sell on day 3 (price = 6), profit = 6-2 = 4.\n * Then buy on day 5 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.\n * \n */\n\npublic class BestTimeToBuyAndSellStockIV188 {\n    public int maxProfit(int k, int[] prices) {\n        if (prices == null || prices.length <= 1 || k <= 0) return 0;\n        \n        if (k >= prices.length >>> 1) {\n            int profit = 0;\n            for(int i=1; i<prices.length; i++){\n                if(prices[i] > prices[i-1]){\n                    profit += prices[i] - prices[i-1];\n                }\n            }\n            return profit;\n        }\n        \n        int[] buy = new int[k];\n        int[] sell = new int[k];\n        for (int j=0; j<k; j++) {\n            buy[j] = Integer.MIN_VALUE;\n        }\n        for (int i=1; i<=prices.length; i++) {\n            for (int j=1; j<k; j++) {\n                buy[j] = Math.max(buy[j], sell[j-1] - prices[i-1]);\n                sell[j] = Math.max(sell[j], buy[j] + prices[i-1]);\n            }\n        }\n        return sell[k-1];\n    }\n\n\n    /**\n     * https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/discuss/54113/A-Concise-DP-Solution-in-Java\n     */\n    public int maxProfit2(int k, int[] prices) {\n        int len = prices.length;\n        if (k >= len / 2) return quickSolve(prices);\n        \n        int[][] t = new int[k + 1][len];\n        for (int i = 1; i <= k; i++) {\n            int tmpMax =  -prices[0];\n            for (int j = 1; j < len; j++) {\n                t[i][j] = Math.max(t[i][j - 1], prices[j] + tmpMax);\n                tmpMax =  Math.max(tmpMax, t[i - 1][j - 1] - prices[j]);\n            }\n        }\n        return t[k][len - 1];\n    }\n\n    private int quickSolve(int[] prices) {\n        int len = prices.length, profit = 0;\n        for (int i = 1; i < len; i++)\n            // as long as there is a price gap, we gain a profit.\n            if (prices[i] > prices[i - 1]) profit += prices[i] - prices[i - 1];\n        return profit;\n    }\n\n}\n"
  },
  {
    "path": "src/BestTimeToBuyAndSellStockWithCooldown309.java",
    "content": "/**\n * Say you have an array for which the ith element is the price of a given\n * stock on day i.\n *\n * Design an algorithm to find the maximum profit. You may complete as many\n * transactions as you like (ie, buy one and sell one share of the stock\n * multiple times) with the following restrictions:\n *\n * You may not engage in multiple transactions at the same time (ie, you\n * must sell the stock before you buy again).\n *\n * After you sell your stock, you cannot buy stock on next day.\n * (ie, cooldown 1 day)\n *\n * Example:\n *\n * prices = [1, 2, 3, 0, 2]\n * maxProfit = 3\n * transactions = [buy, sell, cooldown, buy, sell]\n *\n */\n\n\npublic class BestTimeToBuyAndSellStockWithCooldown309 {\n    /**\n     * https://discuss.leetcode.com/topic/30421/share-my-thinking-process\n     */\n    public int maxProfit(int[] prices) {\n        int sell = 0, prev_sell = 0, buy = Integer.MIN_VALUE, prev_buy;\n        for (int price : prices) {\n            prev_buy = buy;\n            buy = Math.max(prev_sell - price, prev_buy);\n            prev_sell = sell;\n            sell = Math.max(prev_buy + price, prev_sell);\n        }\n        return sell;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/30431/easiest-java-solution-with-explanations/35\n     */\n    public int maxProfit2(int[] prices) {\n        if(prices == null || prices.length <= 1) return 0;\n\n        int b0 = -prices[0], b1 = b0;\n        int s0 = 0, s1 = 0, s2 = 0;\n\n        for(int i = 1; i < prices.length; i++) {\n        \tb0 = Math.max(b1, s2 - prices[i]);\n        \ts0 = Math.max(s1, b1 + prices[i]);\n        \tb1 = b0; s2 = s1; s1 = s0;\n        }\n        return s0;\n    }\n\n}\n"
  },
  {
    "path": "src/BestTimeToBuyAndSellStockWithTransactionFee714.java",
    "content": "/**\n * Your are given an array of integers prices, for which the i-th element is\n * the price of a given stock on day i; and a non-negative integer fee\n * representing a transaction fee.\n * \n * You may complete as many transactions as you like, but you need to pay the\n * transaction fee for each transaction. You may not buy more than 1 share of\n * a stock at a time (ie. you must sell the stock share before you buy again.)\n * \n * Return the maximum profit you can make.\n * \n * Example 1:\n * Input: prices = [1, 3, 2, 8, 4, 9], fee = 2\n * Output: 8\n * Explanation: The maximum profit can be achieved by:\n *      Buying at prices[0] = 1\n *      Selling at prices[3] = 8\n *      Buying at prices[4] = 4\n *      Selling at prices[5] = 9\n * The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.\n * \n * Note:\n * 0 < prices.length <= 50000.\n * 0 < prices[i] < 50000.\n * 0 <= fee < 50000.\n * \n */\n\n\npublic class BestTimeToBuyAndSellStockWithTransactionFee714 {\n    public int maxProfit(int[] prices, int fee) {\n        if (prices == null || prices.length < 2) return 0;\n\n        int[] buy = new int[prices.length];\n        int sell = 0;\n\n        buy[0] = -prices[0] - fee;\n        for (int i=1; i<prices.length; i++) {\n            buy[i] = Math.max(buy[i-1], sell - prices[i] - fee);\n            sell = Math.max(sell, buy[i-1] + prices[i]);\n        }\n\n        return sell;\n    }\n\n\n    public int maxProfit2(int[] prices, int fee) {\n        if (prices == null || prices.length <= 1) return 0;\n        \n        int buy = Integer.MIN_VALUE;\n        int sell = 0;\n        for (int p: prices) {\n            buy = Math.max(buy, sell - p);\n            sell = Math.max(sell, buy + p - fee);\n        }\n        return sell;\n    }\n\n}\n"
  },
  {
    "path": "src/BinarySearchTreeIterator173.java",
    "content": "/**\n * Implement an iterator over a binary search tree (BST). Your iterator will be\n * initialized with the root node of a BST.\n *\n * Calling next() will return the next smallest number in the BST.\n *\n * Note: next() and hasNext() should run in average O(1) time and uses O(h)\n * memory, where h is the height of the tree.\n *\n */\n\n\n/**\n * Definition for binary tree\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class BinarySearchTreeIterator173 {\n    class BSTIterator {\n        private Stack<TreeNode> stack = new Stack();\n\n        public BSTIterator(TreeNode root) {\n            if (root != null) {\n                addAllLeft(root);\n            }\n        }\n\n        private void addAllLeft(TreeNode node) {\n            while (true) {\n                this.stack.push(node);\n                node = node.left;\n                if (node == null) return;\n            }\n        }\n\n        /** @return whether we have a next smallest number */\n        public boolean hasNext() {\n            return !this.stack.isEmpty();\n        }\n\n        /** @return the next smallest number */\n        public int next() {\n            TreeNode tmp = this.stack.pop();\n            int returned = tmp.val;\n            if (tmp.right != null) {\n                addAllLeft(tmp.right);\n            }\n            return returned;\n        }\n    }\n\n/**\n * Your BSTIterator will be called like this:\n * BSTIterator i = new BSTIterator(root);\n * while (i.hasNext()) v[f()] = i.next();\n */\n\n}\n\n\n"
  },
  {
    "path": "src/BinaryTreeInorderTraversal94.java",
    "content": "/**\n * Given a binary tree, return the inorder traversal of its nodes' values.\n *\n * For example:\n * Given binary tree [1,null,2,3],\n *    1\n *     \\\n *      2\n *     /\n *    3\n * return [1,3,2].\n *\n * Note: Recursive solution is trivial, could you do it iteratively?\n */\n\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Stack;\n\n\npublic class BinaryTreeInorderTraversal94 {\n    public List<Integer> inorderTraversal(TreeNode root) {\n        if (node == null) {\n            return new ArrayList<Integer>();\n        }\n\n        List<Integer> result =  new ArrayList<>();\n\n        if (root.left == null && root.right == null) {\n            result.add(root.val);\n            return result;\n        }\n\n        result.addAll(inorderTraversal(root.left));\n        result.add(root.val);\n        result.addAll(inorderTraversal(root.right));\n\n        return result;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/6478/iterative-solution-in-java-simple-and-readable\n     */\n    public List<Integer> inorderTraversal2(TreeNode root) {\n        List<Integer> list = new ArrayList<Integer>();\n\n        Stack<TreeNode> stack = new Stack<TreeNode>();\n        TreeNode cur = root;\n\n        while (cur != null || !stack.empty()){\n            while (cur != null){\n                stack.add(cur);\n                cur = cur.left;\n            }\n            cur = stack.pop();\n            list.add(cur.val);\n            cur = cur.right;\n        }\n\n        return list;\n    }\n\n\n    public List<Integer> inorderTraversal3(TreeNode root) {\n        List<Integer> res = new ArrayList<>();\n        inorderTraversal(root, res);\n        return res;\n    }\n\n    private void inorderTraversal(TreeNode root, List<Integer> res) {\n        if (root == null) return;\n        inorderTraversal(root.left, res);\n        res.add(root.val);\n        inorderTraversal(root.right, res);\n    }\n\n}\n"
  },
  {
    "path": "src/BinaryTreeLevelOrderTraversal102.java",
    "content": "/**\n * Given a binary tree, return the level order traversal of its nodes' values.\n * (ie, from left to right, level by level).\n *\n * For example:\n * Given binary tree [3,9,20,null,null,15,7],\n *     3\n *    / \\\n *   9  20\n *     /  \\\n *    15   7\n * return its level order traversal as:\n * [\n *   [3],\n *   [9,20],\n *   [15,7]\n * ]\n */\n\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\n\nimport java.util.LinkedList;\nimport java.util.Queue;\nimport java.util.ArrayList;\nimport java.util.List;\n\n\npublic class BinaryTreeLevelOrderTraversal102 {\n    public List<List<Integer>> levelOrder(TreeNode root) {\n\n        Queue<TreeNode> q = new LinkedList<>();\n        List<List<Integer>> result = new ArrayList<>();\n        int level = 0;\n\n        if (root == null) {\n            return result;\n        } else {\n            q.add(root);\n        }\n\n        helper(q, result, 0);\n\n        return result;\n    }\n\n\n    private void helper(Queue<TreeNode> q, List<List<Integer>> result, int level) {\n        int s = q.size();\n        if (s == 0) {\n            return;\n        }\n\n        addLevel(result, level);\n\n        int i = 0;\n        while (i < s) {\n            TreeNode now = q.poll();\n            result.get(level).add(now.val);\n            if (now.left != null) {\n                q.add(now.left);\n            }\n            if (now.right != null) {\n                q.add(now.right);\n            }\n            i++;\n        }\n\n        helper(q, result, level + 1);\n    }\n\n\n    private void addLevel(List<List<Integer>> result, int level) {\n        while (result.size() <= level) {\n            result.add(new ArrayList<Integer>());\n        }\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/7647/java-solution-with-a-queue-used\n     */\n    public List<List<Integer>> levelOrder2(TreeNode root) {\n        Queue<TreeNode> queue = new LinkedList<TreeNode>();\n        List<List<Integer>> wrapList = new LinkedList<List<Integer>>();\n\n        if(root == null) return wrapList;\n\n        queue.offer(root);\n        while(!queue.isEmpty()){\n            int levelNum = queue.size();\n            List<Integer> subList = new LinkedList<Integer>();\n            for(int i=0; i<levelNum; i++) {\n                if(queue.peek().left != null) queue.offer(queue.peek().left);\n                if(queue.peek().right != null) queue.offer(queue.peek().right);\n                subList.add(queue.poll().val);\n            }\n            wrapList.add(subList);\n        }\n        return wrapList;\n    }\n\n\n    public List<List<Integer>> levelOrder3(TreeNode root) {\n        List<List<Integer>> res = new ArrayList<>();\n        if (root == null) return res;\n        Queue<TreeNode> queue = new LinkedList<>();\n        queue.add(root);\n        while (!queue.isEmpty()) {\n            List<Integer> level = new ArrayList<>();\n            int cnt = queue.size();\n            for (int i = 0; i < cnt; i++) {\n                TreeNode node = queue.poll();\n                level.add(node.val);\n                if (node.left != null) {\n                    queue.add(node.left);\n                }\n                if (node.right != null) {\n                    queue.add(node.right);\n                }\n            }\n            res.add(level);\n        }\n        return res;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/7332/java-solution-using-dfs\n     */\n\n    public List<List<Integer>> levelOrder(TreeNode root) {\n        List<List<Integer>> res = new ArrayList<List<Integer>>();\n        levelHelper(res, root, 0);\n        return res;\n    }\n\n    public void levelHelper(List<List<Integer>> res, TreeNode root, int height) {\n        if (root == null) return;\n        if (height >= res.size()) {\n            res.add(new LinkedList<Integer>());\n        }\n        res.get(height).add(root.val);\n        levelHelper(res, root.left, height+1);\n        levelHelper(res, root.right, height+1);\n    }\n\n}\n"
  },
  {
    "path": "src/BinaryTreeLevelOrderTraversalII107.java",
    "content": "/**\n * Given a binary tree, return the bottom-up level order traversal of its\n * nodes' values. (ie, from left to right, level by level from leaf to root).\n *\n * For example:\n * Given binary tree [3,9,20,null,null,15,7],\n *     3\n *    / \\\n *   9  20\n *     /  \\\n *    15   7\n * return its bottom-up level order traversal as:\n * [\n *   [15,7],\n *   [9,20],\n *   [3]\n * ]\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class BinaryTreeLevelOrderTraversalII107 {\n    public List<List<Integer>> levelOrderBottom(TreeNode root) {\n        LinkedList<List<Integer>> res = new LinkedList<>();\n        if (root == null) return res;\n        Queue<TreeNode> q = new LinkedList<>();\n        q.add(root);\n        while (!q.isEmpty()) {\n            int size = q.size();\n            List<Integer> level = new ArrayList<>();\n            for (int i=0; i<size; i++) {\n                TreeNode node = q.remove();\n                level.add(node.val);\n                if (node.left != null) q.add(node.left);\n                if (node.right != null) q.add(node.right);\n            }\n            res.addFirst(level);\n        }\n        return res;\n    }\n\n\n    public List<List<Integer>> levelOrderBottom2(TreeNode root) {\n        LinkedList<List<Integer>> res = new LinkedList<>();\n        if (root == null) return res;\n        levelOrder(root, 0, res);\n        return res;\n    }\n\n    private void levelOrder(TreeNode root, int level, LinkedList<List<Integer>> res) {\n        if (root == null) return;\n        if (res.size() <= level) res.addFirst(new ArrayList<>());\n        levelOrder(root.left, level+1, res);\n        levelOrder(root.right, level+1, res);\n        res.get(res.size()-level-1).add(root.val);\n    }\n\n}\n"
  },
  {
    "path": "src/BinaryTreeLongestConsecutiveSequence298.java",
    "content": "/**\n * Given a binary tree, find the length of the longest consecutive sequence path.\n * \n * The path refers to any sequence of nodes from some starting node to any node\n * in the tree along the parent-child connections. The longest consecutive path\n * need to be from parent to child (cannot be the reverse).\n * \n * Example 1:\n * \n * Input:\n * \n *   1\n *     \\\n *      3\n *     / \\\n *    2   4\n *         \\\n *          5\n * \n * Output: 3\n * Explanation: Longest consecutive sequence path is 3-4-5, so return 3.\n * \n * Example 2:\n * \n * Input:\n * \n *    2\n *     \\\n *      3\n *     / \n *    2    \n *   / \n *  1\n * \n * Output: 2 \n * Explanation: Longest consecutive sequence path is 2-3, not 3-2-1, so return 2.\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class BinaryTreeLongestConsecutiveSequence298 {\n    public int longestConsecutive(TreeNode root) {\n        if (root == null) return 0;\n        return helper(root, 0);\n    }\n\n    public int helper(TreeNode root, int i) {\n        if (root == null) return i;\n        \n        int l = i + 1;\n        if (root.left != null) {\n            if (root.val + 1 == root.left.val) {\n                l = helper(root.left, i+1);\n            } else {\n                l = helper(root.left, 0);\n            }\n        }\n\n        int r = i + 1;\n        if (root.right != null) {\n            if (root.val + 1 == root.right.val) {\n                r = helper(root.right, i+1);\n            } else {\n                r = helper(root.right, 0);\n            }\n        }\n\n        return Math.max(Math.max(l, r), i+1);\n    }\n\n\n    /**\n     * Bottom-up\n     * https://leetcode.com/problems/binary-tree-longest-consecutive-sequence/solution/\n     */\n    private int maxLength = 0;\n    public int longestConsecutive2(TreeNode root) {\n        dfs(root);\n        return maxLength;\n    }\n    \n    private int dfs(TreeNode p) {\n        if (p == null) return 0;\n        int L = dfs(p.left) + 1;\n        int R = dfs(p.right) + 1;\n        if (p.left != null && p.val + 1 != p.left.val) {\n            L = 1;\n        }\n        if (p.right != null && p.val + 1 != p.right.val) {\n            R = 1;\n        }\n        int length = Math.max(L, R);\n        maxLength = Math.max(maxLength, length);\n        return length;\n    }\n\n}\n"
  },
  {
    "path": "src/BinaryTreeMaximumPathSum124.java",
    "content": "/**\n * Given a binary tree, find the maximum path sum.\n *\n * For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections.\n * The path must contain at least one node and does not need to go through the root.\n *\n * For example:\n * Given the below binary tree,\n *\n *     1\n *    / \\\n *   2   3\n *\n * Return 6.\n */\n\n\npublic class BinaryTreeMaximumPathSum124 {\n\n    private int maxSum;\n\n    public int maxPathSum(TreeNode root) {\n        maxSum = Integer.MIN_VALUE;\n        maxBranch(root);\n        return maxSum;\n    }\n\n    private int maxBranch(TreeNode root) {\n        if (root == null) return 0;\n\n        int valueLeft = Math.max(0, maxBranch(root.left));\n        int valueRight = Math.max(0, maxBranch(root.right));\n        maxSum = Math.max(maxSum, root.val + valueLeft + valueRight);\n\n        return Math.max(valueLeft, valueRight) + root.val;\n    }\n\n\n    public static void main(String[] args) {\n        BinaryTreeMaximumPathSum124 btmps = new BinaryTreeMaximumPathSum124();\n\n        TreeNode root1 = new TreeNode(2);\n        root1.left = new TreeNode(1);\n        root1.right = new TreeNode(3);\n\n        TreeNode root2 = new TreeNode(-3);\n\n        System.out.println(btmps.maxPathSum(root1));\n        System.out.println(btmps.maxPathSum(root2));\n\n    }\n\n}\n"
  },
  {
    "path": "src/BinaryTreePaths257.java",
    "content": "/**\n * Given a binary tree, return all root-to-leaf paths.\n *\n * For example, given the following binary tree:\n *\n *    1\n *  /   \\\n * 2     3\n *  \\\n *   5\n * All root-to-leaf paths are:\n *\n * [\"1->2->5\", \"1->3\"]\n *\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class BinaryTreePaths257 {\n    public List<String> binaryTreePaths(TreeNode root) {\n        List<String> res = new ArrayList<>();\n        binaryTreePaths(root, new StringBuilder(), res);\n        return res;\n    }\n\n    public void binaryTreePaths(TreeNode root, StringBuilder path, List<String> res) {\n        if (root == null) return;\n        path.append(root.val);\n        if (root.left == null && root.right == null) {\n            res.add(path.toString());\n            return;\n        }\n\n        path.append(\"->\");\n        int l = path.length();\n        binaryTreePaths(root.left, path, res);\n        path.delete(l, path.length());\n        binaryTreePaths(root.right, path, res);\n        path.delete(l, path.length());\n    }\n\n\n    /**\n     * https://leetcode.com/problems/binary-tree-paths/discuss/68278/My-Java-solution-in-DFS-BFS-recursion\n     */\n    public List<String> binaryTreePaths2(TreeNode root) {\n        List<String> sList=new LinkedList<String>();\n        if (root==null) return sList;\n        if (root.left==null && root.right==null) {\n            sList.add(Integer.toString(root.val));\n            return sList;\n        }\n\n        for (String s: binaryTreePaths(root.left)) {\n            sList.add(Integer.toString(root.val)+\"->\"+s);\n        }\n        for (String s: binaryTreePaths(root.right)) {\n            sList.add(Integer.toString(root.val)+\"->\"+s);\n        }\n        return sList;\n    }\n\n}\n"
  },
  {
    "path": "src/BinaryTreePreorderTraversal144.java",
    "content": "/**\n * Given a binary tree, return the preorder traversal of its nodes' values.\n * \n * Example:\n * \n * Input: [1,null,2,3]\n *    1\n *     \\\n *      2\n *     /\n *    3\n * Output: [1,2,3]\n * \n * Follow up: Recursive solution is trivial, could you do it iteratively?\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class BinaryTreePreorderTraversal144 {\n    public List<Integer> preorderTraversal(TreeNode root) {\n        List<Integer> res = new ArrayList<>();\n        helper(root, res);\n        return res;\n    }\n\n    private void helper(TreeNode root, List<Integer> res) {\n        if (root == null) return;\n        res.add(root.val);\n        helper(root.left, res);\n        helper(root.right, res);\n    }\n\n\n    public List<Integer> preorderTraversal2(TreeNode root) {\n        List<Integer> res = new ArrayList<>();\n        if (root == null) return res;\n        Stack<TreeNode> stack = new Stack<>();\n        stack.add(root);\n        while (!stack.isEmpty()) {\n            TreeNode curr = stack.pop();\n            res.add(curr.val);\n            if (curr.right != null) stack.add(curr.right);\n            if (curr.left != null) stack.add(curr.left);\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/BinaryTreeRightSideView199.java",
    "content": "/**\n * Given a binary tree, imagine yourself standing on the right side of it,\n * return the values of the nodes you can see ordered from top to bottom.\n * \n * Example:\n * \n * Input: [1,2,3,null,5,null,4]\n * Output: [1, 3, 4]\n * \n * Explanation:\n * \n *    1            <---\n *  /   \\\n * 2     3         <---\n *  \\     \\\n *   5     4       <---\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class BinaryTreeRightSideView199 {\n    public List<Integer> rightSideView(TreeNode root) {\n        List<Integer> res = new ArrayList<>();\n        rightSideView(root, res, 0);\n        return res;\n    }\n\n    public void rightSideView(TreeNode root, List<Integer> res, int level) {\n        if (root == null) return;\n        if (level >= res.size()) res.add(root.val);\n        \n        if (root.right != null) rightSideView(root.right, res, level+1);\n        if (root.left != null) rightSideView(root.left, res, level+1);\n    }\n\n}\n"
  },
  {
    "path": "src/BinaryTreeVerticalOrderTraversal314.java",
    "content": "/**\n * Given a binary tree, return the vertical order traversal of its nodes' values.\n * (ie, from top to bottom, column by column).\n *\n * If two nodes are in the same row and column, the order should be from left to right.\n *\n * Examples:\n *\n * 1. Given binary tree [3,9,20,null,null,15,7],\n *    3\n *   /\\\n *  /  \\\n *  9  20\n *     /\\\n *    /  \\\n *   15   7\n * return its vertical order traversal as:\n * [\n *   [9],\n *   [3,15],\n *   [20],\n *   [7]\n * ]\n *\n *\n * 2. Given binary tree [3,9,8,4,0,1,7],\n *      3\n *     /\\\n *    /  \\\n *    9   8\n *   /\\  /\\\n *  /  \\/  \\\n *  4  01   7\n * return its vertical order traversal as:\n * [\n *   [4],\n *   [9],\n *   [3,0,1],\n *   [8],\n *   [7]\n * ]\n *\n *\n * 3. Given binary tree [3,9,8,4,0,1,7,null,null,null,2,5] (0's right child is 2 and 1's left child is 5),\n *      3\n *     /\\\n *    /  \\\n *    9   8\n *   /\\  /\\\n *  /  \\/  \\\n *  4  01   7\n *     /\\\n *    /  \\\n *    5   2\n * return its vertical order traversal as:\n * [\n *   [4],\n *   [9,5],\n *   [3,0,1],\n *   [8,2],\n *   [7]\n * ]\n *\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class BinaryTreeVerticalOrderTraversal314 {\n    public List<List<Integer>> verticalOrder(TreeNode root) {\n        if (root == null) return new ArrayList<List<Integer>>();\n        Map<Integer, List<Integer>> map = new HashMap<>();\n        Queue<TreeNode> q = new LinkedList<>();\n        Map<TreeNode, Integer> vs = new HashMap<>();\n        q.offer(root);\n        vs.put(root, 0);\n        int min = 0;\n        while (!q.isEmpty()) {\n            TreeNode curr = q.poll();\n            int i = vs.get(curr);\n            if (curr.left != null) {\n                vs.put(curr.left, i-1);\n                q.offer(curr.left);\n            }\n            if (curr.right != null) {\n                vs.put(curr.right, i+1);\n                q.offer(curr.right);\n            }\n            map.computeIfAbsent(i, p -> new ArrayList<Integer>()).add(curr.val);\n            min = Math.min(min, i);\n        }\n\n        List<List<Integer>> res = new ArrayList<>();\n\n        while (map.containsKey(min)) {\n            res.add(map.get(min++));\n        }\n\n        return res;\n    }\n\n\n\n    public List<List<Integer>> verticalOrder2(TreeNode root) {\n        if (root == null) return new ArrayList<List<Integer>>();\n        Map<Integer, List<Integer>> map = new HashMap<>();\n        Queue<TreeNode> q = new LinkedList<>();\n        Queue<Integer> qi = new LinkedList<>();\n        q.add(root);\n        qi.add(0);\n        int min = 0;\n        while (!q.isEmpty()) {\n            TreeNode curr = q.remove();\n            Integer i = qi.remove();\n            if (curr.left != null) {\n                qi.add(i-1);\n                q.add(curr.left);\n            }\n            if (curr.right != null) {\n                qi.add(i+1);\n                q.add(curr.right);\n            }\n            if (!map.containsKey(i)) {\n                map.put(i, new ArrayList<Integer>());\n            }\n            map.get(i).add(curr.val);\n            // map.computeIfAbsent(i, p -> new ArrayList<Integer>()).add(curr.val);\n            min = Math.min(min, i);\n        }\n\n        List<List<Integer>> res = new ArrayList<>();\n\n        while (map.containsKey(min)) {\n            res.add(map.get(min++));\n        }\n\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/binary-tree-vertical-order-traversal/discuss/76401/5ms-Java-Clean-Solution\n     */\n    public List<List<Integer>> verticalOrder3(TreeNode root) {\n        List<List<Integer>> cols = new ArrayList<>();\n        if (root == null) {\n            return cols;\n        }\n\n        int[] range = new int[] {0, 0};\n        getRange(root, range, 0);\n\n        for (int i = range[0]; i <= range[1]; i++) {\n            cols.add(new ArrayList<Integer>());\n        }\n\n        Queue<TreeNode> queue = new LinkedList<>();\n        Queue<Integer> colQueue = new LinkedList<>();\n\n        queue.add(root);\n        colQueue.add(-range[0]);\n\n        while (!queue.isEmpty()) {\n            TreeNode node = queue.poll();\n            int col = colQueue.poll();\n\n            cols.get(col).add(node.val);\n\n            if (node.left != null) {\n                queue.add(node.left);\n                colQueue.add(col - 1);\n            }\n            if (node.right != null) {\n                queue.add(node.right);\n                colQueue.add(col + 1);\n            }\n        }\n\n        return cols;\n    }\n\n    public void getRange(TreeNode root, int[] range, int col) {\n        if (root == null) {\n            return;\n        }\n        range[0] = Math.min(range[0], col);\n        range[1] = Math.max(range[1], col);\n\n        getRange(root.left, range, col - 1);\n        getRange(root.right, range, col + 1);\n    }\n\n}\n"
  },
  {
    "path": "src/BinaryTreeZigzagLevelOrderTraversal103.java",
    "content": "/**\n * Given a binary tree, return the zigzag level order traversal of its nodes'\n * values. (ie, from left to right, then right to left for the next level and\n * alternate between).\n *\n * For example:\n * Given binary tree [3,9,20,null,null,15,7],\n *     3\n *    / \\\n *   9  20\n *     /  \\\n *    15   7\n * return its zigzag level order traversal as:\n * [\n *   [3],\n *   [20,9],\n *   [15,7]\n * ]\n */\n\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\n\npublic class BinaryTreeZigzagLevelOrderTraversal103 {\n    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {\n        List<List<Integer>> res = new ArrayList<>();\n        if (root == null) return res;\n        LinkedList<TreeNode> level = new LinkedList<>();\n        level.add(root);\n        zigzagLevelOrder(level, true, res);\n        return res;\n    }\n\n    private void zigzagLevelOrder(LinkedList<TreeNode> level, boolean left, List<List<Integer>> res) {\n        if (level.isEmpty()) return;\n        LinkedList<Integer> one = new LinkedList<>();\n        LinkedList<TreeNode> newLevel = new LinkedList<>();\n        while (!level.isEmpty()) {\n            TreeNode t = level.removeFirst();\n            if (t == null) continue;\n            if (left) one.add(t.val);\n            else one.addFirst(t.val);\n            newLevel.add(t.left);\n            newLevel.add(t.right);\n        }\n        if (!one.isEmpty()) res.add(one);\n        zigzagLevelOrder(newLevel, !left, res);\n    }\n\n}\n"
  },
  {
    "path": "src/BinaryTreesWithFactors823.java",
    "content": "/**\n * Given an array of unique integers, each integer is strictly greater than 1.\n * \n * We make a binary tree using these integers and each number may be used for\n * any number of times.\n * \n * Each non-leaf node's value should be equal to the product of the values of\n * it's children.\n * \n * How many binary trees can we make?  Return the answer modulo 10 ** 9 + 7.\n * \n * Example 1:\n * Input: A = [2, 4]\n * Output: 3\n * Explanation: We can make these trees: [2], [4], [4, 2, 2]\n * \n * Example 2:\n * Input: A = [2, 4, 5, 10]\n * Output: 7\n * Explanation: We can make these trees:\n * [2], [4], [5], [10], [4, 2, 2], [10, 2, 5], [10, 5, 2].\n * \n * Note:\n * 1 <= A.length <= 1000.\n * 2 <= A[i] <= 10 ^ 9.\n */\n\npublic class BinaryTreesWithFactors823 {\n    private static long MOD = (long) Math.pow(10, 9) + 7;\n    public int numFactoredBinaryTrees(int[] A) {\n        Arrays.sort(A);\n        int N = A.length;\n        int max = A[N-1];\n        Map<Integer, Long> map = new HashMap<>();\n        long res = 0;\n        for (int i=0; i<N; i++) {\n            int curr = A[i];\n            long local = 1;\n            for (int j=0; j<i; j++) {\n                int left = A[j];\n                if (curr % left != 0) continue;\n                int right = curr / left;\n                if (left == right) {\n                    local += map.get(left) * map.get(left);\n                    continue;\n                }\n                int idx = Arrays.binarySearch(A, j, i, right);\n                if (idx < 0) continue;\n                local += map.get(left) * map.get(right) * 2;\n            }\n            res += local;\n            map.put(curr, local);\n        }\n        return (int) (res % MOD);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/binary-trees-with-factors/solution/\n     */\n    public int numFactoredBinaryTrees2(int[] A) {\n        int MOD = 1_000_000_007;\n        int N = A.length;\n        Arrays.sort(A);\n        long[] dp = new long[N];\n        Arrays.fill(dp, 1);\n\n        Map<Integer, Integer> index = new HashMap();\n        for (int i = 0; i < N; ++i)\n            index.put(A[i], i);\n\n        for (int i = 0; i < N; ++i)\n            for (int j = 0; j < i; ++j) {\n                if (A[i] % A[j] == 0) { // A[j] is left child\n                    int right = A[i] / A[j];\n                    if (index.containsKey(right)) {\n                        dp[i] = (dp[i] + dp[j] * dp[index.get(right)]) % MOD;\n                    }\n                }\n            }\n\n        long ans = 0;\n        for (long x: dp) ans += x;\n        return (int) (ans % MOD);\n    }\n\n}\n"
  },
  {
    "path": "src/BitwiseANDOfNumbersRange201.java",
    "content": "/**\n * Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND\n * of all numbers in this range, inclusive.\n * \n * Example 1:\n * Input: [5,7]\n * Output: 4\n * \n * Example 2:\n * Input: [0,1]\n * Output: 0\n */\n\npublic class BitwiseANDOfNumbersRange201 {\n    public int rangeBitwiseAnd(int m, int n) {\n        if (m == 0) return 0;\n        int res = 0;\n        int range = n - m + 1;\n        int b = 1;\n        for (int i=0; i<=31; i++) {\n            if (range <= b && (getBit(m, i) == 1 && getBit(n, i) == 1)) {\n                res = setBit(res, i);\n            }\n            b <<= 1;\n        }\n        return res;\n    }\n\n    private int setBit(int num, int pos) {\n        return num | (1 << pos);\n    }\n\n    private int getBit(int num, int pos) {\n        return (num & (1 << pos)) >> pos;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/bitwise-and-of-numbers-range/discuss/56729/Bit-operation-solution(JAVA)\n     */\n    public int rangeBitwiseAnd2(int m, int n) {\n        if(m == 0){\n            return 0;\n        }\n        int moveFactor = 1;\n        while(m != n){\n            m >>= 1;\n            n >>= 1;\n            moveFactor <<= 1;\n        }\n        return m * moveFactor;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/bitwise-and-of-numbers-range/discuss/56721/2-line-Solution-with-detailed-explanation\n     */\n    public int rangeBitwiseAnd3(int m, int n) {\n        while(m<n) n = n & (n-1);\n        return n;\n    }\n\n}\n"
  },
  {
    "path": "src/BoatsToSavePeople885.java",
    "content": "/**\n * The i-th person has weight people[i], and each boat can carry a maximum\n * weight of limit.\n * \n * Each boat carries at most 2 people at the same time, provided the sum of the\n * weight of those people is at most limit.\n * \n * Return the minimum number of boats to carry every given person.\n * (It is guaranteed each person can be carried by a boat.)\n * \n * Example 1:\n * Input: people = [1,2], limit = 3\n * Output: 1\n * Explanation: 1 boat (1, 2)\n * \n * Example 2:\n * Input: people = [3,2,2,1], limit = 3\n * Output: 3\n * Explanation: 3 boats (1, 2), (2) and (3)\n * \n * Example 3:\n * Input: people = [3,5,3,4], limit = 5\n * Output: 4\n * Explanation: 4 boats (3), (3), (4), (5)\n * \n * Note:\n * 1 <= people.length <= 50000\n * 1 <= people[i] <= limit <= 30000\n */\n\npublic class BoatsToSavePeople885 {\n    public int numRescueBoats(int[] people, int limit) {\n        Arrays.sort(people);\n        int res = 0;\n        int N = people.length;\n        int i = 0;\n        int j = N-1;\n        while (i < j) {\n            if (people[i] + people[j] > limit) {\n                j--;\n            } else {\n                i++;\n                j--;\n            }\n            res++;\n        }\n        if (i == j) res++;\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/BombEnemy361.java",
    "content": "/**\n * Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0'\n * (the number zero), return the maximum enemies you can kill using one bomb.\n * The bomb kills all the enemies in the same row and column from the planted\n * point until it hits the wall since the wall is too strong to be destroyed.\n * Note that you can only put the bomb at an empty cell.\n * \n * Example:\n * For the given grid\n * \n * 0 E 0 0\n * E 0 W E\n * 0 E 0 0\n * \n * return 3. (Placing a bomb at (1,1) kills 3 enemies)\n */\n\npublic class BombEnemy361 {\n    public int maxKilledEnemies(char[][] grid) {\n        if (grid == null || grid.length <= 0 || grid[0].length <= 0) return 0;\n        int n = grid.length;\n        int m = grid[0].length;\n        int res = 0;\n        for (int i=0; i<n; i++) {\n            for (int j=0; j<m; j++) {\n                if (grid[i][j] == '0') {\n                    res = Math.max(killedByBomb(grid, i, j, n, m), res);\n                }\n            }\n        }\n        return res;\n    }\n    \n    private int killedByBomb(char[][] grid, int i, int j, int n, int m) {\n        int res = 0;\n        // right\n        for (int k=j+1; k<m && grid[i][k] != 'W'; k++) {\n            if (grid[i][k] == 'E') res++;\n        }\n        \n        // left\n        for (int k=j-1; k>=0 && grid[i][k] != 'W'; k--) {\n            if (grid[i][k] == 'E') res++;\n        }\n        \n        // top\n        for (int k=i-1; k>=0 && grid[k][j] != 'W'; k--) {\n            if (grid[k][j] == 'E') res++;\n        }\n        \n        // bottom\n        for (int k=i+1; k<n && grid[k][j] != 'W'; k++) {\n            if (grid[k][j] == 'E') res++;\n        }\n        \n        return res;\n    }\n  \n\n\n    private int[][] hori;\n    private int[][] vert;\n    public int maxKilledEnemies2(char[][] grid) {\n        if (grid == null || grid.length <= 0 || grid[0].length <= 0) return 0;\n        int n = grid.length;\n        int m = grid[0].length;\n        hori = new int[n][m];\n        vert = new int[n][m];\n        \n        int res = 0;\n        for (int i=0; i<n; i++) {\n            for (int j=0; j<m; j++) {\n                if (grid[i][j] == '0') {\n                    res = Math.max(killedByBomb2(grid, i, j, n, m), res);\n                }\n            }\n        }\n        return res;\n    }\n    \n    private int killedByBomb2(char[][] grid, int i, int j, int n, int m) {\n        int h = 0;\n        boolean hf = false;\n        // left\n        for (int k=j-1; k>=0 && grid[i][k] != 'W'; k--) {\n            if (grid[i][k] == 'E') h++;\n            else if (grid[i][k] == '0') {\n                h = hori[i][k];\n                hf = true;\n                break;\n            } else {\n                break;\n            }\n        }\n        \n        if (!hf) {\n            // right\n            for (int k=j+1; k<m && grid[i][k] != 'W'; k++) {\n                if (grid[i][k] == 'E') h++;\n            }\n        }\n        hori[i][j] = h;\n\n        int v = 0;\n        boolean vf = false;\n        // top\n        for (int k=i-1; k>=0 && grid[k][j] != 'W'; k--) {\n            if (grid[k][j] == 'E') v++;\n            else if (grid[k][j] == '0') {\n                v = vert[k][j];\n                vf = true;\n                break;\n            } else {\n                break;\n            }\n        }\n\n        if (!vf) {\n            // bottom\n            for (int k=i+1; k<n && grid[k][j] != 'W'; k++) {\n                if (grid[k][j] == 'E') v++;\n            }\n        }\n        \n        vert[i][j] = v;\n\n        return h + v;\n    }\n\n\n    public int maxKilledEnemies3(char[][] grid) {\n        if (grid == null || grid.length == 0 || grid[0].length == 0) return 0;\n        int m = grid.length;\n        int n = grid[0].length;\n        int[][] left = new int[m][n];\n        int[][] right = new int[m][n];\n        int[][] top = new int[m][n];\n        int[][] bottom = new int[m][n];\n        \n        for (int i=0; i<m; i++) {\n            for (int j=0; j<n; j++) {\n                if (grid[i][j] != 'W') {\n                    int add = grid[i][j] == 'E' ? 1 : 0;\n                    left[i][j] = (j > 0 ? left[i][j-1] : 0) + add;\n                    top[i][j] = (i > 0 ? top[i-1][j] : 0) + add;\n                }\n                if (grid[i][n-j-1] != 'W') {\n                    right[i][n-j-1] = (j > 0 ? right[i][n-j] : 0) + (grid[i][n-j-1] == 'E' ? 1 : 0);\n                }\n                if (grid[m-i-1][j] != 'W') {\n                    bottom[m-i-1][j] = (i > 0 ? bottom[m-i][j] : 0) + (grid[m-i-1][j] == 'E' ? 1 : 0);\n                }\n            }\n        }\n\n        int res = 0;\n        for (int i=0; i<m; i++) {\n            for (int j=0; j<n; j++) {\n                if (grid[i][j] == '0') {\n                    int local = left[i][j] + right[i][j] + top[i][j] + bottom[i][j];\n                    if (local > res) {\n                        res = local;\n                    }\n                }\n            }\n        }\n        return res;\n    }\n\n\n    public int maxKilledEnemies4(char[][] grid) {\n        if (grid == null || grid.length == 0 || grid[0].length == 0) return 0;\n        int m = grid.length;\n        int n = grid[0].length;\n        int rowKills = 0;\n        int[] colKills = new int[n];\n        \n        int res = 0;\n        for (int i=0; i<m; i++) {\n            for (int j=0; j<n; j++) {\n                if (j == 0 || grid[i][j-1] == 'W') {\n                    int tempRow = 0;\n                    for (int k=j; k<n && grid[i][k] != 'W'; k++) {\n                        if (grid[i][k] == 'E') {\n                            tempRow++;\n                        }\n                    }\n                    rowKills = tempRow;\n                }\n                \n                if (i == 0 || grid[i-1][j] == 'W') {\n                    int tempCol = 0;\n                    for (int k=i; k<m && grid[k][j] != 'W'; k++) {\n                        if (grid[k][j] == 'E') {\n                            tempCol++;\n                        }\n                    }\n                    colKills[j] = tempCol;\n                }\n                \n                if (grid[i][j] == '0' && rowKills + colKills[j] > res) {\n                    res = rowKills + colKills[j];\n                }\n            }\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/BoundaryOfBinaryTree545.java",
    "content": "/**\n * Given a binary tree, return the values of its boundary in anti-clockwise\n * direction starting from root. Boundary includes left boundary, leaves, and\n * right boundary in order without duplicate nodes.\n * \n * Left boundary is defined as the path from root to the left-most node. Right\n * boundary is defined as the path from root to the right-most node. If the\n * root doesn't have left subtree or right subtree, then the root itself is\n * left boundary or right boundary. Note this definition only applies to the\n * input binary tree, and not applies to any subtrees.\n * \n * The left-most node is defined as a leaf node you could reach when you always\n * firstly travel to the left subtree if exists. If not, travel to the right\n * subtree. Repeat until you reach a leaf node.\n * \n * The right-most node is also defined by the same way with left and right exchanged.\n * \n * Example 1\n * Input:\n *   1\n *    \\\n *     2\n *    / \\\n *   3   4\n * \n * Ouput:\n * [1, 3, 4, 2]\n * \n * Explanation:\n * The root doesn't have left subtree, so the root itself is left boundary.\n * The leaves are node 3 and 4.\n * The right boundary are node 1,2,4. Note the anti-clockwise direction means\n * you should output reversed right boundary.\n * So order them in anti-clockwise without duplicates and we have [1,3,4,2].\n * \n * Example 2\n * Input:\n *     ____1_____\n *    /          \\\n *   2            3\n *  / \\          / \n * 4   5        6   \n *    / \\      / \\\n *   7   8    9  10  \n *        \n * Ouput:\n * [1,2,4,7,8,9,10,6,3]\n * \n * Explanation:\n * The left boundary are node 1,2,4. (4 is the left-most node according to definition)\n * The leaves are node 4,7,8,9,10.\n * The right boundary are node 1,3,6,10. (10 is the right-most node).\n * So order them in anti-clockwise without duplicate nodes we have [1,2,4,7,8,9,10,6,3].\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class BoundaryOfBinaryTree545 {\n    public List<Integer> boundaryOfBinaryTree(TreeNode root) {\n        List<Integer> res = new ArrayList<>();\n        if (root == null) return res;\n        res.add(root.val);\n        if (root.left != null) dfsLeft(root.left, new boolean[1], res);\n        List<Integer> rightRes = new ArrayList<>();\n        if (root.right != null) dfsRight(root.right, new boolean[1], rightRes);\n        for (int i=rightRes.size()-1; i>=0; i--) {\n            res.add(rightRes.get(i));\n        }\n        return res;\n    }\n    \n    private void dfsLeft(TreeNode root, boolean[] flag, List<Integer> res) {\n        if (root.left == null && root.right == null) {\n            res.add(root.val);\n            flag[0] = true;\n            return;\n        }\n        \n        if (!flag[0]) res.add(root.val);\n        if (root.left != null) dfsLeft(root.left, flag, res);\n        if (root.right != null) dfsLeft(root.right, flag, res);\n    }\n\n    private void dfsRight(TreeNode root, boolean[] flag, List<Integer> res) {\n        if (root.left == null && root.right == null) {\n            res.add(root.val);\n            flag[0] = true;\n            return;\n        }\n\n        if (!flag[0]) res.add(root.val);\n        if (root.right != null) dfsRight(root.right, flag, res);\n        if (root.left != null) dfsRight(root.left, flag, res);\n    }\n  \n}\n"
  },
  {
    "path": "src/BrickWall554.java",
    "content": "/**\n * There is a brick wall in front of you. The wall is rectangular and has\n * several rows of bricks. The bricks have the same height but different width.\n * You want to draw a vertical line from the top to the bottom and cross the\n * least bricks.\n *\n * The brick wall is represented by a list of rows. Each row is a list of\n * integers representing the width of each brick in this row from left to right.\n *\n * If your line go through the edge of a brick, then the brick is not considered\n * as crossed. You need to find out how to draw the line to cross the least\n * bricks and return the number of crossed bricks.\n *\n * You cannot draw a line just along one of the two vertical edges of the wall,\n * in which case the line will obviously cross no bricks.\n *\n * Example:\n *    Input:\n *      [[1,2,2,1],\n *      [3,1,2],\n *      [1,3,2],\n *      [2,4],\n *      [3,1,2],\n *      [1,3,1,1]]\n *    Output: 2\n *\n * Explanation:\n *    https://leetcode.com/static/images/problemset/brick_wall.png\n *\n * Note:\n *      The width sum of bricks in different rows are the same and won't exceed INT_MAX.\n *      The number of bricks in each row is in range [1,10,000]. The height of\n *      wall is in range [1,10,000]. Total number of bricks of the wall won't\n *      exceed 20,000.\n *\n */\n\n\npublic class BrickWall554 {\n    public int leastBricks(List<List<Integer>> wall) {\n        Map<Integer, Integer> map = new HashMap<>();\n\n        for (int i = 0; i<wall.size(); i++) {\n            List<Integer> row = wall.get(i);\n            int sum = 0;\n            for (int j = 0; j<row.size()-1; j++) {\n                sum += row.get(j);\n                map.put(sum, map.getOrDefault(sum, 0) + 1);\n            }\n        }\n\n        int res = 0;\n        for (Integer v: map.values()) {\n            res = Math.max(res, v);\n        }\n        return wall.size()-res;\n    }\n\n}\n"
  },
  {
    "path": "src/BricksFallingWhenHit803.java",
    "content": "/**\n * We have a grid of 1s and 0s; the 1s in a cell represent bricks. A brick\n * will not drop if and only if it is directly connected to the top of the\n * grid, or at least one of its (4-way) adjacent bricks will not drop.\n * \n * We will do some erasures sequentially. Each time we want to do the erasure\n * at the location (i, j), the brick (if it exists) on that location will\n * disappear, and then some other bricks may drop because of that erasure.\n * \n * Return an array representing the number of bricks that will drop after\n * each erasure in sequence.\n * \n * Example 1:\n * Input: \n * grid = [[1,0,0,0],[1,1,1,0]]\n * hits = [[1,0]]\n * Output: [2]\n * Explanation: \n * If we erase the brick at (1, 0), the brick at (1, 1) and (1, 2) will drop.\n * So we should return 2.\n * \n * Example 2:\n * Input: \n * grid = [[1,0,0,0],[1,1,0,0]]\n * hits = [[1,1],[1,0]]\n * Output: [0,0]\n * Explanation: \n * When we erase the brick at (1, 0), the brick at (1, 1) has already\n * disappeared due to the last move. So each erasure will cause no bricks\n * dropping.  Note that the erased brick (1, 0) will not be counted as a\n * dropped brick.\n * \n * Note:\n * The number of rows and columns in the grid will be in the range [1, 200].\n * The number of erasures will not exceed the area of the grid.\n * It is guaranteed that each erasure will be different from any other erasure,\n * and located inside the grid.\n * An erasure may refer to a location with no brick - if it does, no bricks\n * drop.\n */\n\npublic class BricksFallingWhenHit803 {\n    /**\n     * https://leetcode.com/problems/bricks-falling-when-hit/solution/\n     */\n    public int[] hitBricks(int[][] grid, int[][] hits) {\n        int R = grid.length, C = grid[0].length;\n        int[] dr = {1, 0, -1, 0};\n        int[] dc = {0, 1, 0, -1};\n\n        int[][] A = new int[R][C];\n        for (int r = 0; r < R; ++r)\n            A[r] = grid[r].clone();\n        for (int[] hit: hits)\n            A[hit[0]][hit[1]] = 0;\n\n        DSU dsu = new DSU(R*C + 1);\n        for (int r = 0; r < R; ++r) {\n            for (int c = 0; c < C; ++c) {\n                if (A[r][c] == 1) {\n                    int i = r * C + c;\n                    if (r == 0)\n                        dsu.union(i, R*C);\n                    if (r > 0 && A[r-1][c] == 1)\n                        dsu.union(i, (r-1) *C + c);\n                    if (c > 0 && A[r][c-1] == 1)\n                        dsu.union(i, r * C + c-1);\n                }\n            }\n        }\n        int t = hits.length;\n        int[] ans = new int[t--];\n\n        while (t >= 0) {\n            int r = hits[t][0];\n            int c = hits[t][1];\n            int preRoof = dsu.top();\n            if (grid[r][c] == 0) {\n                t--;\n            } else {\n                int i = r * C + c;\n                for (int k = 0; k < 4; ++k) {\n                    int nr = r + dr[k];\n                    int nc = c + dc[k];\n                    if (0 <= nr && nr < R && 0 <= nc && nc < C && A[nr][nc] == 1)\n                        dsu.union(i, nr * C + nc);\n                }\n                if (r == 0)\n                    dsu.union(i, R*C);\n                A[r][c] = 1;\n                ans[t--] = Math.max(0, dsu.top() - preRoof - 1);\n            }\n        }\n        return ans;\n    }\n\n    class DSU {\n        int[] parent;\n        int[] rank;\n        int[] sz;\n\n        public DSU(int N) {\n            parent = new int[N];\n            for (int i = 0; i < N; ++i)\n                parent[i] = i;\n            rank = new int[N];\n            sz = new int[N];\n            Arrays.fill(sz, 1);\n        }\n\n        public int find(int x) {\n            if (parent[x] != x) parent[x] = find(parent[x]);\n            return parent[x];\n        }\n\n        public void union(int x, int y) {\n            int xr = find(x), yr = find(y);\n            if (xr == yr) return;\n\n            if (rank[xr] < rank[yr]) {\n                parent[xr] = yr;\n                sz[yr] += sz[xr];\n            } else if (rank[xr] > rank[yr]) {\n                parent[yr] = xr;\n                sz[xr] += sz[yr];\n            } else {\n                rank[xr]++;\n                parent[yr] = xr;\n                sz[xr] += sz[yr];\n            }\n        }\n\n        public int size(int x) {\n            return sz[find(x)];\n        }\n\n        public int top() {\n            return sz[find(sz.length - 1)] - 1;\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/bricks-falling-when-hit/discuss/121072/Java-Solution\n     */\n    public int[] hitBricks2(int[][] grid, int[][] hits) {\n        if (hits.length == 0 || hits[0].length == 0) return null;\n        removeHitBrick(grid, hits);\n        markRemainBricks(grid);\n        return searchFallingBrick(grid, hits);\n    }\n\n    private void markRemainBricks(int[][] grid) {\n        for (int i = 0; i < grid[0].length; i++) {\n            deepSearch(grid, 0, i);\n        }\n    }\n\n    private void removeHitBrick(int[][] grid, int[][] hits) {\n        for (int i = 0; i < hits.length; i++) {\n            grid[hits[i][0]][hits[i][1]] = grid[hits[i][0]][hits[i][1]] - 1;\n        }\n    }\n\n    private int[] searchFallingBrick(int[][] grid, int[][] hits) {\n        int[] result = new int[hits.length];\n        for (int i = hits.length - 1; i >= 0; i--) {\n            if (grid[hits[i][0]][hits[i][1]] == 0) {\n                grid[hits[i][0]][hits[i][1]] = 1;\n                if (isConnectToTop(grid, hits[i][0], hits[i][1])) {\n                    result[i] = deepSearch(grid, hits[i][0], hits[i][1]) - 1;\n                } else {\n                    result[i] = 0;\n                }\n            }\n        }\n        return result;\n    }\n\n    private boolean isConnectToTop(int[][] grid, int i, int j) {\n        if(i == 0) return true;\n\n        if (i - 1 >= 0 && grid[i - 1][j] == 2) {\n            return true;\n        }\n        if (i + 1 < grid.length && grid[i + 1][j] == 2) {\n            return true;\n        }\n        if (j - 1 >= 0 && grid[i][j - 1] == 2) {\n            return true;\n        }\n        if (j + 1 < grid[0].length && grid[i][j + 1] == 2) {\n            return true;\n        }\n        return false;\n    }\n\n    private int deepSearch(int[][] data, int row, int column) {\n        int arrayRow = data.length;\n        int arrayLine = data[0].length;\n        int effectBricks = 0;\n        if (row < 0 || row >= arrayRow) return effectBricks;\n        if (column < 0 || column >= arrayLine) return effectBricks;\n        if (data[row][column] == 1) {\n            data[row][column] = 2;\n            effectBricks = 1;\n            effectBricks += deepSearch(data, row + 1, column);\n            effectBricks += deepSearch(data, row - 1, column);\n            effectBricks += deepSearch(data, row, column + 1);\n            effectBricks += deepSearch(data, row, column - 1);\n        }\n        return effectBricks;\n    }\n\n\n\n\n\n\n\n}\n\n"
  },
  {
    "path": "src/BuddyStrings859.java",
    "content": "/**\n * Given two strings A and B of lowercase letters, return true if and only if\n * we can swap two letters in A so that the result equals B.\n * \n * Example 1:\n * Input: A = \"ab\", B = \"ba\"\n * Output: true\n * \n * Example 2:\n * Input: A = \"ab\", B = \"ab\"\n * Output: false\n * \n * Example 3:\n * Input: A = \"aa\", B = \"aa\"\n * Output: true\n * \n * Example 4:\n * Input: A = \"aaaaaaabc\", B = \"aaaaaaacb\"\n * Output: true\n * \n * Example 5:\n * Input: A = \"\", B = \"aa\"\n * Output: false\n * \n * Note:\n * 0 <= A.length <= 20000\n * 0 <= B.length <= 20000\n * A and B consist only of lowercase letters.\n */\n\npublic class BuddyStrings859 {\n    public boolean buddyStrings(String A, String B) {\n        if (A == null || B == null || A.length() < 2 || B.length() < 2 || A.length() != B.length()) return false;\n        char[] aa = A.toCharArray();\n        char[] bb = B.toCharArray();\n        int len = A.length();\n        int first = -1;\n        int second = -1;\n        int[] map = new int[26];\n        boolean same = false;\n        for (int i=0; i<len; i++) {\n            if (aa[i] == bb[i]) {\n                map[aa[i]-'a']++;\n                if (map[aa[i]-'a'] >= 2) same = true;\n                continue;\n            }\n            if (first == -1) {\n                first = i;\n            } else {\n                if (second != -1 || (aa[first] != bb[i] || aa[i] != bb[first])) return false;\n                second = i;\n            }\n        }\n        return first != -1 || same;\n    }\n}\n\n"
  },
  {
    "path": "src/BullsAndCows299.java",
    "content": "/**\n * You are playing the following Bulls and Cows game with your friend:\n * You write down a number and ask your friend to guess what the number is.\n * Each time your friend makes a guess, you provide a hint that indicates\n * how many digits in said guess match your secret number exactly in both digit\n * and position (called \"bulls\") and how many digits match the secret number\n * but locate in the wrong position (called \"cows\"). Your friend will use\n * successive guesses and hints to eventually derive the secret number.\n *\n * Bulls and Cows https://en.wikipedia.org/wiki/Bulls_and_Cows\n *\n * For example:\n *\n * Secret number:  \"1807\"\n * Friend's guess: \"7810\"\n *\n * Hint: 1 bull and 3 cows. (The bull is 8, the cows are 0, 1 and 7.)\n * Write a function to return a hint according to the secret number and\n * friend's guess, use A to indicate the bulls and B to indicate the cows.\n * In the above example, your function should return \"1A3B\".\n *\n * Please note that both secret number and friend's guess may contain duplicate digits, for example:\n *\n * Secret number:  \"1123\"\n * Friend's guess: \"0111\"\n *\n * In this case, the 1st 1 in friend's guess is a bull, the 2nd or 3rd 1 is a\n * cow, and your function should return \"1A1B\".\n *\n * You may assume that the secret number and your friend's guess only contain\n * digits, and their lengths are always equal.\n */\n\n\npublic class BullsAndCows299 {\n    public String getHint(String secret, String guess) {\n\n        Map<Character, Integer> secrets = new HashMap<>();\n        Map<Character, Integer> guesses = new HashMap<>();\n\n        Map<String, Integer> counts = new HashMap<>();\n        counts.put(\"bull\", 0);\n        counts.put(\"cows\", 0);\n\n        List<Integer> left = new ArrayList<>();\n\n        for (int i=0; i<guess.length(); i++) {\n            Character c1 = secret.charAt(i);\n            Character c2 = guess.charAt(i);\n\n            if (c1.equals(c2)) {\n                counts.put(\"bull\", counts.get(\"bull\")+1);\n            } else {\n                secrets.put(c1, secrets.getOrDefault(c1, 0)+1);\n                guesses.put(c2, guesses.getOrDefault(c2, 0)+1);\n            }\n        }\n\n        for (Map.Entry<Character, Integer> e: guesses.entrySet()) {\n            if (secrets.containsKey(e.getKey())) {\n                counts.put(\"cows\", counts.get(\"cows\") + Math.min(secrets.get(e.getKey()), e.getValue()));\n            }\n        }\n\n        return String.format(\"%dA%dB\", counts.get(\"bull\"), counts.get(\"cows\"));\n    }\n\n\n    public String getHint2(String secret, String guess) {\n\n        Map<Character, Integer> secrets = new HashMap<>();\n        Map<Character, Integer> guesses = new HashMap<>();\n\n        Map<String, Integer> counts = new HashMap<>();\n        counts.put(\"bull\", 0);\n        counts.put(\"cows\", 0);\n\n        for (int i=0; i<guess.length(); i++) {\n            Character c1 = secret.charAt(i);\n            Character c2 = guess.charAt(i);\n\n            if (c1.equals(c2)) {\n                counts.put(\"bull\", counts.get(\"bull\")+1);\n            } else {\n                if (secrets.containsKey(c2) && secrets.get(c2) > 0) {\n                    secrets.put(c2, secrets.get(c2)-1);\n                    counts.put(\"cows\", counts.get(\"cows\")+1);\n                } else {\n                    guesses.put(c2, guesses.getOrDefault(c2, 0)+1);\n                }\n                if (guesses.containsKey(c1) && guesses.get(c1) > 0) {\n                    guesses.put(c1, guesses.get(c1)-1);\n                    counts.put(\"cows\", counts.get(\"cows\")+1);\n                } else {\n                    secrets.put(c1, secrets.getOrDefault(c1, 0)+1);\n                }\n            }\n        }\n\n        return String.format(\"%dA%dB\", counts.get(\"bull\"), counts.get(\"cows\"));\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/28463/one-pass-java-solution\n     */\n    public String getHint3(String secret, String guess) {\n        int bulls = 0;\n        int cows = 0;\n        int[] numbers = new int[10];\n        for (int i = 0; i<secret.length(); i++) {\n            if (secret.charAt(i) == guess.charAt(i)) bulls++;\n            else {\n                if (numbers[secret.charAt(i)-'0']++ < 0) cows++;\n                if (numbers[guess.charAt(i)-'0']-- > 0) cows++;\n            }\n        }\n        return bulls + \"A\" + cows + \"B\";\n    }\n\n}\n"
  },
  {
    "path": "src/BurstBalloons312.java",
    "content": "/**\n * Given n balloons, indexed from 0 to n-1. Each balloon is painted with a\n * number on it represented by array nums. You are asked to burst all the\n * balloons. If the you burst balloon i you will get\n *\n * nums[left] * nums[i] * nums[right]\n *\n * coins. Here left and right are adjacent indices of i. After the burst,\n * the left and right then becomes adjacent.\n *\n * Find the maximum coins you can collect by bursting the balloons wisely.\n *\n * Note:\n * (1) You may imagine nums[-1] = nums[n] = 1. They are not real therefore you can not burst them.\n * (2) 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100\n *\n * Example:\n *\n * Given [3, 1, 5, 8]\n *\n * Return 167\n *\n * nums = [3,1,5,8] --> [3,5,8] -->   [3,8]   -->  [8]  --> []\n * coins =  3*1*5      +  3*5*8    +  1*3*8      + 1*8*1   = 167\n *\n */\n\n\npublic class BurstBalloons312 {\n    public int maxCoins(int[] nums) {\n        if (nums.length == 0) return 0;\n        if (nums.length == 1) return nums[0];\n\n        int res = Integer.MIN_VALUE;\n        for (int i=0; i<nums.length; i++) {\n            int l = (i == 0) ? 1 : nums[i-1];\n            int r = (i == nums.length-1) ? 1 : nums[i+1];\n            int curr = l*nums[i]*r;\n            int[] left = Arrays.copyOfRange(nums, 0, i);\n            int[] right = Arrays.copyOfRange(nums, i+1, nums.length);\n            res = Math.max(res, curr + maxCoins(\n                IntStream.concat(Arrays.stream(left), Arrays.stream(right)).toArray()\n            ));\n        }\n        return res;\n    }\n\n\n    public int maxCoins1(int[] nums) {\n        if (nums.length == 0) return 0;\n        if (nums.length == 1) return nums[0];\n        Set<Integer> key = new HashSet<>();\n        for (int i=0; i<nums.length; i++) key.add(i);\n        return dp(nums, key, new HashMap<Set<Integer>, Integer>());\n    }\n\n    private int dp(int[] nums, Set<Integer> key, Map<Set<Integer>, Integer> caches) {\n        if (key.size() == 0) return 0;\n        if (key.size() == 1) return nums[key.iterator().next()];\n        if (caches.containsKey(key)) return caches.get(key);\n\n        int res = Integer.MIN_VALUE;\n        for (Integer pos: key) {\n            int posL = pos-1;\n            int posR = pos+1;\n            while(posL >= 0 && !key.contains(posL)) posL--;\n            while(posR < nums.length && !key.contains(posR)) posR++;\n            int l = (posL < 0) ? 1 : nums[posL];\n            int r = (posR >= nums.length) ? 1 : nums[posR];\n            int curr = l * nums[pos] * r;\n            Set<Integer> newKey = new HashSet<>(key);\n            newKey.remove(pos);\n\n            if (caches.containsKey(newKey)) {\n                res = Math.max(res, curr + caches.get(newKey));\n            } else {\n                Integer rem = dp(nums, newKey, caches);\n                caches.put(newKey, rem);\n                res = Math.max(res, curr + rem);\n            }\n        }\n        return res;\n    }\n\n\n    public int maxCoins2(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        if (nums.length == 1) return nums[0];\n        int[][] dp = new int[nums.length][nums.length];\n        for (int len=0; len<=nums.length; len++) {\n            for (int s=0; s<=nums.length-len; s++) {\n                int e = s + len - 1;\n                for (int i=s; i<=e; i++) {\n                    int l = (s <= 0) ? 1 : nums[s-1];\n                    int r = (e >= nums.length-1) ? 1 : nums[e+1];\n                    int curr = l * nums[i] * r;\n                    curr += i != s ? dp[s][i - 1] : 0;\n                    curr += i != e ? dp[i + 1][e] : 0;\n                    dp[s][e] = Math.max(dp[s][e], curr);\n                }\n\n            }\n        }\n\n        return dp[0][nums.length-1];\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/30746/share-some-analysis-and-explanations\n     */\n    public int maxCoins3(int[] iNums) {\n        int[] nums = new int[iNums.length + 2];\n        int n = 1;\n        for (int x : iNums) if (x > 0) nums[n++] = x;\n        nums[0] = nums[n++] = 1;\n\n        int[][] dp = new int[n][n];\n        for (int k = 2; k < n; ++k)\n            for (int left = 0; left < n - k; ++left) {\n                int right = left + k;\n                for (int i = left + 1; i < right; ++i)\n                    dp[left][right] = Math.max(dp[left][right], nums[left] * nums[i] * nums[right] + dp[left][i] + dp[i][right]);\n            }\n\n        return dp[0][n - 1];\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/30746/share-some-analysis-and-explanations\n     */\n    public int maxCoins4(int[] iNums) {\n        int[] nums = new int[iNums.length + 2];\n        int n = 1;\n        for (int x : iNums) if (x > 0) nums[n++] = x;\n        nums[0] = nums[n++] = 1;\n\n        int[][] memo = new int[n][n];\n        return burst(memo, nums, 0, n - 1);\n    }\n\n    public int burst(int[][] memo, int[] nums, int left, int right) {\n        if (left + 1 == right) return 0;\n        if (memo[left][right] > 0) return memo[left][right];\n        int ans = 0;\n        for (int i = left + 1; i < right; ++i)\n            ans = Math.max(ans, nums[left] * nums[i] * nums[right] + burst(memo, nums, left, i) + burst(memo, nums, i, right));\n        memo[left][right] = ans;\n        return ans;\n    }\n\n}\n"
  },
  {
    "path": "src/CanIWin464.java",
    "content": "/**\n * In the \"100 game,\" two players take turns adding, to a running total, any\n * integer from 1..10. The player who first causes the running total to reach\n * or exceed 100 wins.\n * \n * What if we change the game so that players cannot re-use integers?\n * \n * For example, two players might take turns drawing from a common pool of\n * numbers of 1..15 without replacement until they reach a total >= 100.\n * \n * Given an integer maxChoosableInteger and another integer desiredTotal,\n * determine if the first player to move can force a win, assuming both players\n * play optimally.\n * \n * You can always assume that maxChoosableInteger will not be larger than 20\n * and desiredTotal will not be larger than 300.\n * \n * Example\n * Input:\n * maxChoosableInteger = 10\n * desiredTotal = 11\n * Output:\n * false\n * \n * Explanation:\n * No matter which integer the first player choose, the first player will lose.\n * The first player can choose an integer from 1 up to 10.\n * If the first player choose 1, the second player can only choose integers from 2 up to 10.\n * The second player will win by choosing 10 and get a total = 11, which is >= desiredTotal.\n * Same with other integers chosen by the first player, the second player will always win.\n */\n\npublic class CanIWin464 {\n    public boolean canIWin(int maxChoosableInteger, int desiredTotal) {\n        if (desiredTotal == 0) return true;\n        if (((1 + maxChoosableInteger) / 2 * maxChoosableInteger) < desiredTotal) {\n            return false;\n        }\n        return helper(new boolean[maxChoosableInteger], desiredTotal, new HashMap<>());\n    }\n\n    private boolean helper(boolean[] set, int desiredTotal, Map<String, Boolean> memo) {\n        if (desiredTotal <= 0) return false;\n        String k = setKey(set);\n        if (memo.containsKey(k)) return memo.get(k);\n\n        for (int i=set.length-1; i>=0; i--) {\n            if (!set[i]) {\n                set[i] = true;\n                if (!helper(set, desiredTotal-i-1, memo)) {\n                    set[i] = false;\n                    memo.put(k, true);\n                    return true;\n                }\n                set[i] = false;\n            }\n        }\n        memo.put(k, false);\n        return false;\n    }\n\n    private String setKey(boolean[] set) {\n        StringBuilder sb = new StringBuilder();\n        for (boolean b: set) {\n            sb.append(b ? 't' : 'f');\n        }\n        return sb.toString();\n    }\n\n\n\n    public boolean canIWin2(int maxChoosableInteger, int desiredTotal) {\n        if (desiredTotal == 0) return true;\n        if (((1 + maxChoosableInteger) / 2 * maxChoosableInteger) < desiredTotal) {\n            return false;\n        }\n        return helper(0, desiredTotal, new Boolean[1 << maxChoosableInteger], maxChoosableInteger);\n    }\n\n    private boolean helper(int state, int desiredTotal, Boolean[] memo, int M) {\n        if (desiredTotal <= 0) return false;\n        if (memo[state] != null) return memo[state];\n        for (int i=M-1; i>=0; i--) {\n            if ((state & (1 << i)) == 0) {\n                state |= 1 << i;\n                if (!helper(state, desiredTotal-i-1, memo, M)) {\n                    state &= ~(1 << i);\n                    memo[state] = true;\n                    return true;\n                }\n                state &= ~(1 << i);\n            }\n        }\n        memo[state] = false;\n        return false;\n    }\n\n\n}\n"
  },
  {
    "path": "src/CheapestFlightsWithinKStops787.java",
    "content": "/**\n * There are n cities connected by m flights. Each fight starts from city u and\n * arrives at v with a price w.\n * \n * Now given all the cities and flights, together with starting city src and\n * the destination dst, your task is to find the cheapest price from src to dst\n * with up to k stops. If there is no such route, output -1.\n * \n * Example 1:\n * Input: \n * n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]]\n * src = 0, dst = 2, k = 1\n * Output: 200\n *\n * Explanation: \n * The graph looks like this:\n * https://s3-lc-upload.s3.amazonaws.com/uploads/2018/02/16/995.png\n * \n * The cheapest price from city 0 to city 2 with at most 1 stop costs 200, as\n * marked red in the picture.\n * \n * Example 2:\n * Input: \n * n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]]\n * src = 0, dst = 2, k = 0\n * Output: 500\n * \n * Explanation: \n * The graph looks like this:\n * https://s3-lc-upload.s3.amazonaws.com/uploads/2018/02/16/995.png\n * \n * The cheapest price from city 0 to city 2 with at most 0 stop costs 500, as\n * marked blue in the picture.\n * \n * Note:\n * The number of nodes n will be in range [1, 100], with nodes labeled from 0\n * to n - 1.\n * The size of flights will be in range [0, n * (n - 1) / 2].\n * The format of each flight will be (src, dst, price).\n * The price of each flight will be in the range [1, 10000].\n * k is in the range of [0, n - 1].\n * There will not be any duplicated flights or self cycles.\n */\n\npublic class CheapestFlightsWithinKStops787 {\n    public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) {\n        int[][] graph = constructGraph(n, flights);\n        Queue<int[]> q = new LinkedList<>();\n        q.add(new int[]{src, 0});\n        int[][] dist = new int[n][K+2];\n        for (int[] row: dist) Arrays.fill(row, Integer.MAX_VALUE);\n        dist[src][0] = 0;\n        while (!q.isEmpty()) {\n            int[] cur = q.poll();\n            int[] nei = graph[cur[0]];\n            for (int next=0; next<n; next++) {\n                int weight = nei[next];\n                if (weight == 0) continue;\n                int newDis = dist[cur[0]][cur[1]] + weight;\n                if (cur[1] + 1 <= K+1 && newDis < dist[next][cur[1]+1]) {\n                    dist[next][cur[1]+1] = newDis;\n                    q.add(new int[]{next, cur[1]+1});\n                }\n            }\n        }\n        int res = Integer.MAX_VALUE;\n        for (int r: dist[dst]) {\n            res = Math.min(res, r);\n        }\n        return res == Integer.MAX_VALUE ? -1 : res;\n    }\n\n    private int[][] constructGraph(int n, int[][] flights) {\n        int[][] res = new int[n][n];\n        for (int[] f: flights) {\n            res[f[0]][f[1]] = f[2];\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/cheapest-flights-within-k-stops/solution/\n     */\n    public int findCheapestPrice2(int n, int[][] flights, int src, int dst, int K) {\n        int[][] dist = new int[2][n];\n        int INF = Integer.MAX_VALUE / 2;\n        Arrays.fill(dist[0], INF);\n        Arrays.fill(dist[1], INF);\n        dist[0][src] = dist[1][src] = 0;\n\n        for (int i = 0; i <= K; ++i)\n            for (int[] edge: flights)\n                dist[i&1][edge[1]] = Math.min(dist[i&1][edge[1]], dist[~i&1][edge[0]] + edge[2]);\n\n        return dist[K&1][dst] < INF ? dist[K&1][dst] : -1;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/cheapest-flights-within-k-stops/solution/\n     */\n    public int findCheapestPrice3(int n, int[][] flights, int src, int dst, int K) {\n        int[][] graph = new int[n][n];\n        for (int[] flight: flights)\n            graph[flight[0]][flight[1]] = flight[2];\n\n        Map<Integer, Integer> best = new HashMap();\n\n        Comparator<int[]> comp = (a, b) -> a[0] - b[0];\n        PriorityQueue<int[]> pq = new PriorityQueue<int[]>(comp);\n        pq.offer(new int[]{0, 0, src});\n\n        while (!pq.isEmpty()) {\n            int[] info = pq.poll();\n            int cost = info[0], k = info[1], place = info[2];\n            if (k > K+1 || cost > best.getOrDefault(k * 1000 + place, Integer.MAX_VALUE))\n                continue;\n            if (place == dst)\n                return cost;\n\n            for (int nei = 0; nei < n; ++nei) if (graph[place][nei] > 0) {\n                int newcost = cost + graph[place][nei];\n                if (newcost < best.getOrDefault((k+1) * 1000 + nei, Integer.MAX_VALUE)) {\n                    pq.offer(new int[]{newcost, k+1, nei});\n                    best.put((k+1) * 1000 + nei, newcost);\n                }\n            }\n        }\n\n        return -1;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/128776/5-ms-AC-Java-Solution-based-on-Dijkstra's-Algorithm\n     */\n    private class City implements Comparable<City>{\n        int id;\n        int costFromSrc;\n        int stopFromSrc;\n        public City(int id, int costFromSrc, int stopFromSrc){\n            this.id = id;\n            this.costFromSrc = costFromSrc;\n            this.stopFromSrc = stopFromSrc;\n        }\n        public boolean equals(City c){\n            if(c instanceof City)\n                return this.id == c.id;\n            return false;\n        }\n        public int compareTo(City c){\n            return this.costFromSrc - c.costFromSrc;\n        }\n    }\n\n    public int findCheapestPrice4(int n, int[][] flights, int src, int dst, int K) {\n        int[][] srcToDst = new int[n][n];\n        for(int i = 0; i < flights.length; i++)\n            srcToDst[flights[i][0]][flights[i][1]] = flights[i][2]; \n\n        PriorityQueue<City> minHeap = new PriorityQueue();\n        minHeap.offer(new City(src,0,0));\n\n        int[] cost = new int[n];\n        Arrays.fill(cost, Integer.MAX_VALUE);\n        cost[src] = 0;\n        int[] stop = new int[n];\n        Arrays.fill(stop, Integer.MAX_VALUE);\n        stop[src] = 0;\n\n        while(!minHeap.isEmpty()){\n            City curCity = minHeap.poll();\n            if(curCity.id == dst) return curCity.costFromSrc;\n            if(curCity.stopFromSrc == K + 1) continue;\n            int[] nexts = srcToDst[curCity.id];\n            for(int i = 0; i < n; i++){\n                if(nexts[i] != 0){\n                    int newCost = curCity.costFromSrc + nexts[i];\n                    int newStop = curCity.stopFromSrc + 1;\n                    if(newCost < cost[i]){\n                        minHeap.offer(new City(i, newCost, newStop));\n                        cost[i] = newCost;\n                    }\n                    else if(newStop < stop[i]){\n                        minHeap.offer(new City(i, newCost, newStop));\n                        stop[i] = newStop;\n                    }\n                }\n            }\n        }\n\n        return cost[dst] == Integer.MAX_VALUE? -1:cost[dst];\n    }\n\n\n    /**\n     * https://leetcode.com/problems/cheapest-flights-within-k-stops/discuss/163698/easy-java-Bellman-Ford\n     */\n    public int findCheapestPrice5(int n, int[][] flights, int src, int dst, int k) {\n        int INF = 0x3F3F3F3F;\n        int[] cost = new int[n];\n        Arrays.fill(cost, INF);\n        cost[src] = 0;\n        int ans = cost[dst];\n        for(int i = k; i >= 0; i--){\n            int[] cur = new int[n];\n            Arrays.fill(cur, INF);\n            for(int[] flight : flights){\n                cur[flight[1]] = Math.min(cur[flight[1]], cost[flight[0]] + flight[2]);\n            }\n            cost = cur;\n            ans = Math.min(ans, cost[dst]);\n        }\n        return ans == INF ? -1 : ans;\n    }\n\n\n    private static int MAX = Integer.MAX_VALUE / 2;\n    public int findCheapestPrice6(int n, int[][] flights, int src, int dst, int K) {\n        int[][] dp = new int[K+2][n];\n        for (int[] row: dp) Arrays.fill(row, MAX);\n        dp[0][src] = 0;\n        for (int i=1; i<=K+1; i++) {\n            for (int[] f: flights) {\n                dp[i][f[1]] = Math.min(dp[i][f[1]], Math.min(dp[i-1][f[1]],\n                                       dp[i-1][f[0]] + f[2]));\n            }\n        }\n        return dp[K+1][dst] >= MAX ? -1 : dp[K+1][dst];\n    }\n\n\n    public int findCheapestPrice7(int n, int[][] flights, int src, int dst, int K) {\n        int[][] dp = new int[2][n];\n        Arrays.fill(dp[0], MAX);\n        Arrays.fill(dp[1], MAX);\n        dp[0][src] = 0;\n        int k = 1;\n        while (k <= K+1) {\n            for (int[] f: flights) {\n                dp[k%2][f[1]] = Math.min(dp[k%2][f[1]], Math.min(dp[(k-1)%2][f[1]],\n                                       dp[(k-1)%2][f[0]] + f[2]));\n            }\n            k++;\n        }\n        k--;\n        return dp[k%2][dst] >= MAX ? -1 : dp[k%2][dst];\n    }\n\n}\n\n"
  },
  {
    "path": "src/ClimbingStairs70.java",
    "content": "/**\n * You are climbing a stair case. It takes n steps to reach to the top.\n *\n * Each time you can either climb 1 or 2 steps. In how many distinct ways can\n * you climb to the top?\n *\n * Note: Given n will be a positive integer.\n *\n * Example 1:\n *\n * Input: 2\n * Output:  2\n * Explanation:  There are two ways to climb to the top.\n *\n * 1. 1 step + 1 step\n * 2. 2 steps\n *\n *\n * Example 2:\n *\n * Input: 3\n * Output:  3\n * Explanation:  There are three ways to climb to the top.\n *\n * 1. 1 step + 1 step + 1 step\n * 2. 1 step + 2 steps\n * 3. 2 steps + 1 step\n *\n */\n\n\npublic class ClimbingStairs70 {\n    public int climbStairs(int n) {\n        if (n == 1) return 1;\n        int[] dp = new int[n+1];\n        dp[0] = 1;\n        dp[1] = 1;\n        for (int i=2; i<=n; i++) {\n            dp[i] = dp[i-1] + dp[i-2];\n        }\n        return dp[n];\n    }\n\n\n    public int climbStairs2(int n) {\n        if (n == 1) return 1;\n        int pre = 1;\n        int now = 1;\n\n        for (int i=2; i<=n; i++) {\n            int newVal = pre + now;\n            pre = now;\n            now = newVal;\n        }\n\n        return now;\n    }\n\n}\n"
  },
  {
    "path": "src/CloneGraph133.java",
    "content": "/**\n * Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.\n *\n *\n * OJ's undirected graph serialization:\n * Nodes are labeled uniquely.\n *\n * We use # as a separator for each node, and , as a separator for node label and each neighbor of the node.\n * As an example, consider the serialized graph {0,1,2#1,2#2,2}.\n *\n * The graph has a total of three nodes, and therefore contains three parts as separated by #.\n *\n * First node is labeled as 0. Connect node 0 to both nodes 1 and 2.\n * Second node is labeled as 1. Connect node 1 to node 2.\n * Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle.\n * Visually, the graph looks like the following:\n *\n *        1\n *       / \\\n *      /   \\\n *     0 --- 2\n *          / \\\n *          \\_/\n *\n */\n\n/**\n * Definition for undirected graph.\n * class UndirectedGraphNode {\n *     int label;\n *     List<UndirectedGraphNode> neighbors;\n *     UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }\n * };\n */\n\npublic class CloneGraph133 {\n    public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {\n        HashMap<Integer, UndirectedGraphNode> map = new HashMap<>();\n        return clone(node, map);\n    }\n\n    private UndirectedGraphNode clone(UndirectedGraphNode node, HashMap<Integer, UndirectedGraphNode> map) {\n        if (node == null) return null;\n\n        if (map.containsKey(node.label)) {\n            return map.get(node.label);\n        }\n        UndirectedGraphNode clone = new UndirectedGraphNode(node.label);\n        map.put(clone.label, clone);\n        for (UndirectedGraphNode neighbor : node.neighbors) {\n            clone.neighbors.add(clone(neighbor, map));\n        }\n        return clone;\n    }\n}\n"
  },
  {
    "path": "src/ClosestBinarySearchTreeValue270.java",
    "content": "/**\n * Given a non-empty binary search tree and a target value, find the value in\n * the BST that is closest to the target.\n * \n * Note:\n * \n * Given target value is a floating point.\n * You are guaranteed to have only one unique value in the BST that is closest\n * to the target.\n * \n * Example:\n * \n * Input: root = [4,2,5,1,3], target = 3.714286\n * \n *     4\n *    / \\\n *   2   5\n *  / \\\n * 1   3\n * \n * Output: 4\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class ClosestBinarySearchTreeValue270 {\n    public int closestValue(TreeNode root, double target) {\n        return closestValue(root, target, null, null);\n    }\n\n    private int closestValue(TreeNode root, double target, Integer mi, Integer ma) {\n        if (root == null) {\n            if (mi == null) return ma;\n            else if (ma == null) return mi;\n            else return (ma - target > target - mi) ? mi : ma;\n        } \n\n        double val = root.val * 1.0;\n        if (val == target) {\n            return root.val;\n        } else if (val > target) {\n            return closestValue(root.left, target, mi, root.val);\n        } else {\n            return closestValue(root.right, target, root.val, ma);\n        }\n    }\n\n\n    public int closestValue2(TreeNode root, double target) {\n        Integer mi = null;\n        Integer ma = null;\n\n        while (root != null) {\n            double val = root.val * 1.0;\n            if (val == target) {\n                return root.val;\n            } else if (val > target) {\n                ma = root.val;\n                root = root.left;\n            } else {\n                mi = root.val;\n                root = root.right;\n            }\n        }\n\n        if (mi == null) return ma;\n        else if (ma == null) return mi;\n        else return (ma - target > target - mi) ? mi : ma;\n    }\n    \n\n    /**\n     * https://leetcode.com/problems/closest-binary-search-tree-value/discuss/70327/4-7-lines-recursiveiterative-RubyC++JavaPython\n     */\n    public int closestValue3(TreeNode root, double target) {\n        int a = root.val;\n        TreeNode kid = target < a ? root.left : root.right;\n        if (kid == null) return a;\n        int b = closestValue(kid, target);\n        return Math.abs(a - target) < Math.abs(b - target) ? a : b;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/closest-binary-search-tree-value/discuss/70331/Clean-and-concise-java-solution\n     */\n    public int closestValue4(TreeNode root, double target) {\n        int ret = root.val;   \n        while(root != null){\n            if(Math.abs(target - root.val) < Math.abs(target - ret)){\n                ret = root.val;\n            }      \n            root = root.val > target? root.left: root.right;\n        }     \n        return ret;\n    }\n\n}\n"
  },
  {
    "path": "src/ClosestBinarySearchTreeValueII272.java",
    "content": "/**\n * Given a non-empty binary search tree and a target value, find k values in\n * the BST that are closest to the target.\n * \n * Note:\n * Given target value is a floating point.\n * You may assume k is always valid, that is: k ≤ total nodes.\n * You are guaranteed to have only one unique set of k values in the BST that\n * are closest to the target.\n * \n * Example:\n * \n * Input: root = [4,2,5,1,3], target = 3.714286, and k = 2\n * \n *     4\n *    / \\\n *   2   5\n *  / \\\n * 1   3\n * \n * Output: [4,3]\n * \n * Follow up:\n * Assume that the BST is balanced, could you solve it in less than O(n)\n * runtime (where n = total nodes)?\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class ClosestBinarySearchTreeValueII272 {\n    public List<Integer> closestKValues(TreeNode root, double target, int k) {\n        LinkedList<Integer> res = new LinkedList<>();\n        helper(root, target, k, res);\n        return res;\n    }\n\n    private void helper(TreeNode root, double target, int k, LinkedList<Integer> res) {\n        if (root == null) return;\n        helper(root.left, target, k, res);\n        res.addLast(root.val);\n        helper(root.right, target, k, res);\n        cut(target, k, res);\n    }\n    \n    private void cut(double target, int k, LinkedList<Integer> res) {\n        if (res.size() > k) {\n            if (Math.abs(res.getFirst() * 1.0 - target) >= Math.abs(res.getLast() * 1.0 - target)) {\n                res.removeFirst();\n            } else {\n                res.removeLast();\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/CoinChange322.java",
    "content": "/**\n * You are given coins of different denominations and a total amount of money\n * amount. Write a function to compute the fewest number of coins that you\n * need to make up that amount. If that amount of money cannot be made up by\n * any combination of the coins, return -1.\n *\n * Example 1:\n * coins = [1, 2, 5], amount = 11\n * return 3 (11 = 5 + 5 + 1)\n *\n * Example 2:\n * coins = [2], amount = 3\n * return -1.\n *\n * Note:\n * You may assume that you have an infinite number of each kind of coin.\n *\n */\n\npublic class CoinChange322 {\n    public int coinChange(int[] coins, int amount) {\n        Arrays.sort(coins);\n        return helper(coins.length-1, coins, amount);\n    }\n\n    private int helper(int idx, int[] coins, int left) {\n        if (idx < 0) return -1;\n\n        int curr = coins[idx];\n        int multi = left / curr;\n        int currLeft = left % curr;\n        if (currLeft == 0) return multi;\n\n        int res = Integer.MAX_VALUE;\n        int reduce = multi;\n        int newLeft = currLeft;\n\n        while(reduce >= 0) {\n            int temp = helper(idx-1, coins, newLeft);\n            if (temp != -1) res = Math.min(res, temp+reduce);\n            reduce--;\n            newLeft = newLeft + curr;\n        }\n\n        return (res == Integer.MAX_VALUE) ? -1 : res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/coin-change/solution/\n     */\n    public int coinChange2(int[] coins, int amount) {\n        if (amount < 1) return 0;\n        return dp(coins, amount, new int[amount]);\n    }\n\n    private int dp(int[] coins, int left, int[] amounts) {\n        if (left < 0) return -1;\n        if (left == 0) return 0;\n        if (amounts[left - 1] != 0) return amounts[left - 1];\n        int res = Integer.MAX_VALUE;\n        for (int i=0; i<coins.length; i++) {\n            int next = dp(coins, left-coins[i], amounts);\n            if (next >= 0 && next < res)\n                res = next +1;\n        }\n        amounts[left - 1] = (res == Integer.MAX_VALUE) ? -1 : res;\n        return amounts[left - 1];\n    }\n\n\n    /**\n     * https://leetcode.com/problems/coin-change/solution/\n     */\n    public int coinChange3(int[] coins, int amount) {\n        int[] dp = new int[amount + 1];\n        Arrays.fill(dp, amount + 1);\n        dp[0] = 0;\n        for (int i=1; i<=amount; i++) {\n            for (int j=0; j<coins.length; j++) {\n                if (coins[j] <= i) {\n                    dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);\n                }\n            }\n        }\n        return dp[amount] > amount ? -1 : dp[amount];\n    }\n\n\n    public int coinChange4(int[] coins, int amount) {\n        int[] dp = new int[amount + 1];\n        for (int i=1; i<=amount; i++) {\n            int t = Integer.MAX_VALUE;\n            for (int c: coins) {\n                if (i >= c && dp[i - c] != -1) {\n                    t = Math.min(t, dp[i - c] + 1);\n                }\n            }\n            dp[i] = t == Integer.MAX_VALUE ? -1 : t;\n        }\n        return dp[amount];\n    }\n\n\n    public int coinChange5(int[] coins, int amount) {\n        int[] dp = new int[amount + 1];\n        Arrays.fill(dp, amount + 1);\n        dp[0] = 0;\n        for (int c: coins) {\n            for (int i=c; i<=amount; i++) {\n                dp[i] = Math.min(dp[i], dp[i - c] + 1);\n            }\n        }\n        return (dp[amount] == amount + 1) ? -1 : dp[amount];\n    }\n\n\n    public int coinChange6(int[] coins, int amount) {\n        Arrays.sort(coins);\n        int[] res = new int[]{amount + 1};\n        coinChange(coins, amount, coins.length - 1, res, 0);\n        return (res[0] == amount + 1) ? -1 : res[0];\n    }\n\n    public void coinChange(int[] coins, int amount, int idx, int[] res, int num) {\n        if (amount == 0) {\n            res[0] = Math.min(res[0], num);\n            return;\n        }\n        if (idx < 0) return;\n        int k = amount / coins[idx];\n        for (int j=k; j>=0 && num + j < res[0]; j--) {\n            coinChange(coins, amount - j * coins[idx], idx-1, res, num + j);\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/CoinChangeII518.java",
    "content": "/**\n * You are given coins of different denominations and a total amount of money.\n * Write a function to compute the number of combinations that make up that\n * amount. You may assume that you have infinite number of each kind of coin.\n *\n * Note: You can assume that\n *\n * 0 <= amount <= 5000\n * 1 <= coin <= 5000\n * the number of coins is less than 500\n * the answer is guaranteed to fit into signed 32-bit integer\n *\n *\n * Example 1:\n *\n * Input: amount = 5, coins = [1, 2, 5]\n * Output: 4\n * Explanation: there are four ways to make up the amount:\n * 5=5\n * 5=2+2+1\n * 5=2+1+1+1\n * 5=1+1+1+1+1\n *\n *\n * Example 2:\n *\n * Input: amount = 3, coins = [2]\n * Output: 0\n * Explanation: the amount of 3 cannot be made up just with coins of 2.\n *\n * \n * Example 3:\n *\n * Input: amount = 10, coins = [10]\n * Output: 1\n */\n\n\npublic class CoinChangeII518 {\n    public int change(int amount, int[] coins) {\n        int[][] dp = new int[coins.length+1][amount + 1];\n        dp[0][0] = 1;\n        for (int i=1; i<=coins.length; i++) {\n            dp[i][0] = 1;\n            int c = coins[i-1];\n            for (int j=1; j<=amount; j++) {\n                dp[i][j] = dp[i-1][j] + (j < c ? 0 : dp[i][j-c]);\n            }\n        }\n        return dp[coins.length][amount];\n    }\n\n\n    public int change2(int amount, int[] coins) {\n        int[] dp = new int[amount + 1];\n        dp[0] = 1;\n        for (int coin : coins) {\n            for (int i = coin; i <= amount; i++) {\n                dp[i] += dp[i-coin];\n            }\n        }\n        return dp[amount];\n    }\n\n\n    public int change3(int amount, int[] coins) {\n        int[][] dp = new int[coins.length+1][amount + 1];\n        for (int i=0; i<=coins.length; i++) dp[i][0] = 1;\n        for (int j=1; j<=amount; j++) {\n            for (int i=1; i<=coins.length; i++) {\n                int c = coins[i - 1];\n                dp[i][j] = dp[i-1][j] + (j < c ? 0 : dp[i][j-c]);\n            }\n        }\n        return dp[coins.length][amount];\n    }\n\n}\n"
  },
  {
    "path": "src/CollatzConjecture.java",
    "content": "/**\n * \n */\n\npublic class CollatzConjecture {\n\n    // public int maxSteps(int n) {\n    //     if (n < 1) return -1;\n    //     int res = -1;\n    //     for (int i=1; i<=n; i++) {\n    //         res = Math.max(res, steps(i));\n    //     }\n    //     return res;\n    // }\n\n    // public int steps(int i) {\n    //     int res = 0;\n    //     while (i != 1) {\n    //         if (i % 2 == 0) {\n    //             i = i / 2;\n    //         } else {\n    //             i = i * 3 + 1;\n    //         }\n    //     }\n    //     return res;\n    // }\n\n    public int maxSteps(int n) {\n        if (n < 1) return -1;\n        int res = -1;\n        int[] memo = new int[n+1];\n        for (int i=1; i<=n; i++) {\n            res = Math.max(res, steps(i, memo));\n        }\n        return res;\n    }\n\n    public int steps(int i, int[] memo) {\n        int res = 0;\n        int p = i;\n        while (p != 1) {\n            if (memo[p] > 0) {\n                memo[i] = res = memo[p];\n                return memo[i];\n            }\n            if (p % 2 == 0) {\n                p = p / 2;\n            } else {\n                p = p * 3 + 1;\n            }\n        }\n        memo[i] = res;\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/CombinationSum39.java",
    "content": "/**\n * Given a set of candidate numbers (candidates) (without duplicates) and a\n * target number (target), find all unique combinations in candidates where\n * the candidate numbers sums to target.\n * \n * The same repeated number may be chosen from candidates unlimited number of times.\n * \n * Note:\n * All numbers (including target) will be positive integers.\n * The solution set must not contain duplicate combinations.\n * \n * Example 1:\n * Input: candidates = [2,3,6,7], target = 7,\n * A solution set is:\n * [\n *   [7],\n *   [2,2,3]\n * ]\n * \n * Example 2:\n * Input: candidates = [2,3,5], target = 8,\n * A solution set is:\n * [\n *   [2,2,2,2],\n *   [2,3,3],\n *   [3,5]\n * ]\n */\n\npublic class CombinationSum39 {\n    public List<List<Integer>> combinationSum(int[] candidates, int target) {\n        List<List<Integer>> res = new ArrayList<>();\n        helper(candidates, target, 0, new ArrayList<Integer>(), res);\n        return res;\n    }\n    \n    private void helper(int[] candidates, int target, int start, List<Integer> path, List<List<Integer>> res) {\n        if (target < 0) return;\n        if (target == 0) {\n            List<Integer> newPath = new ArrayList<Integer>();\n            for (Integer i: path) newPath.add(i);\n            res.add(newPath);\n        }\n    \n        for (int i = start; i<candidates.length; i++) {\n            int c = candidates[i];\n            int count =  target / c;\n            if (count >= 1) {\n                for (int j=1; j<= count; j++) {path.add(c);}\n                while (count >= 1) {\n                    helper(candidates, target - c * count, i+1, path, res);\n                    path.remove(path.size() - 1);\n                    count--;\n                }\n            }\n        }\n    }\n  \n}\n"
  },
  {
    "path": "src/CombinationSumIII216.java",
    "content": "/**\n * Find all possible combinations of k numbers that add up to a number n, given\n * that only numbers from 1 to 9 can be used and each combination should be a\n * unique set of numbers.\n * \n * Note:\n * All numbers will be positive integers.\n * The solution set must not contain duplicate combinations.\n * \n * Example 1:\n * Input: k = 3, n = 7\n * Output: [[1,2,4]]\n * \n * Example 2:\n * Input: k = 3, n = 9\n * Output: [[1,2,6], [1,3,5], [2,3,4]]\n */\n\npublic class CombinationSumIII216 {\n    public List<List<Integer>> combinationSum3(int k, int n) {\n        List<List<Integer>> res = new ArrayList<>();\n        combinationSum3(k, n, new boolean[9], new ArrayList<>(), 0, 1, res);\n        return res;\n    }\n\n    private void combinationSum3(int k, int n, List<Integer> path, int sum, int start, List<List<Integer>> res) {\n        if (path.size() == k) {\n            if (sum == n) res.add(new ArrayList<>(path));\n            return;\n        }\n        for (int i=start; i<=9; i++) {\n            path.add(i);\n            combinationSum3(k, n, visited, path, sum + i, i+1, res);\n            path.remove(path.size()-1);\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/CombinationSumIV377.java",
    "content": "/**\n * Given an integer array with all positive numbers and no duplicates, find the\n * number of possible combinations that add up to a positive integer target.\n * \n * Example:\n * \n * nums = [1, 2, 3]\n * target = 4\n * \n * The possible combination ways are:\n * (1, 1, 1, 1)\n * (1, 1, 2)\n * (1, 2, 1)\n * (1, 3)\n * (2, 1, 1)\n * (2, 2)\n * (3, 1)\n * \n * Note that different sequences are counted as different combinations.\n * Therefore the output is 7.\n * \n * Follow up:\n * What if negative numbers are allowed in the given array?\n * How does it change the problem?\n * What limitation we need to add to the question to allow negative numbers?\n */\n\n\npublic class CombinationSumIV377 {\n    public int combinationSum4(int[] nums, int target) {\n        if (nums == null || target < 0) return 0;\n        int N = nums.length;\n        int[][] dp = new int[N + 1][target + 1];\n        for (int i=0; i<=N; i++) {\n            dp[i][0] = 1;\n        }\n        for (int i=1; i<=N; i++) {\n            int n = nums[i-1];\n            for (int j=1; j<=target; j++) {\n                int local = 0;\n                for (int k=1; k<i; k++) {\n                    local += j < nums[k-1] ? 0 : (dp[i][j - nums[k-1]] - dp[i-1][j - nums[k-1]]);\n                }\n                dp[i][j] = local + (j < n ? 0 : dp[i][j - n]) + dp[i-1][j];\n            }\n        }\n        return dp[N][target];\n    }\n\n\n    /**\n     * https://leetcode.com/problems/combination-sum-iv/discuss/85036/1ms-Java-DP-Solution-with-Detailed-Explanation\n     */\n    private int[] dp;\n    public int combinationSum42(int[] nums, int target) {\n        dp = new int[target + 1];\n        Arrays.fill(dp, -1);\n        dp[0] = 1;\n        return helper(nums, target);\n    }\n    \n    private int helper(int[] nums, int target) {\n        if (dp[target] != -1) {\n            return dp[target];\n        }\n        int res = 0;\n        for (int i = 0; i < nums.length; i++) {\n            if (target >= nums[i]) {\n                res += helper(nums, target - nums[i]);\n            }\n        }\n        dp[target] = res;\n        return res;\n    }\n\n\n    public int combinationSum43(int[] nums, int target) {\n        int[] comb = new int[target + 1];\n        comb[0] = 1;\n        for (int i = 1; i <= target; i++) {\n            for (int n: nums) {\n                if (i - n >= 0) {\n                    comb[i] += comb[i - n];\n                }\n            }\n        }\n        return comb[target];\n    }\n\n}\n"
  },
  {
    "path": "src/CompareVersionNumbers165.java",
    "content": "/**\n * Compare two version numbers version1 and version2.\n * If version1 > version2 return 1; if version1 < version2 return -1;\n * otherwise return 0.\n * \n * You may assume that the version strings are non-empty and contain only\n * digits and the . character.\n * \n * The . character does not represent a decimal point and is used to separate\n * number sequences.\n * \n * For instance, 2.5 is not \"two and a half\" or \"half way to version three\",\n * it is the fifth second-level revision of the second first-level revision.\n * \n * Example 1:\n * Input: version1 = \"0.1\", version2 = \"1.1\"\n * Output: -1\n * \n * Example 2:\n * Input: version1 = \"1.0.1\", version2 = \"1\"\n * Output: 1\n * \n * Example 3:\n * Input: version1 = \"7.5.2.4\", version2 = \"7.5.3\"\n * Output: -1\n */\n\n\npublic class CompareVersionNumbers165 {\n    public int compareVersion(String version1, String version2) {\n        String[] v1 = version1.split(\"\\\\.\");\n        String[] v2 = version2.split(\"\\\\.\");\n        \n        int len = Math.min(v1.length, v2.length);\n        for (int i=0; i<len; i++) {\n            int i1 = Integer.valueOf(v1[i]);\n            int i2 = Integer.valueOf(v2[i]);\n            if (i1 == i2) {\n                continue;\n            }\n            return Integer.compare(i1, i2);\n        }\n\n        int l = len;\n        while (l < v1.length) {\n            if (Integer.valueOf(v1[l]) > 0) return 1;\n            l++;\n        }\n        l = len;\n        while (l < v2.length) {\n            if (Integer.valueOf(v2[l]) > 0) return -1;\n            l++;\n        }\n        return 0;\n    }\n\n\n    public int compareVersion2(String version1, String version2) {\n        String[] v1 = version1.split(\"\\\\.\");\n        String[] v2 = version2.split(\"\\\\.\");\n        \n        int len = Math.max(v1.length, v2.length);\n        for (int i=0; i<len; i++) {\n            int i1 = i < v1.length ? Integer.valueOf(v1[i]) : 0;\n            int i2 = i < v2.length ? Integer.valueOf(v2[i]) : 0;\n            if (i1 == i2) {\n                continue;\n            }\n            return Integer.compare(i1, i2);\n        }\n\n        return 0;\n    }\n\n}\n"
  },
  {
    "path": "src/ConcatenatedWords472.java",
    "content": "/**\n * Given a list of words (without duplicates), please write a program that\n * returns all concatenated words in the given list of words.\n * \n * A concatenated word is defined as a string that is comprised entirely of at\n * least two shorter words in the given array.\n * \n * Example:\n * Input: [\"cat\",\"cats\",\"catsdogcats\",\"dog\",\"dogcatsdog\",\"hippopotamuses\",\"rat\",\"ratcatdogcat\"]\n * Output: [\"catsdogcats\",\"dogcatsdog\",\"ratcatdogcat\"]\n * \n * Explanation: \"catsdogcats\" can be concatenated by \"cats\", \"dog\" and \"cats\"; \n *  \"dogcatsdog\" can be concatenated by \"dog\", \"cats\" and \"dog\"; \n * \"ratcatdogcat\" can be concatenated by \"rat\", \"cat\", \"dog\" and \"cat\".\n * \n * Note:\n * The number of elements of the given array will not exceed 10,000\n * The length sum of elements in the given array will not exceed 600,000.\n * All the input string will only include lower case letters.\n * The returned elements order does not matter.\n */\n\npublic class ConcatenatedWords472 {\n    public List<String> findAllConcatenatedWordsInADict(String[] words) {\n        Trie trie = constructTrie(words);\n        List<String> res = new ArrayList<>();\n        for (String word: words) {\n            if (count(trie, word.toCharArray(), 0, trie, 1) >= 2) {\n                res.add(word);\n            }\n        }\n        return res;\n    }\n\n    private int count(Trie trie, char[] chars, int i, Trie root, int cnt) {\n        if (i == chars.length) return -1;\n        int idx = chars[i] - 'a';\n        if (trie.children[idx] == null) return -1;\n        if (trie.children[idx].isWord) {\n            if (i == chars.length - 1) return cnt;\n            int tmp = count(root, chars, i+1, root, cnt+1);\n            if (tmp >= 2) {\n                return tmp;\n            }\n        }\n        return count(trie.children[idx], chars, i+1, root, cnt);\n    }\n\n    private Trie constructTrie(String[] words) {\n        Trie trie = new Trie();\n        for (String word: words) trie.add(word);\n        return trie;\n    }\n\n    class Trie {\n        Trie[] children = new Trie[26];\n        boolean isWord;\n\n        void add(String word) {\n            add(word.toCharArray(), 0);\n        }\n\n        void add(char[] chars, int i) {\n            if (i == chars.length) {\n                isWord = true;\n                return;\n            }\n            int idx = chars[i] - 'a';\n            if (children[idx] == null) {\n                children[idx] = new Trie();\n            }\n            children[idx].add(chars, i+1);\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/ConstructBinaryTreeFromInorderAndPostorderTraversal106.java",
    "content": "/**\n * Given inorder and postorder traversal of a tree, construct the binary tree.\n * \n * Note:\n * You may assume that duplicates do not exist in the tree.\n * \n * For example, given\n * \n * inorder = [9,3,15,20,7]\n * postorder = [9,15,7,20,3]\n * Return the following binary tree:\n * \n *     3\n *    / \\\n *   9  20\n *     /  \\\n *    15   7\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class ConstructBinaryTreeFromInorderAndPostorderTraversal106 {\n    public TreeNode buildTree(int[] inorder, int[] postorder) {\n        if (inorder == null || postorder == null || inorder.length == 0 || postorder.length == 0 || inorder.length != postorder.length) return null;\n        int len = inorder.length;\n        return buildTree(inorder, 0, len-1, postorder, 0, len-1);\n    }\n\n    private TreeNode buildTree(int[] inorder, int ii, int ij, int[] postorder, int pi, int pj) {\n        if (ii > ij) return null;\n        int midVal = postorder[pj];\n        TreeNode curr = new TreeNode(midVal);\n        if (pi == pj) return curr;\n        \n        int mid = ii;\n        while (inorder[mid] != midVal) mid++;\n        \n        curr.left = buildTree(inorder, ii, mid-1, postorder, pi, pi+(mid-1-ii));\n        curr.right = buildTree(inorder, mid+1, ij, postorder, pi+(mid-ii), pj-1);\n        return curr;\n    }\n\n}\n"
  },
  {
    "path": "src/ConstructBinaryTreeFromPreorderAndInorderTraversal105.java",
    "content": "/**\n * Given preorder and inorder traversal of a tree, construct the binary tree.\n *\n * Note:\n * You may assume that duplicates do not exist in the tree.\n *\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\n\npublic class ConstructBinaryTreeFromPreorderAndInorderTraversal105 {\n    public TreeNode buildTree(int[] preorder, int[] inorder) {\n        if (inorder == null || inorder.length == 0) return null;\n        if (inorder.length == 1) return new TreeNode(inorder[0]);\n        int val = preorder[0];\n        int index = search(inorder, val);\n        TreeNode root = new TreeNode(val);\n        root.left = buildTree(Arrays.copyOfRange(preorder, 1, index+1), Arrays.copyOfRange(inorder, 0, index));\n        root.right = buildTree(Arrays.copyOfRange(preorder, index+1, preorder.length), Arrays.copyOfRange(inorder, index+1, inorder.length));\n        return root;\n    }\n\n    private int search(int[] order, int val) {\n        for (int i=0; i<order.length; i++) {\n            if (order[i] == val) return i;\n        }\n        return -1;\n    }\n\n\n\n    public TreeNode buildTree2(int[] preorder, int[] inorder) {\n        if (inorder == null || inorder.length == 0) return null;\n        if (inorder.length == 1) return new TreeNode(inorder[0]);\n        return buildTree(preorder, 0, preorder.length-1, inorder, 0, inorder.length-1);\n    }\n\n    public TreeNode buildTree(int[] preorder, int s1, int e1, int[] inorder, int s2, int e2) {\n        if (s1 > e1 || s2 > e2) return null;\n        if (s1 == e1 || s2 == e2) return new TreeNode(preorder[s1]);\n        int val = preorder[s1];\n        int index = search(inorder, val, s2, e2);\n        int len = index-s2;\n        TreeNode root = new TreeNode(val);\n        root.left = buildTree(preorder, s1+1, len+s1, inorder, s2, index-1);\n        root.right = buildTree(preorder, len+s1+1, e1, inorder, index+1, e2);\n        return root;\n    }\n\n    private int search(int[] order, int val, int start, int end) {\n        for (int i=start; i<=end; i++) {\n            if (order[i] == val) return i;\n        }\n        return -1;\n    }\n\n\n\n    public TreeNode buildTree3(int[] preorder, int[] inorder) {\n        if (preorder.length == 0) return null;\n        return buildTree(preorder, 0, inorder, 0, inorder.length);\n    }\n\n    private TreeNode buildTree(int[] preorder, int p, int[] inorder, int i, int j) {\n        if (p >= inorder.length || i > j) return null;\n\n        int curr = preorder[p];\n        TreeNode res = new TreeNode(curr);\n\n        int mid = i;\n        while (inorder[mid] != curr) mid++;\n\n        res.left = buildTree(preorder, p+1, inorder, i, mid-1);\n        res.right = buildTree(preorder, p+(mid-i)+1, inorder, mid+1, j);\n\n        return res;\n    }\n\n\n\n    /**\n     * https://discuss.leetcode.com/topic/29838/5ms-java-clean-solution-with-caching\n     */\n    public TreeNode buildTree4(int[] preorder, int[] inorder) {\n        Map<Integer, Integer> inMap = new HashMap<Integer, Integer>();\n\n        for(int i = 0; i < inorder.length; i++) {\n            inMap.put(inorder[i], i);\n        }\n\n        TreeNode root = buildTree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1, inMap);\n        return root;\n    }\n\n    public TreeNode buildTree(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd, Map<Integer, Integer> inMap) {\n        if(preStart > preEnd || inStart > inEnd) return null;\n\n        TreeNode root = new TreeNode(preorder[preStart]);\n        int inRoot = inMap.get(root.val);\n        int numsLeft = inRoot - inStart;\n\n        root.left = buildTree(preorder, preStart + 1, preStart + numsLeft, inorder, inStart, inRoot - 1, inMap);\n        root.right = buildTree(preorder, preStart + numsLeft + 1, preEnd, inorder, inRoot + 1, inEnd, inMap);\n\n        return root;\n    }\n\n}\n"
  },
  {
    "path": "src/ConstructBinaryTreeFromString536.java",
    "content": "/**\n * You need to construct a binary tree from a string consisting of parenthesis\n * and integers.\n * \n * The whole input represents a binary tree. It contains an integer followed\n * by zero, one or two pairs of parenthesis. The integer represents the root's\n * value and a pair of parenthesis contains a child binary tree with the same\n * structure.\n * \n * You always start to construct the left child node of the parent first if\n * it exists.\n * \n * Example:\n * Input: \"4(2(3)(1))(6(5))\"\n * Output: return the tree root node representing the following tree:\n * \n *        4\n *      /   \\\n *     2     6\n *    / \\   / \n *   3   1 5   \n * \n * Note:\n * There will only be '(', ')', '-' and '0' ~ '9' in the input string.\n * An empty tree is represented by \"\" instead of \"()\".\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class ConstructBinaryTreeFromString536 {\n    public TreeNode str2tree(String s) {\n        if (s == null || s.length() == 0) return null;\n        return str2tree(s.toCharArray(), 0, s.length()-1);\n    }\n    \n    public TreeNode str2tree(char[] chars, int i, int j) {\n        if (i > j) return null;\n        int len = 0;\n        while (i+len <= j && chars[i+len] != '(' && chars[i+len] != ')') {\n            len++;\n        }\n        TreeNode root = new TreeNode(Integer.parseInt(new String(chars, i, len)));\n        if (i + len - 1 == j) return root;\n\n        int m = i + len;\n        int count = 0;\n        while (m <= j) {\n            if (chars[m] == '(') {\n                count++;\n            } else if (chars[m] == ')') {\n                count--;\n            }\n            m++;\n            if (count == 0) break;\n        }\n        root.left = str2tree(chars, i+len+1, m-2);\n        root.right = str2tree(chars, m+1, j-1);\n        return root;\n    }\n\n}\n"
  },
  {
    "path": "src/ConstructQuadTree427.java",
    "content": "/**\n * We want to use quad trees to store an N x N boolean grid. Each cell in the\n * grid can only be true or false. The root node represents the whole grid. For\n * each node, it will be subdivided into four children nodes until the values\n * in the region it represents are all the same.\n * \n * Each node has another two boolean attributes : isLeaf and val. isLeaf is\n * true if and only if the node is a leaf node. The val attribute for a leaf\n * node contains the value of the region it represents.\n * \n * Your task is to use a quad tree to represent a given grid. The following\n * example may help you understand the problem better:\n * \n * Given the 8 x 8 grid below, we want to construct the corresponding quad tree:\n * https://s3-lc-upload.s3.amazonaws.com/uploads/2018/02/01/962_grid.png\n * \n * It can be divided according to the definition above:\n * https://s3-lc-upload.s3.amazonaws.com/uploads/2018/02/01/962_grid_divided.png\n * \n * The corresponding quad tree should be as following, where each node is\n * represented as a (isLeaf, val) pair.\n * \n * For the non-leaf nodes, val can be arbitrary, so it is represented as *.\n * https://s3-lc-upload.s3.amazonaws.com/uploads/2018/02/01/962_quad_tree.png\n * \n * Note:\n * N is less than 1000 and guaranteened to be a power of 2.\n * If you want to know more about the quad tree, you can refer to its wiki.\n */\n\n/*\n// Definition for a QuadTree node.\nclass Node {\n    public boolean val;\n    public boolean isLeaf;\n    public Node topLeft;\n    public Node topRight;\n    public Node bottomLeft;\n    public Node bottomRight;\n\n    public Node() {}\n\n    public Node(boolean _val,boolean _isLeaf,Node _topLeft,Node _topRight,Node _bottomLeft,Node _bottomRight) {\n        val = _val;\n        isLeaf = _isLeaf;\n        topLeft = _topLeft;\n        topRight = _topRight;\n        bottomLeft = _bottomLeft;\n        bottomRight = _bottomRight;\n    }\n};\n*/\n\npublic class ConstructQuadTree427 {\n    public Node construct(int[][] grid) {\n        if (grid == null) return null;\n        int N = grid.length;\n        return construct(grid, 0, N-1, 0, N-1);\n    }\n\n    public Node construct(int[][] grid, int xi, int xj, int yi, int yj) {\n        if (xi > xj) return null;\n        Node res = new Node();\n        if (xi == xj) {\n            res.isLeaf = true;\n            res.val = grid[xi][yi] == 1;\n            return res;\n        }\n\n        int xm = (xi + xj) / 2;\n        int ym = (yi + yj) / 2;\n        res.topLeft = construct(grid, xi, xm, yi, ym);\n        res.topRight = construct(grid, xi, xm, ym+1, yj);\n        res.bottomLeft = construct(grid, xm+1, xj, yi, ym);\n        res.bottomRight = construct(grid, xm+1, xj, ym+1, yj);\n\n        if (allLeaves(res) && allSame(res)) {\n            res.isLeaf = true;\n            res.val = res.topLeft.val;\n            res.topLeft = null;\n            res.topRight = null;\n            res.bottomLeft = null;\n            res.bottomRight = null;\n        }\n        return res;\n    }\n\n    private boolean allLeaves(Node n) {\n        return n.topLeft.isLeaf &&\n            n.topRight.isLeaf &&\n            n.bottomLeft.isLeaf &&\n            n.bottomRight.isLeaf;\n    }\n\n    private boolean allSame(Node n) {\n        return (n.topLeft.val == n.topRight.val) &&\n                (n.bottomLeft.val == n.bottomRight.val) &&\n                (n.topLeft.val == n.bottomLeft.val);\n    }\n\n}\n\n\n\n\n"
  },
  {
    "path": "src/ContainerWithMostWater11.java",
    "content": "/**\n * Given n non-negative integers a1, a2, ..., an, where each represents a point\n * at coordinate (i, ai). n vertical lines are drawn such that the two endpoints\n * of line i is at (i, ai) and (i, 0). Find two lines, which together with\n * x-axis forms a container, such that the container contains the most water.\n * \n * Note: You may not slant the container and n is at least 2.\n */\n\npublic class ContainerWithMostWater11 {\n    /**\n     * https://leetcode.com/problems/container-with-most-water/discuss/6089/Anyone-who-has-a-O(N)-algorithm/7268\n     * Here is the proof.\n     * Proved by contradiction:\n     * \n     * Suppose the returned result is not the optimal solution. Then there must\n     * exist an optimal solution, say a container with a_ol and a_or (left and\n     * right respectively), such that it has a greater volume than the one we got.\n     * Since our algorithm stops only if the two pointers meet. So, we must have\n     * visited one of them but not the other. WLOG, let's say we visited a_ol but\n     * not a_or. When a pointer stops at a_ol, it won't move until\n     * \n     * The other pointer also points to a_ol.\n     * In this case, iteration ends. But the other pointer must have visited a_or\n     * on its way from right end to a_ol. Contradiction to our assumption that we\n     * didn't visit a_or.\n     * \n     * The other pointer arrives at a value, say a_rr, that is greater than a_ol\n     * before it reaches a_or.\n     * \n     * In this case, we does move a_ol. But notice that the volume of a_ol and\n     * a_rr is already greater than a_ol and a_or (as it is wider and heigher),\n     * which means that a_ol and a_or is not the optimal solution --\n     * Contradiction!\n     * \n     * Both cases arrive at a contradiction.\n     */\n    public int maxArea(int[] height) {\n        int res = 0;\n        int n = height.length;\n        int left = 0;\n        int right = n-1;\n        while (left < right) {\n            res = Math.max(res, Math.min(height[left], height[right]) * (right - left));\n            if (height[left] < height[right]) {\n                left++;\n            } else {\n                right--;\n            }\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/ContainsDuplicate217.java",
    "content": "/**\n * Given an array of integers, find if the array contains any duplicates. Your\n * function should return true if any value appears at least twice in the array,\n * and it should return false if every element is distinct.\n */\n\npublic class ContainsDuplicate217 {\n    public boolean containsDuplicate(int[] nums) {\n        Set<Integer> set = new HashSet<>();\n        for (int n: nums) {\n            if (set.contains(n)) {\n                return true;\n            } else {\n                set.add(n);\n            }\n        }\n        return false;\n    }\n\n\n    public boolean containsDuplicate2(int[] nums) {\n        Arrays.sort(nums);\n        for (int i = 0; i < nums.length - 1; ++i) {\n            if (nums[i] == nums[i + 1]) return true;\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "src/ContainsDuplicateIII220.java",
    "content": "/**\n * Given an array of integers, find out whether there are two distinct indices\n * i and j in the array such that the absolute difference between nums[i] and\n * nums[j] is at most t and the absolute difference between i and j is at\n * most k.\n */\n\npublic class ContainsDuplicateIII220 {\n    // // TLE\n    // public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {\n    //     for (int i=0; i<nums.length; i++) {\n    //         for (int j=i+1; j<nums.length && j<=i+k; j++) {\n    //             if (Math.abs((long)nums[i] - (long)nums[j]) <= (long)t) return true;\n    //         }\n    //     }\n    //\n    //     return false;\n    // }\n\n\n    /**\n     * https://leetcode.com/problems/contains-duplicate-iii/solution/\n     */\n    public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {\n        TreeSet<Integer> set = new TreeSet<>();\n        for (int i = 0; i < nums.length; ++i) {\n            // Find the successor of current element\n            Integer s = set.ceiling(nums[i]);\n            if (s != null && s <= nums[i] + t) return true;\n\n            // Find the predecessor of current element\n            Integer g = set.floor(nums[i]);\n            if (g != null && nums[i] <= g + t) return true;\n\n            set.add(nums[i]);\n            if (set.size() > k) {\n                set.remove(nums[i - k]);\n            }\n        }\n        return false;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/contains-duplicate-iii/solution/\n     */\n    // Get the ID of the bucket from element value x and bucket width w\n    // In Java, `-3 / 5 = 0` and but we need `-3 / 5 = -1`.\n    private long getID(long x, long w) {\n        return x < 0 ? (x + 1) / w - 1 : x / w;\n    }\n\n    public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {\n        if (t < 0) return false;\n        Map<Long, Long> d = new HashMap<>();\n        long w = (long)t + 1;\n        for (int i = 0; i < nums.length; ++i) {\n            long m = getID(nums[i], w);\n            // check if bucket m is empty, each bucket may contain at most one element\n            if (d.containsKey(m))\n                return true;\n            // check the neighbor buckets for almost duplicate\n            if (d.containsKey(m - 1) && Math.abs(nums[i] - d.get(m - 1)) < w)\n                return true;\n            if (d.containsKey(m + 1) && Math.abs(nums[i] - d.get(m + 1)) < w)\n                return true;\n            // now bucket m is empty and no almost duplicate in neighbor buckets\n            d.put(m, (long)nums[i]);\n            if (i >= k) d.remove(getID(nums[i - k], w));\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "src/ContainsDuplicatesII219.java",
    "content": "/**\n * Given an array of integers and an integer k, find out whether there are\n * two distinct indices i and j in the array such that nums[i] = nums[j] and\n * the absolute difference between i and j is at most k.\n */\n\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.HashMap;\nimport java.util.Map;\n\n\npublic class ContainsDuplicatesII219 {\n    // too slow\n    public boolean containsNearbyDuplicate(int[] nums, int k) {\n        if (nums.length < 2) {\n          return false;\n        }\n\n        for (int i = 0; i < nums.length; i++) {\n          int numI = nums[i];\n          for (int j = i + 1; j < nums.length && j - i <= k; j++) {\n            int numJ = nums[j];\n            if (numI == numJ) {\n              return true;\n            }\n          }\n        }\n        return false;\n    }\n\n    public boolean containsNearbyDuplicate2(int[] nums, int k) {\n        if (nums.length < 2) {\n          return false;\n        }\n\n        Map<Integer, Integer> map = new HashMap<>();\n        for (int i = 0; i < nums.length; i++) {\n          Integer key = nums[i];\n          if (map.containsKey(key)) {\n              if (i - map.get(key) <= k) {\n                  return true;\n              }\n          }\n          map.put(key, i);\n        }\n\n        return false;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/15305/simple-java-solution\n     */\n    public boolean containsNearbyDuplicate3(int[] nums, int k) {\n        Set<Integer> set = new HashSet<Integer>();\n        for(int i = 0; i < nums.length; i++) {\n            if(i > k) {\n              set.remove(nums[i-k-1]);\n            }\n\n            if(!set.add(nums[i])) {\n              return true;\n            }\n        }\n        return false;\n    }\n\n\n    public static void main(String[] args) {\n        ContainsDuplicatesII219 cd2 = new ContainsDuplicatesII219();\n\n        System.out.println(cd2.containsNearbyDuplicate2(new int[]{5, 8, 2, 10, 5}, 4));\n        System.out.println(cd2.containsNearbyDuplicate2(new int[]{5, 8, 2, 10}, 1));\n    }\n}\n"
  },
  {
    "path": "src/ContiguousArray525.java",
    "content": "/**\n * Given a binary array, find the maximum length of a contiguous subarray with\n * equal number of 0 and 1.\n *\n * Example 1:\n *    Input: [0,1]\n *    Output: 2\n *\n * Explanation: [0, 1] is the longest contiguous subarray with equal number of 0 and 1.\n *\n * Example 2:\n *    Input: [0,1,0]\n *    Output: 2\n *\n * Explanation: [0, 1] (or [1, 0]) is a longest contiguous subarray with equal number of 0 and 1.\n *\n * Note: The length of the given binary array will not exceed 50,000.\n *\n */\n\n\npublic class ContiguousArray525 {\n    /**\n     * https://leetcode.com/problems/contiguous-array/solution/\n     */\n    public int findMaxLength(int[] nums) {\n        int maxlen = 0;\n        for (int start = 0; start < nums.length; start++) {\n            int zeroes = 0, ones = 0;\n            for (int end = start; end < nums.length; end++) {\n                if (nums[end] == 0) {\n                    zeroes++;\n                } else {\n                    ones++;\n                }\n                if (zeroes == ones) {\n                    maxlen = Math.max(maxlen, end - start + 1);\n                }\n            }\n        }\n        return maxlen;\n    }\n\n    public int findMaxLength2(int[] nums) {\n        int[] arr = new int[2 * nums.length + 1];\n        Arrays.fill(arr, -2);\n        arr[nums.length] = -1;\n        int maxlen = 0, count = 0;\n        for (int i = 0; i < nums.length; i++) {\n            count = count + (nums[i] == 0 ? -1 : 1);\n            if (arr[count + nums.length] >= -1) {\n                maxlen = Math.max(maxlen, i - arr[count + nums.length]);\n            } else {\n                arr[count + nums.length] = i;\n            }\n\n        }\n        return maxlen;\n    }\n\n    public int findMaxLength3(int[] nums) {\n        Map<Integer, Integer> map = new HashMap<>();\n        map.put(0, -1);\n        int maxlen = 0, count = 0;\n        for (int i = 0; i < nums.length; i++) {\n            count = count + (nums[i] == 1 ? 1 : -1);\n            if (map.containsKey(count)) {\n                maxlen = Math.max(maxlen, i - map.get(count));\n            } else {\n                map.put(count, i);\n            }\n        }\n        return maxlen;\n    }\n\n}\n"
  },
  {
    "path": "src/ContinuousSubarraySum523.java",
    "content": "/**\n * Given a list of non-negative numbers and a target integer k, write a\n * function to check if the array has a continuous subarray of size at least 2\n * that sums up to the multiple of k, that is, sums up to n*k where n is also\n * an integer.\n * \n * Example 1:\n * Input: [23, 2, 4, 6, 7],  k=6\n * Output: True\n * Explanation: Because [2, 4] is a continuous subarray of size 2 and sums up\n * to 6.\n * \n * Example 2:\n * Input: [23, 2, 6, 4, 7],  k=6\n * Output: True\n * Explanation: Because [23, 2, 6, 4, 7] is an continuous subarray of size 5\n * and sums up to 42.\n * \n * Note:\n * The length of the array won't exceed 10,000.\n * You may assume the sum of all the numbers is in the range of a signed\n * 32-bit integer.\n * \n */\n\npublic class ContinuousSubarraySum523 {\n    public boolean checkSubarraySum(int[] nums, int k) {\n        if (k == 0) return kIsZero(nums);\n        return kIsNotZero(nums, k);\n    }\n    \n    public boolean kIsNotZero(int[] nums, int k) {\n        Map<Integer, Integer> map = new HashMap<>();\n        map.put(0, -1);\n        int sum = 0;\n        for (int i=0; i<nums.length; i++) {\n            sum += nums[i];\n            int mod = sum % k;\n            if (map.containsKey(mod)) {\n                if (i - map.get(mod) >= 2) return true;\n            } else {\n                map.put(mod, i);\n            }\n        }\n        return false;\n    }\n    \n    public boolean kIsZero(int[] nums) {\n        int count = 0;\n        for (int i=0; i<nums.length; i++) {\n            if (nums[i] == 0) {\n                count++;\n                if (count >= 2) return true;\n            } else {\n                count = 0;\n            }\n        }\n        return false;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/continuous-subarray-sum/solution/\n     */\n    public boolean checkSubarraySum2(int[] nums, int k) {\n        int sum = 0;\n        HashMap < Integer, Integer > map = new HashMap < > ();\n        map.put(0, -1);\n        for (int i = 0; i < nums.length; i++) {\n            sum += nums[i];\n            if (k != 0)\n                sum = sum % k;\n            if (map.containsKey(sum)) {\n                if (i - map.get(sum) > 1)\n                    return true;\n            } else\n                map.put(sum, i);\n        }\n        return false;\n    }\n\n\n}\n"
  },
  {
    "path": "src/ConvertANumberToHexadecimal405.java",
    "content": "/**\n * Given an integer, write an algorithm to convert it to hexadecimal. For\n * negative integer, two’s complement method is used.\n * \n * Note:\n * \n * All letters in hexadecimal (a-f) must be in lowercase.\n * The hexadecimal string must not contain extra leading 0s. If the number is\n * zero, it is represented by a single zero character '0'; otherwise, the first\n * character in the hexadecimal string will not be the zero character.\n * The given number is guaranteed to fit within the range of a 32-bit signed integer.\n * You must not use any method provided by the library which converts/formats\n * the number to hex directly.\n * \n * Example 1:\n * Input:\n * 26\n * Output:\n * \"1a\"\n * \n * Example 2:\n * Input:\n * -1\n * Output:\n * \"ffffffff\"\n */\n\npublic class ConvertANumberToHexadecimal405 {\n    public String toHex(int num) {\n        if (num == 0) return \"0\";\n        char[] map = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};\n        StringBuilder sb = new StringBuilder();\n        long n = num & 0x00000000ffffffffL;\n        while (n > 0) {\n            sb.insert(0, map[(int) (n % 16)]);\n            n /= 16;\n        }\n        return sb.toString();\n    }\n\n\n    /**\n     * https://leetcode.com/problems/convert-a-number-to-hexadecimal/discuss/89253/Simple-Java-solution-with-comment\n     */\n    public String toHex2(int num) {\n        if(num == 0) return \"0\";\n        char[] map = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};\n        String result = \"\";\n        while(num != 0){\n            result = map[(num & 15)] + result; \n            num = (num >>> 4);\n        }\n        return result;\n    }\n\n}\n"
  },
  {
    "path": "src/ConvertBSTToGreaterTree538.java",
    "content": "/**\n * Given a Binary Search Tree (BST), convert it to a Greater Tree such that\n * every key of the original BST is changed to the original key plus sum of\n * all keys greater than the original key in BST.\n * \n * Example:\n * \n * Input: The root of a Binary Search Tree like this:\n *               5\n *             /   \\\n *            2     13\n * \n * Output: The root of a Greater Tree like this:\n *              18\n *             /   \\\n *           20     13\n * \n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class ConvertBSTToGreaterTree538 {\n    public TreeNode convertBST(TreeNode root) {\n        return convertBST(root, new int[1]);\n    }\n\n    private TreeNode convertBST(TreeNode root, int[] sum) {\n        if (root == null) return null;\n        convertBST(root.right, sum);\n        sum[0] += root.val;\n        root.val = sum[0];\n        convertBST(root.left, sum);\n        return root;\n    }\n\n\n    public TreeNode convertBST2(TreeNode root) {\n        if (root == null) return null;\n        TreeNode curr = root;\n        Stack<TreeNode> stack = new Stack<>();\n        int sum = 0;\n        while (!stack.isEmpty() || curr != null) {\n            while (curr != null) {\n                stack.push(curr);\n                curr = curr.right;\n            }\n            \n            curr = stack.pop();\n            sum += curr.val;\n            curr.val = sum;\n            curr = curr.left;\n        }\n        return root;\n    }\n\n}\n"
  },
  {
    "path": "src/ConvertBinarySearchTreeToSortedDoublyLinkedList.java",
    "content": "/**\n * Convert a BST to a sorted circular doubly-linked list in-place. Think of the\n * left and right pointers as synonymous to the previous and next pointers in a\n * doubly-linked list.\n *\n * Let's take the following BST as an example, it may help you understand the problem better:\n *\n * https://leetcode.com/static/images/problemset/BSTDLLOriginalBST.png\n *\n * We want to transform this BST into a circular doubly linked list. Each node\n * in a doubly linked list has a predecessor and successor. For a circular\n * doubly linked list, the predecessor of the first element is the last element,\n * and the successor of the last element is the first element.\n *\n * The figure below shows the circular doubly linked list for the BST above.\n * The \"head\" symbol means the node it points to is the smallest element of\n * the linked list.\n *\n * https://leetcode.com/static/images/problemset/BSTDLLReturnDLL.png\n *\n * Specifically, we want to do the transformation in place. After the\n * transformation, the left pointer of the tree node should point to its\n * predecessor, and the right pointer should point to its successor. We should\n * return the pointer to the first element of the linked list.\n *\n * The figure below shows the transformed BST. The solid line indicates the\n * successor relationship, while the dashed line means the predecessor relationship.\n *\n * https://leetcode.com/static/images/problemset/BSTDLLReturnBST.png\n *\n */\n\n\n/*\n// Definition for a Node.\nclass Node {\n    public int val;\n    public Node left;\n    public Node right;\n\n    public Node() {}\n\n    public Node(int _val,Node _left,Node _right) {\n        val = _val;\n        left = _left;\n        right = _right;\n    }\n};\n*/\n\npublic class ConvertBinarySearchTreeToSortedDoublyLinkedList {\n    public Node treeToDoublyList(Node root) {\n        if (root == null) return null;\n        Node[] edges = dfs(root);\n        edges[0].left = edges[1];\n        edges[1].right = edges[0];\n        return edges[0];\n    }\n\n    private Node[] dfs(Node n) {\n        if (n.left == null && n.right == null) return new Node[]{n, n};\n        Node head;\n        Node tail;\n        if (n.left == null) {\n            head = n;\n            head.left = null;\n        } else {\n            Node[] left = dfs(n.left);\n            head = left[0];\n            head.left = null;\n            Node leftTail = left[1];\n            leftTail.right = n;\n            n.left = leftTail;\n        }\n        if (n.right == null) {\n            tail = n;\n            tail.right = null;\n        } else {\n            Node[] right = dfs(n.right);\n            tail = right[1];\n            tail.right = null;\n            Node rightHead = right[0];\n            rightHead.left = n;\n            n.right = rightHead;\n        }\n\n        return new Node[]{head, tail};\n    }\n\n\n}\n"
  },
  {
    "path": "src/ConvertSortedArrayToBinarySearchTree108.java",
    "content": "/**\n * Given an array where elements are sorted in ascending order, convert it to a\n * height balanced BST.\n *\n * For this problem, a height-balanced binary tree is defined as a binary tree\n * in which the depth of the two subtrees of every node never differ by more\n * than 1.\n *\n *\n * Example:\n *\n * Given the sorted array: [-10,-3,0,5,9],\n *\n * One possible answer is: [0,-3,9,-10,null,5], which represents the following\n * height balanced BST:\n *\n *       0\n *      / \\\n *    -3   9\n *    /   /\n *  -10  5\n *\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\nclass ConvertSortedArrayToBinarySearchTree108 {\n    public TreeNode sortedArrayToBST(int[] nums) {\n        return sortedArrayToBST(nums, 0, nums.length-1);\n    }\n\n    public TreeNode sortedArrayToBST(int[] nums, int i, int j) {\n        if (i > j) return null;\n        int mid = (i + j) / 2;\n        TreeNode res = new TreeNode(nums[mid]);\n        if (i == j) return res;\n        res.left = sortedArrayToBST(nums, i, mid-1);\n        res.right = sortedArrayToBST(nums, mid+1, j);\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/ConvertSortedListToBST109.java",
    "content": "/**\n * Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.\n */\n\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n\n/*\n  The following classes are defined in seperate files.\n */\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\n\npublic class ConvertSortedListToBST109 {\n    public TreeNode sortedListToBST(ListNode head) {\n        List<TreeNode> nodes = new ArrayList<TreeNode>();\n        storeBSTNodes(head, nodes);\n\n        int n = nodes.size();\n        return buildBST(nodes, 0, n-1);\n    }\n\n    private void storeBSTNodes(ListNode head, List<TreeNode> nodes) {\n        while (head != null) {\n            nodes.add(new TreeNode(head.val));\n            head = head.next;\n        }\n    }\n\n    private TreeNode buildBST(List<TreeNode> nodes, int start, int end) {\n        if (start > end)\n            return null;\n\n        int mid = (start + end) / 2;\n        TreeNode node = nodes.get(mid);\n\n        node.left = buildBST(nodes, start, mid - 1);\n        node.right = buildBST(nodes, mid + 1, end);\n\n        return node;\n    }\n\n    /** -------------------------------------------------------------------\n     * Top Solution: O(n logn)\n     * https://discuss.leetcode.com/topic/35997/share-my-java-solution-1ms-very-short-and-concise\n     * --------------------------------------------------------------------\n     */\n\n    public TreeNode sortedListToBST2(ListNode head) {\n        if (head == null) return null;\n        return toBST(head, null);\n    }\n\n    public TreeNode toBST(ListNode head, ListNode tail){\n        ListNode slow = head;\n        ListNode fast = head;\n        if(head == tail) return null;\n\n        while(fast != tail && fast.next != tail){\n            fast = fast.next.next;\n            slow = slow.next;\n        }\n        TreeNode thead = new TreeNode(slow.val);\n        thead.left = toBST(head, slow);\n        thead.right = toBST(slow.next, tail);\n        return thead;\n    }\n\n\n    /** -------------------------------------------------------------------\n     * Top Solution: O(n)\n     * https://discuss.leetcode.com/topic/35997/share-my-java-solution-1ms-very-short-and-concise\n     * --------------------------------------------------------------------\n     */\n\n    private ListNode node;\n\n    public TreeNode sortedListToBST3(ListNode head) {\n      \tif(head == null){\n      \t\t  return null;\n      \t}\n\n      \tint size = 0;\n      \tListNode runner = head;\n      \tnode = head;\n\n      \twhile(runner != null){\n      \t\t  runner = runner.next;\n      \t\t      size ++;\n      \t}\n\n      \treturn inorderHelper(0, size - 1);\n    }\n\n    public TreeNode inorderHelper(int start, int end){\n    \t  if(start > end){\n    \t\t    return null;\n    \t  }\n\n        int mid = start + (end - start) / 2;\n        TreeNode left = inorderHelper(start, mid - 1);\n\n        TreeNode treenode = new TreeNode(node.val);\n        treenode.left = left;\n        node = node.next;\n\n        TreeNode right = inorderHelper(mid + 1, end);\n        treenode.right = right;\n\n        return treenode;\n    }\n\n\n    public TreeNode sortedListToBST4(ListNode head) {\n        if (head == null) return null;\n        if (head.next == null) return new TreeNode(head.val);\n\n        ListNode fast = head;\n        ListNode slow = head;\n        ListNode beforeSlow = null;\n        while (slow != null && fast != null && fast.next != null) {\n            fast = fast.next.next;\n            beforeSlow = slow;\n            slow = slow.next;\n        }\n\n        beforeSlow.next = null;\n        TreeNode res = new TreeNode(slow.val);\n        res.left = sortedListToBST(head);\n        res.right = sortedListToBST(slow.next);\n\n        return res;\n    }\n\n    public TreeNode sortedListToBST5(ListNode head) {\n        if (head == null) return null;\n        \n        ListNode fast = head;\n        ListNode slow = head;\n        ListNode pre = null;\n        while (fast != null && fast.next != null) {\n            fast = fast.next.next;\n            pre = slow;\n            slow = slow.next;\n        }\n        if (pre == null) {\n            return new TreeNode(head.val);\n        }\n        pre.next = null;\n        TreeNode root = new TreeNode(slow.val);\n        root.left = sortedListToBST(head);\n        root.right = sortedListToBST(slow.next);\n        return root;\n    }\n\n\n}\n"
  },
  {
    "path": "src/CopyListWithRandomPointer138.java",
    "content": "/**\n * A linked list is given such that each node contains an additional random\n * pointer which could point to any node in the list or null.\n *\n * Return a deep copy of the list.\n *\n */\n\n/**\n * Definition for singly-linked list with a random pointer.\n * class RandomListNode {\n *     int label;\n *     RandomListNode next, random;\n *     RandomListNode(int x) { this.label = x; }\n * };\n */\n\npublic class CopyListWithRandomPointer138 {\n    public RandomListNode copyRandomList(RandomListNode head) {\n        return deepCopy(head, new HashMap<RandomListNode, RandomListNode>());\n    }\n\n    public RandomListNode deepCopy(RandomListNode node, Map<RandomListNode, RandomListNode> map) {\n        if (node == null) return null;\n        if (map.containsKey(node)) return map.get(node);\n\n        RandomListNode copy = new RandomListNode(node.label);\n        map.put(node, copy);\n        copy.next = deepCopy(node.next, map);\n        copy.random = deepCopy(node.random, map);\n\n        return copy;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/copy-list-with-random-pointer/discuss/43488/Java-O(n)-solution\n     */\n    public RandomListNode copyRandomList2(RandomListNode head) {\n      if (head == null) return null;\n\n      Map<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();\n\n      // loop 1. copy all the nodes\n      RandomListNode node = head;\n      while (node != null) {\n        map.put(node, new RandomListNode(node.label));\n        node = node.next;\n      }\n\n      // loop 2. assign next and random pointers\n      node = head;\n      while (node != null) {\n        map.get(node).next = map.get(node.next);\n        map.get(node).random = map.get(node.random);\n        node = node.next;\n      }\n\n      return map.get(head);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/copy-list-with-random-pointer/discuss/43491/A-solution-with-constant-space-complexity-O(1)-and-linear-time-complexity-O(N)\n     */\n    public RandomListNode copyRandomList3(RandomListNode head) {\n    \tRandomListNode iter = head, next;\n\n    \t// First round: make copy of each node,\n    \t// and link them together side-by-side in a single list.\n    \twhile (iter != null) {\n    \t\tnext = iter.next;\n\n    \t\tRandomListNode copy = new RandomListNode(iter.label);\n    \t\titer.next = copy;\n    \t\tcopy.next = next;\n\n    \t\titer = next;\n    \t}\n\n    \t// Second round: assign random pointers for the copy nodes.\n    \titer = head;\n    \twhile (iter != null) {\n    \t\tif (iter.random != null) {\n    \t\t\titer.next.random = iter.random.next;\n    \t\t}\n    \t\titer = iter.next.next;\n    \t}\n\n    \t// Third round: restore the original list, and extract the copy list.\n    \titer = head;\n    \tRandomListNode pseudoHead = new RandomListNode(0);\n    \tRandomListNode copy, copyIter = pseudoHead;\n\n    \twhile (iter != null) {\n    \t\tnext = iter.next.next;\n\n    \t\t// extract the copy\n    \t\tcopy = iter.next;\n    \t\tcopyIter.next = copy;\n    \t\tcopyIter = copy;\n\n    \t\t// restore the original list\n    \t\titer.next = next;\n\n    \t\titer = next;\n    \t}\n\n    \treturn pseudoHead.next;\n    }\n\n\n\n}\n"
  },
  {
    "path": "src/CountNumbersWithUniqueDigits357.java",
    "content": "/**\n * Given a non-negative integer n, count all numbers with unique digits, x,\n * where 0 ≤ x < 10n.\n * \n * Example:\n * Given n = 2, return 91. (The answer should be the total numbers in the\n * range of 0 ≤ x < 100, excluding [11,22,33,44,55,66,77,88,99])\n */\n\n\npublic class CountNumbersWithUniqueDigits357 {\n    public int countNumbersWithUniqueDigits(int n) {\n        n = Math.min(n, 10);\n        int res = 1;\n        for (int i=1; i<=n; i++) {\n            res += count(i);\n        }\n        return res;\n    }\n    private int count(int i) {\n        int res = 9;\n        int k = 1;\n        while (k < i) {\n            res *= (10-k);\n            k++;\n        }\n        return res;\n    }\n\n    /**\n     * https://leetcode.com/problems/count-numbers-with-unique-digits/discuss/83037/Very-simple-15-line-backtrack-solution\n     */\n    public int countNumbersWithUniqueDigits2(int n) {\n        return count(n, new boolean[10], 0);\n    }\n    \n    private int count(int n, boolean[] used, int l) {\n        if (l == n) return 1;\n\n        int res = 0;\n        for (int i = (l == 0 ? 1 : 0); i<=9; i++) {\n            if (!used[i]) {\n                used[i] = true;\n                res += count(n, used, l+1);\n                used[i] = false;\n            }\n        }\n        return res;\n    }\n  \n    public int countNumbersWithUniqueDigits3(int n) {\n        int[] res = new int[1];\n        count(n, new boolean[10], 0, res);\n        return res[0];\n    }\n    \n    private void count(int n, boolean[] used, int l, int[] res) {\n        res[0]++;\n        if (l == n) return;\n\n        for (int i = (l == 0 ? 1 : 0); i<=9; i++) {\n            if (!used[i]) {\n                used[i] = true;\n                count(n, used, l+1, res);\n                used[i] = false;\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/CountOfRangeSum327.java",
    "content": "/**\n * Given an integer array nums, return the number of range sums that lie in\n * [lower, upper] inclusive.\n *\n * Range sum S(i, j) is defined as the sum of the elements in nums between\n * indices i and j (i ≤ j), inclusive.\n *\n * Note:\n * A naive algorithm of O(n2) is trivial. You MUST do better than that.\n *\n * Example:\n * Given nums = [-2, 5, -1], lower = -2, upper = 2,\n * Return 3.\n *\n * The three ranges are : [0, 0], [2, 2], [0, 2] and their respective sums\n * are: -2, -1, 2.\n *\n */\n\n\npublic class CountOfRangeSum327 {\n    public int countRangeSum(int[] nums, int lower, int upper) {\n        int len = nums.length;\n        if (nums == null || len == 0) return 0;\n        int[][] dp = new int[len][len];\n        int res = 0;\n        for (int i=0; i<len; i++) {\n            dp[i][i] = nums[i];\n            if (nums[i] >= lower && nums[i] <= upper) res++;\n        }\n\n        for (int j=1; j<len; j++) {\n            int ii = 0;\n            int jj = j;\n            while (jj < len && ii < len) {\n                long curr = (long) dp[ii][jj-1] + (long) dp[ii+1][jj] - (long) dp[ii+1][jj-1];\n                // System.out.println(ii + \", \" + jj + \": \" + dp[ii][jj-1] + \" + \" + dp[ii+1][jj] + \" = \" + curr);\n                if (curr >= lower && curr <= upper) res++;\n                dp[ii][jj] = (int) curr;\n                ii++;\n                jj++;\n            }\n        }\n\n        return res;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/33738/share-my-solution\n     */\n    int count = 0;\n    int lower;\n    int upper;\n    public int countRangeSum2(int[] nums, int lower, int upper) {\n        long[] sum = new long[nums.length + 1];\n        long[] temp = new long[nums.length + 1];\n        sum[0] = 0;\n        this.lower = lower;\n        this.upper = upper;\n        for (int i = 1; i <= nums.length; i++) {\n            sum[i] = sum[i - 1] + (long) nums[i - 1];\n        }\n\n        mergesort(sum, 0, sum.length - 1, temp);\n        return count;\n    }\n\n    private void mergesort(long[] sum, int start, int end, long[] temp) {\n        if (start >= end) {\n            return;\n        }\n        int mid = start + (end - start) / 2;\n        mergesort(sum, start, mid, temp);\n        mergesort(sum, mid + 1, end, temp);\n        merge(sum, start, mid, end, temp);\n    }\n\n    private void merge(long[] sum, int start, int mid, int end, long[] temp) {\n        int right = mid + 1;\n        int index = start;\n        int low = mid + 1, high = mid + 1;\n        for (int left = start; left <= mid; left++) {\n            while (low <= end && sum[low] - sum[left] < lower) {\n                low++;\n            }\n            while (high <= end && sum[high] - sum[left] <= upper) {\n                high++;\n            }\n            while (right <= end && sum[right] < sum[left]) {\n                temp[index++] = sum[right++];\n            }\n            temp[index++] = sum[left];\n            count += high - low;\n        }\n        while (right <= end) {\n            temp[index++] = sum[right++];\n        }\n\n        for (int i = start; i <= end; i++) {\n            sum[i] = temp[i];\n        }\n    }\n\n\n\n}\n"
  },
  {
    "path": "src/CountOfSmallerNumbersAfterSelf315.java",
    "content": "/**\n * You are given an integer array nums and you have to return a new counts array.\n * The counts array has the property where counts[i] is the number of smaller\n * elements to the right of nums[i].\n *\n * Example:\n *\n * Given nums = [5, 2, 6, 1]\n *\n * To the right of 5 there are 2 smaller elements (2 and 1).\n * To the right of 2 there is only 1 smaller element (1).\n * To the right of 6 there is 1 smaller element (1).\n * To the right of 1 there is 0 smaller element.\n *\n * Return the array [2, 1, 1, 0].\n *\n */\n\n\npublic class CountOfSmallerNumbersAfterSelf315 {\n    // brutal force method, Time Limit Exceeded\n    public List<Integer> countSmaller(int[] nums) {\n        List<Integer> res = new ArrayList<>(nums.length);\n        for (int i=0; i<nums.length; i++) {\n            int now = nums[i];\n            int count = 0;\n            for (int j=i+1; j<nums.length; j++) {\n                if (nums[j] < now) {\n                    count++;\n                }\n            }\n            res.set(i, count);\n        }\n        return res;\n    }\n\n    // another method, Time Limit Exceeded\n    public List<Integer> countSmaller2(int[] nums) {\n        if (nums.length == 0) {\n            return new ArrayList<Integer>();\n        }\n        LinkedList<Integer> res = new LinkedList<>();\n        res.add(0);\n        ListNode head = new ListNode(nums[nums.length-1]);\n        for (int i=nums.length-2; i>=0; i--) {\n            ListNode newNode = new ListNode(nums[i]);\n            int count = 0;\n            ListNode temp = head;\n            if (nums[i] <= temp.val) {\n                newNode.next = temp;\n                head = newNode;\n                res.addFirst(count);\n                continue;\n            }\n            while (temp.next != null && nums[i] > temp.next.val) {\n                temp = temp.next;\n                count++;\n            }\n            if (temp.next == null) {\n                temp.next = newNode;\n            } else {\n                newNode.next = temp.next;\n                temp.next = newNode;\n            }\n            count++;\n            res.addFirst(count);\n        }\n        return res;\n    }\n\n\n    public List<Integer> countSmaller3(int[] nums) {\n\n        Integer[] count = new Integer[nums.length];\n\n        int[][] arr = new int[nums.length][2];\n        for (int i=0; i<nums.length; i++) {\n            arr[i][0] = i;\n            arr[i][1] = nums[i];\n            count[i] = 0;\n        }\n\n        mergeSort(arr, count, 0, nums.length-1);\n\n        return Arrays.asList(count);\n    }\n\n    private void mergeSort(int[][] arr, Integer[] count, int l, int r) {\n        if (l >= r) return;\n\n        int m = (l+r)/2;\n        mergeSort(arr, count, l, m);\n        mergeSort(arr, count, m+1, r);\n\n        merge(arr, count, l, m, r);\n    }\n\n    private void merge(int[][] arr, Integer[] count, int l, int m, int r) {\n        int len1 = m - l + 1;\n        int len2 = r - m;\n\n        int[][] L = new int [len1][2];\n        int[][] R = new int [len2][2];\n\n        for (int i=0; i < len1; i++)\n            L[i] = arr[l + i];\n        for (int j=0; j < len2; j++)\n            R[j] = arr[m + 1 + j];\n\n        int i = 0;\n        int j = 0;\n        int k = l;\n        while (i < len1 && j < len2) {\n            if (L[i][1] <= R[j][1]) {\n                arr[k] = L[i];\n                count[L[i][0]] += j;\n                i++;\n            } else {\n                arr[k] = R[j];\n                j++;\n            }\n            k++;\n        }\n\n        while (i < len1) {\n            arr[k] = L[i];\n            i++;\n            k++;\n        }\n\n        while (j < len2) {\n            arr[k] = R[j];\n            j++;\n            k++;\n        }\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/31405/9ms-short-java-bst-solution-get-answer-when-building-bst\n     */\n    public List<Integer> countSmaller4(int[] nums) {\n        Integer[] ans = new Integer[nums.length];\n        Node root = null;\n        for (int i = nums.length - 1; i >= 0; i--) {\n            root = insert(nums[i], root, ans, i, 0);\n        }\n        return Arrays.asList(ans);\n    }\n\n    private Node insert(int num, Node node, Integer[] ans, int i, int preSum) {\n        if (node == null) {\n            node = new Node(num, 0);\n            ans[i] = preSum;\n        } else if (node.val == num) {\n            node.dup++;\n            ans[i] = preSum + node.sum;\n        } else if (node.val > num) {\n            node.sum++;\n            node.left = insert(num, node.left, ans, i, preSum);\n        } else {\n            node.right = insert(num, node.right, ans, i, preSum + node.dup + node.sum);\n        }\n        return node;\n    }\n\n    class Node {\n        Node left, right;\n        int val, sum, dup = 1;\n        public Node(int v, int s) {\n            val = v;\n            sum = s;\n        }\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/31173/my-simple-ac-java-binary-search-code\n     */\n    public List<Integer> countSmaller5(int[] nums) {\n        Integer[] ans = new Integer[nums.length];\n        List<Integer> sorted = new ArrayList<Integer>();\n        for (int i = nums.length - 1; i >= 0; i--) {\n            int index = findIndex(sorted, nums[i]);\n            ans[i] = index;\n            sorted.add(index, nums[i]);\n        }\n        return Arrays.asList(ans);\n    }\n\n    private int findIndex(List<Integer> sorted, int target) {\n        if (sorted.size() == 0) return 0;\n        int start = 0;\n        int end = sorted.size() - 1;\n        if (sorted.get(end) < target) return end + 1;\n        if (sorted.get(start) >= target) return 0;\n        while (start + 1 < end) {\n            int mid = start + (end - start) / 2;\n            if (sorted.get(mid) < target) {\n                start = mid + 1;\n            } else {\n                end = mid;\n            }\n        }\n        if (sorted.get(start) >= target) return start;\n        return end;\n    }\n\n\n    public List<Integer> countSmaller6(int[] nums) {\n        LinkedList<Integer> res = new LinkedList<>();\n        if (nums == null || nums.length == 0) return res;\n        int N = nums.length;\n        int min = Integer.MAX_VALUE;\n        int max = Integer.MIN_VALUE;\n        for (int n: nums) {\n            min = Math.min(min, n);\n        }\n        int[] ranks = new int[N];\n        for (int i = 0; i < N; i++) {\n            ranks[i] = nums[i] - min + 1;\n            max = Math.max(ranks[i], max);\n        }\n\n        BinaryIndexedTree bit = new BinaryIndexedTree(max);\n        for (int i=ranks.length-1; i>=0 ;i--) {\n            res.addFirst(bit.query(ranks[i] - 1));\n            bit.update(ranks[i], 1);\n        }\n        return res;\n    }\n\n    class BinaryIndexedTree {\n        int[] tree;\n        int N;\n\n        BinaryIndexedTree(int N) {\n            this.N = N;\n            this.tree = new int[N+1];\n        }\n\n        void update(int i, int delta) {\n            int k = i + 1;\n            while (k <= this.N) {\n                this.tree[k] += delta;\n                k += lowBit(k);\n            }\n        }\n\n        int query(int i) {\n            int k = i + 1;\n            int res = 0;\n            while (k > 0) {\n                res += this.tree[k];\n                k -= lowBit(k);\n            }\n            return res;\n        }\n\n        private int lowBit(int x) {\n            return x & (-x);\n        }\n    }\n\n\n    public List<Integer> countSmaller7(int[] nums) {\n        LinkedList<Integer> res = new LinkedList<>();\n        if (nums == null || nums.length == 0) return res;\n        int N = nums.length;\n        Node root = new Node(nums[N-1]);\n        res.add(0);\n        for (int i=N-2; i>=0; i--) {\n            res.addFirst(insert(root, nums[i]));\n        }\n        return res;\n    }\n\n    private int insert(Node root, int val) {\n        if (root.val == val) {\n            root.count++;\n            return root.leftCount;\n        } else if (root.val > val) {\n            root.leftCount++;\n            if (root.left == null) {\n                root.left = new Node(val);\n                return 0;\n            }\n            return insert(root.left, val);\n        } else {\n            if (root.right == null) {\n                root.right = new Node(val);\n                return root.count + root.leftCount;\n            }\n            return root.count + root.leftCount + insert(root.right, val);\n        }\n        \n    }\n\n    class Node {\n        Node left;\n        Node right;\n        int val;\n        int count = 1;\n        int leftCount = 0;\n        Node(int v) {\n            this.val = v;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/CountPrimes204.java",
    "content": "/**\n * Description:\n *\n * Count the number of prime numbers less than a non-negative number, n.\n */\n\n\npublic class CountPrimes204 {\n    public int countPrimes(int n) {\n        boolean[] notPrime = new boolean[n];\n        int count = 0;\n        for (int i = 2; i < n; i++) {\n            if (notPrime[i] == false) {\n                count++;\n                for (int j = 2; i*j < n; j++) {\n                    notPrime[i*j] = true;\n                }\n            }\n        }\n\n        return count;\n    }\n}\n"
  },
  {
    "path": "src/CountingBits338.java",
    "content": "/**\n * Given a non negative integer number num. For every numbers i in the range\n * 0 ≤ i ≤ num calculate the number of 1's in their binary representation and\n * return them as an array.\n *\n * Example:\n * For num = 5 you should return [0,1,1,2,1,2].\n *\n * Follow up:\n *      It is very easy to come up with a solution with run time\n *      O(n*sizeof(integer)). But can you do it in linear time O(n) /possibly\n *      in a single pass?\n *\n *      Space complexity should be O(n).\n *\n *      Can you do it like a boss? Do it without using any builtin function\n *      like __builtin_popcount in c++ or in any other language.\n */\n\n\npublic class CountingBits338 {\n    public int[] countBits(int num) {\n        if (num == 0) return new int[]{0};\n        if (num == 1) return new int[]{0, 1};\n\n        int[] r = new int[num+1];\n        r[0] = 0;\n        r[1] = 1;\n\n        int i = 2;\n        while (i <= num) {\n            for (int j = 0; j<i && i+j<=num; j++) {\n                r[i+j] = r[j] + 1;\n            }\n            i = i*2;\n        }\n\n        return r;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/40162/three-line-java-solution\n     */\n    public int[] countBits(int num) {\n        int[] f = new int[num + 1];\n        for (int i=1; i<=num; i++) f[i] = f[i >> 1] + (i & 1);\n        return f;\n    }\n\n}\n"
  },
  {
    "path": "src/CouplesHoldingHands765.java",
    "content": "/**\n * N couples sit in 2N seats arranged in a row and want to hold hands. We want\n * to know the minimum number of swaps so that every couple is sitting side by\n * side. A swap consists of choosing any two people, then they stand up and\n * switch seats.\n *\n * The people and seats are represented by an integer from 0 to 2N-1, the\n * couples are numbered in order, the first couple being (0, 1), the second\n * couple being (2, 3), and so on with the last couple being (2N-2, 2N-1).\n *\n * The couples' initial seating is given by row[i] being the value of the\n * person who is initially sitting in the i-th seat.\n *\n * Example 1:\n *\n * Input: row = [0, 2, 1, 3]\n * Output: 1\n * Explanation: We only need to swap the second (row[1]) and third (row[2]) person.\n *\n *\n * Example 2:\n *\n * Input: row = [3, 2, 0, 1]\n * Output: 0\n * Explanation: All couples are already seated side by side.\n *\n * Note:\n * len(row) is even and in the range of [4, 60].\n * row is guaranteed to be a permutation of 0...len(row)-1.\n */\n\n\n/**\n * https://leetcode.com/problems/couples-holding-hands/discuss/113362/JavaC++-O(N)-solution-using-cyclic-swapping\n */\n\npublic class CouplesHoldingHands765 {\n    public int minSwapsCouples(int[] row) {\n        int n = row.length;\n        int[] pos = new int[n];\n        for (int i = 0; i < n; i++) pos[row[i]] = i;\n\n        int count = 0;\n        for (int i = 0; i < n; i += 2) {\n            int j = row[i] % 2 == 0 ? row[i] + 1 : row[i] - 1;\n            if (row[i + 1] != j) {\n                swap(row, i + 1, pos[j]);\n                swap(pos, row[i + 1], row[pos[j]]);\n                count++;\n            }\n        }\n        return count;\n    }\n\n    private void swap(int[] arr, int i, int j) {\n        int temp = arr[i];\n        arr[i] = arr[j];\n        arr[j] = temp;\n    }\n\n}\n"
  },
  {
    "path": "src/CourseSchedule207.java",
    "content": "/**\n * There are a total of n courses you have to take, labeled from 0 to n - 1.\n *\n * Some courses may have prerequisites, for example to take course 0 you have\n * to first take course 1, which is expressed as a pair: [0,1]\n *\n * Given the total number of courses and a list of prerequisite pairs, is it\n * possible for you to finish all courses?\n *\n * For example:\n *\n * 2, [[1,0]]\n * There are a total of 2 courses to take. To take course 1 you should have\n * finished course 0. So it is possible.\n *\n * 2, [[1,0],[0,1]]\n * There are a total of 2 courses to take. To take course 1 you should have\n * finished course 0, and to take course 0 you should also have finished\n * course 1. So it is impossible.\n *\n * Note:\n * The input prerequisites is a graph represented by a list of edges, not\n * adjacency matrices. Read more about how a graph is represented.\n *\n * You may assume that there are no duplicate edges in the input prerequisites.\n *\n * Hints:\n * This problem is equivalent to finding if a cycle exists in a directed graph.\n * If a cycle exists, no topological ordering exists and therefore it will be\n * impossible to take all courses.\n *\n * Topological Sort via DFS - A great video tutorial (21 minutes) on Coursera\n * explaining the basic concepts of Topological Sort.\n *\n * Topological sort could also be done via BFS.\n *\n */\n\n\npublic class CourseSchedule207 {\n    public boolean canFinish(int numCourses, int[][] prerequisites) {\n        Map<Integer, Set<Integer>> graph = initGraph(prerequisites);\n        Set<Integer> visited = new HashSet<>();\n\n        for (int i=0; i<numCourses; i++) {\n            if (graph.containsKey(i) && !visited.contains(i) && !dfs(graph, visited, new HashSet<>(), i)) return false;\n        }\n\n        return true;\n    }\n\n    private boolean dfs(Map<Integer, Set<Integer>> graph, Set<Integer> visited, Set<Integer> onStack, Integer pre) {\n        if (onStack.contains(pre)) return false;\n        visited.add(pre);\n        onStack.add(pre);\n        if (!graph.containsKey(pre)) return true;\n\n        Set<Integer> adj = graph.get(pre);\n        for (Integer curr: adj) {\n            if (graph.containsKey(curr) && !dfs(graph, visited, onStack, curr)) return false;\n        }\n        onStack.remove(pre);\n        return true;\n    }\n\n    private Map<Integer, Set<Integer>> initGraph(int[][] prerequisites) {\n        Map<Integer, Set<Integer>> graph = new HashMap<>();\n        for (int[] p: prerequisites) {\n            addEdge(graph, p);\n        }\n        return graph;\n    }\n\n    private void addEdge(Map<Integer, Set<Integer>> graph, int[] p) {\n        Set<Integer> adj = graph.getOrDefault(p[1], new HashSet<>());\n        adj.add(p[0]);\n        graph.put(p[1], adj);\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/15762/java-dfs-and-bfs-solution\n     */\n    public boolean canFinish2s(int numCourses, int[][] prerequisites) {\n        ArrayList[] graph = new ArrayList[numCourses];\n        int[] degree = new int[numCourses];\n        Queue queue = new LinkedList();\n        int count=0;\n\n        for(int i=0;i<numCourses;i++)\n            graph[i] = new ArrayList();\n\n        for(int i=0; i<prerequisites.length;i++){\n            degree[prerequisites[i][1]]++;\n            graph[prerequisites[i][0]].add(prerequisites[i][1]);\n        }\n        for(int i=0; i<degree.length;i++){\n            if(degree[i] == 0){\n                queue.add(i);\n                count++;\n            }\n        }\n\n        while(queue.size() != 0){\n            int course = (int)queue.poll();\n            for(int i=0; i<graph[course].size();i++){\n                int pointer = (int)graph[course].get(i);\n                degree[pointer]--;\n                if(degree[pointer] == 0){\n                    queue.add(pointer);\n                    count++;\n                }\n            }\n        }\n        if(count == numCourses)\n            return true;\n        else\n            return false;\n    }\n\n\n    /**\n     * Kahn’s algorithm for Topological Sorting\n     * https://www.geeksforgeeks.org/topological-sorting-indegree-based-solution/\n     */\n    public boolean canFinish3(int numCourses, int[][] prerequisites) {\n        int[] indegree = new int[numCourses];\n        Set<Integer>[] graph = new Set[numCourses];\n        for (int[] link: prerequisites) {\n            if (graph[link[1]] == null) graph[link[1]] = new HashSet<Integer>();\n            graph[link[1]].add(link[0]);\n            indegree[link[0]]++;\n        }\n\n        Queue<Integer> q = new LinkedList<>();\n        for (int i=0; i<numCourses; i++) {\n            if (indegree[i] == 0) q.add(i);\n        }\n\n        int count = 0;\n        while (!q.isEmpty()) {\n            int curr = q.poll();\n            if (graph[curr] == null) {\n                count++;\n                continue;\n            }\n            for (int next: graph[curr]) {\n                indegree[next]--;\n                if (indegree[next] == 0) q.add(next);\n            }\n            count++;\n        }\n        return count == numCourses;\n    }\n\n\n    public boolean canFinish4(int numCourses, int[][] prerequisites) {\n        Set<Integer>[] graph = new Set[numCourses];\n        for (int[] link: prerequisites) {\n            if (graph[link[1]] == null) graph[link[1]] = new HashSet<Integer>();\n            graph[link[1]].add(link[0]);\n        }\n        return !isCyclic(graph, numCourses);\n    }\n\n    private boolean isCyclic(Set<Integer>[] graph, int numCourses) {\n        boolean[] visited = new boolean[numCourses];\n        boolean[] trace = new boolean[numCourses];\n        for (int i=0; i<numCourses; i++) {\n            if (isCyclic(graph, i, visited, trace)) return true;\n        }\n        return false;\n    }\n\n    private boolean isCyclic(Set<Integer>[] graph, int start, boolean[] visited, boolean[] trace) {\n        if (trace[start]) return true;\n        if (visited[start]) return false;\n\n        visited[start] = true;\n        if (graph[start] == null) return false;\n\n        trace[start] = true;\n        for (int next: graph[start]) {\n            if (isCyclic(graph, next, visited, trace)) return true;\n        }\n        trace[start] = false;\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "src/CourseScheduleII210.java",
    "content": "/**\n * There are a total of n courses you have to take, labeled from 0 to n - 1.\n *\n * Some courses may have prerequisites, for example to take course 0 you have\n * to first take course 1, which is expressed as a pair: [0,1]\n *\n * Given the total number of courses and a list of prerequisite pairs, return\n * the ordering of courses you should take to finish all courses.\n *\n * There may be multiple correct orders, you just need to return one of them.\n * If it is impossible to finish all courses, return an empty array.\n *\n * For example:\n *\n * 2, [[1,0]]\n * There are a total of 2 courses to take. To take course 1 you should have\n * finished course 0. So the correct course order is [0,1]\n *\n * 4, [[1,0],[2,0],[3,1],[3,2]]\n * There are a total of 4 courses to take. To take course 3 you should have\n * finished both courses 1 and 2. Both courses 1 and 2 should be taken after\n * you finished course 0. So one correct course order is [0,1,2,3]. Another\n * correct ordering is[0,2,1,3].\n *\n * Note:\n * The input prerequisites is a graph represented by a list of edges, not\n * adjacency matrices. Read more about how a graph is represented.\n *\n * You may assume that there are no duplicate edges in the input prerequisites.\n *\n * Hints:\n * This problem is equivalent to finding the topological order in a directed\n * graph. If a cycle exists, no topological ordering exists and therefore it\n * will be impossible to take all courses.\n *\n * Topological Sort via DFS - A great video tutorial (21 minutes) on Coursera\n * explaining the basic concepts of Topological Sort.\n *\n * Topological sort could also be done via BFS.\n *\n */\n\n\npublic class CourseScheduleII210 {\n    public int[] findOrder(int numCourses, int[][] prerequisites) {\n        Set<Integer>[] graph = new Set[numCourses];\n        for (int[] link: prerequisites) {\n            int src = link[1];\n            int dst = link[0];\n            if (graph[src] == null) graph[src] = new HashSet<>();\n            graph[src].add(dst);\n        }\n\n        int[] order = new int[numCourses];\n        boolean[] visited = new boolean[numCourses];\n        int[] idx = new int[]{numCourses - 1};\n        for (int i=0; i<numCourses; i++) {\n            if (!visited[i]) {\n                if (!helper(graph, i, numCourses, new boolean[numCourses], visited, idx, order)) {\n                    return new int[0];\n                }\n            }\n        }\n        return order;\n    }\n\n    private boolean helper(Set<Integer>[] graph, int curr, int numCourses, boolean[] path, boolean[] visited, int[] idx, int[] order) {\n        if (path[curr]) return false;\n        if (visited[curr]) return true;\n        visited[curr] = true;\n        path[curr] = true;\n        if (graph[curr] != null) {\n            for (int next: graph[curr]) {\n                if (!helper(graph, next, numCourses, path, visited, idx, order)) return false;\n            }\n        }\n        path[curr] = false;\n        order[idx[0]--] = curr;\n        return true;\n    }\n\n\n    public int[] findOrder2(int numCourses, int[][] prerequisites) {\n        Set<Integer>[] graph = new Set[numCourses];\n        int[] indegree = new int[numCourses];\n        for (int[] link: prerequisites) {\n            int src = link[1];\n            int dst = link[0];\n            indegree[dst]++;\n            if (graph[src] == null) graph[src] = new HashSet<>();\n            graph[src].add(dst);\n        }\n\n        Queue<Integer> q = new LinkedList<>();\n        for (int i=0; i<numCourses; i++) {\n            if (indegree[i] == 0) q.add(i);\n        }\n        if (q.isEmpty()) return new int[0];\n\n        int[] order = new int[numCourses];\n        int i = 0;\n        while (!q.isEmpty()) {\n            int curr = q.poll();\n            order[i++] = curr;\n            if (graph[curr] == null) continue;\n            for (int next: graph[curr]) {\n                indegree[next]--;\n                if (indegree[next] == 0) q.add(next);\n            }\n        }\n        return i == numCourses ? order : new int[0];\n    }\n\n}\n"
  },
  {
    "path": "src/CutOffTreesForGolfEvent675.java",
    "content": "/**\n * You are asked to cut off trees in a forest for a golf event. The forest is\n * represented as a non-negative 2D map, in this map:\n *\n * 0 represents the obstacle can't be reached.\n * 1 represents the ground can be walked through.\n *\n * The place with number bigger than 1 represents a tree can be walked through,\n * and this positive number represents the tree's height.\n *\n * You are asked to cut off all the trees in this forest in the order of tree's\n * height - always cut off the tree with lowest height first. And after cutting,\n * the original place has the tree will become a grass (value 1).\n *\n * You will start from the point (0, 0) and you should output the minimum steps\n * you need to walk to cut off all the trees. If you can't cut off all the trees,\n * output -1 in that situation.\n *\n * You are guaranteed that no two trees have the same height and there is at\n * least one tree needs to be cut off.\n *\n * Example 1:\n * Input:\n * [\n *  [1,2,3],\n *  [0,0,4],\n *  [7,6,5]\n * ]\n * Output: 6\n *\n * Example 2:\n * Input:\n * [\n *  [1,2,3],\n *  [0,0,0],\n *  [7,6,5]\n * ]\n * Output: -1\n *\n * Example 3:\n * Input:\n * [\n *  [2,3,4],\n *  [0,0,5],\n *  [8,7,6]\n * ]\n * Output: 6\n *\n * Explanation: You started from the point (0,0) and you can cut off the tree in (0,0) directly without walking.\n *\n * Hint: size of the given matrix will not exceed 50x50.\n *\n */\n\n\npublic class CutOffTreesForGolfEvent675 {\n    private int[][] directions = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};\n    public int cutOffTree(List<List<Integer>> forest) {\n        if (forest == null || forest.size() == 0) return 0;\n        PriorityQueue<TreePoint> pq = new PriorityQueue<>(1, Comparator.comparingInt(p -> p.h));\n        int M = forest.size();\n        int N = forest.get(0).size();\n        int[][] golf = new int[M][N];\n        int i = 0;\n        for (List<Integer> level: forest) {\n            int j = 0;\n            for (Integer pos: level) {\n                if (pos > 1) {\n                    pq.add(new TreePoint(i, j, pos));\n                }\n                golf[i][j] = pos;\n                j++;\n            }\n            i++;\n        }\n\n        Point pre = new Point(0, 0);\n        int res = 0;\n        \n        while (pq.size() > 0) {\n            TreePoint t = pq.poll();\n            Point dest = new Point(t.x, t.y);\n            int d = minDistance(golf, pre, dest, M, N);\n            if (d == -1) return -1;\n            res += d;\n            golf[t.x][t.y] = 1;\n            pre = dest;\n        }\n        \n        return res;\n    }\n\n    private int minDistance(int[][] golf, Point start, Point end, int M, int N) {\n        if (start.x == end.x && start.y == end.y) return 0;\n        Queue<Point> q = new LinkedList<>();\n        q.add(start);\n        boolean[][] visited = new boolean[M][N];\n        visited[start.x][start.y] = true;\n        int dist = 0;\n        while (!q.isEmpty()) {\n            int size = q.size();\n            for (int i =0; i<size; i++) {\n                Point curr = q.poll();\n                if (curr.x == end.x && curr.y == end.y) return dist;\n                for (int[] d: directions) {\n                    int x = curr.x + d[0];\n                    int y = curr.y + d[1];\n                    if (x == end.x && y == end.y) return dist + 1;\n                    if (x >= 0 && y >= 0 && x < M && y < N && !visited[x][y] && golf[x][y] != 0) {\n                        q.add(new Point(x, y));\n                        visited[x][y] = true;\n                    }\n                }\n            }\n            dist++;\n        }\n        return -1;\n    }\n    \n    class Point {\n        int x;\n        int y;\n        Point(int xx, int yy) {\n            x = xx;\n            y = yy;\n        }\n    }\n\n    class TreePoint {\n        int x;\n        int y;\n        int h;\n        TreePoint(int xx, int yy, int hh) {\n            x = xx;\n            y = yy;\n            h = hh;\n        }\n    }\n\n\n\n}\n"
  },
  {
    "path": "src/DailyTemperatures739.java",
    "content": "/**\n * Given a list of daily temperatures, produce a list that, for each day in the\n * input, tells you how many days you would have to wait until a warmer\n * temperature. If there is no future day for which this is possible,\n * put 0 instead.\n * \n * For example, given the list temperatures = [73, 74, 75, 71, 69, 72, 76, 73],\n * your output should be [1, 1, 4, 2, 1, 1, 0, 0].\n * \n * Note: The length of temperatures will be in the range [1, 30000]. Each\n * temperature will be an integer in the range [30, 100].\n */\n\npublic class DailyTemperatures739 {\n    public int[] dailyTemperatures(int[] temperatures) {\n        if (temperatures == null || temperatures.length == 0) return new int[0];\n        int N = temperatures.length;\n        int[] res  = new int[N];\n        Map<Integer, Integer> map = new HashMap<>();\n        LinkedList<Integer> list = new LinkedList<>();\n        for (int i=N-1; i>=0; i--) {\n            int curr = temperatures[i];\n            while (!list.isEmpty() && list.getFirst() <= curr) {\n                list.removeFirst();\n            }\n            if (!list.isEmpty()) {\n                res[i] = map.get(list.getFirst()) - i;\n            }\n            list.addFirst(curr);\n            map.put(curr, i);\n        }\n        return res;\n    }\n\n\n    public int[] dailyTemperatures2(int[] temperatures) {\n        if (temperatures == null || temperatures.length == 0) return new int[0];\n        Stack<Integer> stack = new Stack<>();\n        \n        int N = temperatures.length;\n        int[] res = new int[N];\n        for (int i=N-1; i>=0; i--) {\n            while (!stack.isEmpty() && temperatures[i] >= temperatures[stack.peek()]) {\n                stack.pop();\n            }\n            res[i] = stack.isEmpty() ? 0 : (stack.peek() - i);\n            stack.push(i);\n        }\n        \n        return res;\n    }\n\n\n    public int[] dailyTemperatures3(int[] temperatures) {\n        int[] stack = new int[temperatures.length];\n        int top = -1;\n        int[] ret = new int[temperatures.length];\n        for(int i = 0; i < temperatures.length; i++) {\n            while(top > -1 && temperatures[i] > temperatures[stack[top]]) {\n                int idx = stack[top--];\n                ret[idx] = i - idx;\n            }\n            stack[++top] = i;\n        }\n        return ret;\n    }\n\n}\n"
  },
  {
    "path": "src/DataStreamAsDisjointIntervals352.java",
    "content": "/**\n * Given a data stream input of non-negative integers a1, a2, ..., an, ...,\n * summarize the numbers seen so far as a list of disjoint intervals.\n * \n * For example, suppose the integers from the data stream are 1, 3, 7, 2, 6, ...,\n * then the summary will be:\n * \n * [1, 1]\n * [1, 1], [3, 3]\n * [1, 1], [3, 3], [7, 7]\n * [1, 3], [7, 7]\n * [1, 3], [6, 7]\n * \n * Follow up:\n * What if there are lots of merges and the number of disjoint intervals are\n * small compared to the data stream's size?\n */\n\n/**\n * Definition for an interval.\n * public class Interval {\n *     int start;\n *     int end;\n *     Interval() { start = 0; end = 0; }\n *     Interval(int s, int e) { start = s; end = e; }\n * }\n */\n\npublic class DataStreamAsDisjointIntervals352 {\n    class SummaryRanges {\n        private TreeMap<Integer, Integer> ranges = new TreeMap<>();\n\n        /** Initialize your data structure here. */\n        public SummaryRanges() {\n        }\n\n        public void addNum(int val) {\n            Map.Entry<Integer, Integer> ceiling = ranges.ceilingEntry(val);\n            Map.Entry<Integer, Integer> floor = ranges.floorEntry(val);\n            if (floor == null && ceiling == null) {\n                ranges.put(val, val);\n            } else if (floor == null) {\n                if (val + 1 < ceiling.getKey()) {\n                    ranges.put(val, val);\n                } else if (val + 1 == ceiling.getKey()) {\n                    ranges.remove(ceiling.getKey());\n                    ranges.put(val, ceiling.getValue());\n                }\n            } else if (ceiling == null) {\n                if (val > floor.getValue() + 1) {\n                    ranges.put(val, val);\n                } else if (val == floor.getValue() + 1) {\n                    ranges.put(floor.getKey(), val);\n                }\n            } else {\n                if (val <= floor.getValue() || val >= ceiling.getKey()) return;\n                if (val > floor.getValue() + 1 && val + 1 < ceiling.getKey()) {\n                    ranges.put(val, val);\n                } else if (val == floor.getValue() + 1 && val + 1 == ceiling.getKey()) {\n                    ranges.remove(ceiling.getKey());\n                    ranges.put(floor.getKey(), ceiling.getValue());\n                } else if (val == floor.getValue() + 1) {\n                    ranges.put(floor.getKey(), val);\n                } else if (val + 1 == ceiling.getKey()) {\n                    ranges.remove(ceiling.getKey());\n                    ranges.put(val, ceiling.getValue());\n                }\n            }\n        }\n\n        public List<Interval> getIntervals() {\n            List<Interval> res = new ArrayList<>();\n            for (Map.Entry<Integer, Integer> e: ranges.entrySet()) {\n                res.add(new Interval(e.getKey(), e.getValue()));\n            }\n            return res;\n        }\n    }\n\n\n    class SummaryRanges2 {\n        private Node root;\n\n        /** Initialize your data structure here. */\n        public SummaryRanges2() {\n        }\n\n        public void addNum(int val) {\n            if (this.root == null) {\n                this.root = addNode(this.root, val);\n                return;\n            }\n\n            Node c = findNode(this.root, val);\n            if (c != null) return;\n            Node l = findNode(this.root, val - 1);\n            Node r = findNode(this.root, val + 1);\n            \n            if (l == null && r == null) {\n                this.root = addNode(this.root, val);\n            } else if (l == null) {\n                r.inv.start = val;\n            } else if (r == null) {\n                l.inv.end = val;\n            } else {\n                int newEnd = r.inv.end;\n                this.root = remove(this.root, r.inv);\n                l.inv.end = newEnd;\n            }\n        }\n\n        private Node remove(Node node, Interval inv) {\n            if (node == null) return null;\n            if (inv.end < node.inv.start) {\n                node.left = remove(node.left, inv);;\n            } else if (inv.start > node.inv.end) {\n                node.right = remove(node.right, inv);\n            } else {\n                if (node.left == null) return node.right;\n                else if (node.right == null) return node.left;\n                node.inv = findMin(node.right).inv;\n                node.right = remove(node.right, node.inv);\n            }\n            return node;\n        }\n\n        private Node findMin(Node node) {\n            if (node == null || node.left == null) return node;\n            return findMin(node.left);\n        }\n\n        private Node findNode(Node node, int val) {\n            if (node == null || node.inv.start <= val && val <= node.inv.end) return node;\n            if (val < node.inv.start) return findNode(node.left, val);\n            return findNode(node.right, val);\n        }\n\n        private Node addNode(Node node, int val) {\n            if (node == null) return new Node(new Interval(val, val));\n            if (node.inv.start <= val && val <= node.inv.end) return node;\n            if (val < node.inv.start) node.left = addNode(node.left, val);\n            else if (node.inv.end < val) node.right = addNode(node.right, val);\n            return node;\n        }\n\n        public List<Interval> getIntervals() {\n            List<Interval> res = new ArrayList<>();\n            inorder(this.root, res);\n            return res;\n        }\n\n        private void inorder(Node node, List<Interval> res) {\n            if (node == null) return;\n            inorder(node.left, res);\n            res.add(node.inv);\n            inorder(node.right, res);\n        }\n    }\n\n    class Node {\n        Node left;\n        Node right;\n        Interval inv;\n        Node(Interval inv) {\n            this.inv = inv;\n        }\n    }\n\n\n/**\n* Your SummaryRanges object will be instantiated and called as such:\n* SummaryRanges obj = new SummaryRanges();\n* obj.addNum(val);\n* List<Interval> param_2 = obj.getIntervals();\n*/\n\n}\n"
  },
  {
    "path": "src/DecodeString394.java",
    "content": "/**\n * Given an encoded string, return it's decoded string.\n *\n * The encoding rule is: k[encoded_string], where the encoded_string inside the\n * square brackets is being repeated exactly k times. Note that k is guaranteed\n * to be a positive integer.\n *\n * You may assume that the input string is always valid; No extra white spaces,\n * square brackets are well-formed, etc.\n *\n * Furthermore, you may assume that the original data does not contain any\n * digits and that digits are only for those repeat numbers, k. For example,\n * there won't be input like 3a or 2[4].\n *\n * Examples:\n *\n * s = \"3[a]2[bc]\", return \"aaabcbc\".\n * s = \"3[a2[c]]\", return \"accaccacc\".\n * s = \"2[abc]3[cd]ef\", return \"abcabccdcdcdef\".\n *\n */\n\n\npublic class DecodeString394 {\n    public String decodeString(String s) {\n        StringBuilder sb = new StringBuilder(\"\");\n\n        int i = 0;\n        StringBuilder num = new StringBuilder(\"\");\n        while (i < s.length()) {\n            char c = s.charAt(i);\n            if (c >= '0' && c <= '9') {\n                num.append(c);\n                i++;\n                continue;\n            }\n\n            if (c == '[') {\n                Res res = decodeString(s, i);\n                int next = res.next;\n                String in = res.in;\n                for (int j = 0; j<Integer.parseInt(num.toString()); j++) {\n                    sb.append(in);\n                }\n                num = new StringBuilder(\"\");\n                i = next;\n                continue;\n            }\n\n            if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {\n                sb.append(c);\n                i++;\n                continue;\n            }\n\n        }\n\n        return sb.toString();\n    }\n\n    public Res decodeString(String s, int start) {\n        StringBuilder sb = new StringBuilder(\"\");\n\n        int i = start+1;\n        StringBuilder num = new StringBuilder(\"\");\n        while (i < s.length()) {\n            char c = s.charAt(i);\n            if (c >= '0' && c <= '9') {\n                num.append(c);\n                i++;\n                continue;\n            }\n\n            if (c == '[') {\n                Res res = decodeString(s, i);\n                int next = res.next;\n                String in = res.in;\n                for (int j = 0; j<Integer.parseInt(num.toString()); j++) {\n                    sb.append(in);\n                }\n                num = new StringBuilder(\"\");\n                i = next;\n                continue;\n            }\n\n            if (c == ']') {\n                return new Res(i+1, sb.toString());\n            }\n\n            if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {\n                sb.append(c);\n                i++;\n                continue;\n            }\n\n        }\n        return new Res(i+1, sb.toString());\n    }\n\n    class Res {\n        int next;\n        String in;\n        Res (int next, String in) {\n            this.next = next;\n            this.in = in;\n        }\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/57318/java-simple-recursive-solution\n     */\n    public String decodeString2(String s) {\n        if (s.length() == 0) return \"\";\n        StringBuilder sb = new StringBuilder();\n        for (int i = 0; i < s.length(); i ++) {\n            char c = s.charAt(i);\n            if (Character.isDigit(c)) {\n                int digit_begin = i;\n                while (s.charAt(i) != '[') i++;\n                int num = Integer.valueOf(s.substring(digit_begin, i));\n                int count = 1;\n                int str_begin = i+1;\n                i ++;\n                while (count != 0) {\n                    if (s.charAt(i) == '[') count ++;\n                    else if (s.charAt(i) == ']') count --;\n                    i ++;\n                }\n                i--;\n                String str = decodeString(s.substring(str_begin, i));\n                for (int j = 0; j < num; j ++) {\n                    sb.append(str);\n                }\n            } else {\n                sb.append(c);\n            }\n        }\n        return sb.toString();\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/57159/simple-java-solution-using-stack\n     */\n    public String decodeString3(String s) {\n        String res = \"\";\n        Stack<Integer> countStack = new Stack<>();\n        Stack<String> resStack = new Stack<>();\n        int idx = 0;\n        while (idx < s.length()) {\n            if (Character.isDigit(s.charAt(idx))) {\n                int count = 0;\n                while (Character.isDigit(s.charAt(idx))) {\n                    count = 10 * count + (s.charAt(idx) - '0');\n                    idx++;\n                }\n                countStack.push(count);\n            }\n            else if (s.charAt(idx) == '[') {\n                resStack.push(res);\n                res = \"\";\n                idx++;\n            }\n            else if (s.charAt(idx) == ']') {\n                StringBuilder temp = new StringBuilder (resStack.pop());\n                int repeatTimes = countStack.pop();\n                for (int i = 0; i < repeatTimes; i++) {\n                    temp.append(res);\n                }\n                res = temp.toString();\n                idx++;\n            }\n            else {\n                res += s.charAt(idx++);\n            }\n        }\n        return res;\n    }\n}\n"
  },
  {
    "path": "src/DecodeWays91.java",
    "content": "/**\n * A message containing letters from A-Z is being encoded to numbers using the\n * following mapping:\n *\n * 'A' -> 1\n * 'B' -> 2\n * ...\n * 'Z' -> 26\n * Given an encoded message containing digits, determine the total number of\n * ways to decode it.\n *\n * For example,\n * Given encoded message \"12\", it could be decoded as \"AB\" (1 2) or \"L\" (12).\n *\n * The number of ways decoding \"12\" is 2.\n */\n\n\nimport java.util.Map;\nimport java.util.HashMap;\n\n\npublic class DecodeWays91 {\n    public int numDecodings(String s) {\n        int length = s.length();\n        length = s.length();\n\n        if (length == 0) {\n            return 0;\n        }\n\n        if (s.charAt(0) == '0') {\n            return 0;\n        }\n\n        int[] dp = new int[length + 1];\n        dp[0] = 1;\n        dp[1] = 1;\n\n        boolean isZero = false;\n        for (int i = 2; i <= length; i++) {\n            int n = Integer.valueOf(s.substring(i-2, i));\n\n            if (s.charAt(i - 1) == '0' && (n > 26 || n == 0)) {\n                return 0;\n            } else if (s.charAt(i - 1) == '0') {\n                isZero = true;\n                dp[i] = dp[i - 2];\n            } else if (isZero) {\n                isZero = false;\n                dp[i] = dp[i - 1];\n            } else {\n                isZero = false;\n                dp[i] = dp[i - 1] + ((n > 0 && n <= 26) ? dp[i - 2] : 0);\n            }\n        }\n\n        return dp[length];\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/2562/dp-solution-java-for-reference\n     */\n    public int numDecodings2(String s) {\n        int n = s.length();\n        if (n == 0) return 0;\n\n        int[] memo = new int[n+1];\n        memo[n]  = 1;\n        memo[n-1] = s.charAt(n-1) != '0' ? 1 : 0;\n\n        for (int i = n - 2; i >= 0; i--)\n            if (s.charAt(i) == '0') continue;\n            else memo[i] = (Integer.parseInt(s.substring(i,i+2))<=26) ? memo[i+1]+memo[i+2] : memo[i+1];\n\n        return memo[0];\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/35840/java-clean-dp-solution-with-explanation\n     */\n    public int numDecodings3(String s) {\n        if (s == null || s.length() == 0) {\n            return 0;\n        }\n        int[] ways = new int[s.length() + 1];\n        ways[0] = 1;\n        ways[1] = s.charAt(0) == '0' ? 0 : 1;\n        for (int i = 2; i <= s.length(); i++) {\n            int one = s.charAt(i - 1) - '0';\n            int two = (s.charAt(i - 2) - '0') * 10 + one;\n            if (one != 0) {\n                ways[i] += ways[i - 1];\n            }\n            if (two >= 10 && two <= 26) {\n                ways[i] += ways[i - 2];\n            }\n        }\n        return ways[s.length()];\n    }\n\n\n    public int numDecodings4(String s) {\n        if (s == null || s.length() == 0) return 0;\n        if (s.charAt(0) == '0') return 0;\n        int[] dp = new int[s.length()+1];\n        dp[0] = 1;\n        dp[1] = 1;\n        for (int i=2; i<=s.length(); i++) {\n            int now = s.charAt(i-1) - '0';\n            int prenow = (s.charAt(i-2) - '0')*10 + now;\n            if (now == 0 && prenow != 10 && prenow != 20) return 0;\n            int a = now == 0 ? 0 : dp[i-1];\n            int b = (prenow >= 10 && prenow <= 26) ? dp[i-2] : 0;\n            dp[i] = a + b;\n        }\n\n        return dp[s.length()];\n    }\n\n\n    /**\n     * https://leetcode.com/problems/decode-ways/discuss/30416/Simple-java-solution-with-O(1)-space\n     */\n    public int numDecodings5(String s) {\n        int n1 =1, n2=1, n3=0;\n        if(s.length() == 0 || s.charAt(0) == '0') return 0;\n        for (int i=2; i<=s.length(); i++) {\n            n3=0;\n            if(s.charAt(i-1)!='0') n3=n2;\n            int num = Integer.parseInt(s.substring(i-2,i));\n            if(num>=10 && num<=26) n3+=n1;\n            n1=n2;\n            n2=n3;\n        }\n        return n2;\n    }\n\n}\n"
  },
  {
    "path": "src/DecodeWaysII639.java",
    "content": "/**\n * A message containing letters from A-Z is being encoded to numbers using the\n * following mapping way:\n *\n * 'A' -> 1\n * 'B' -> 2\n * ...\n * 'Z' -> 26\n * Beyond that, now the encoded string can also contain the character '*',\n * which can be treated as one of the numbers from 1 to 9.\n *\n * Given the encoded message containing digits and the character '*', return\n * the total number of ways to decode it.\n *\n * Also, since the answer may be very large, you should return the output mod 109 + 7.\n *\n * Example 1:\n * Input: \"*\"\n * Output: 9\n *\n * Explanation: The encoded message can be decoded to the string:\n * \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\".\n *\n * Example 2:\n * Input: \"1*\"\n * Output: 9 + 9 = 18\n *\n * Note:\n * The length of the input string will fit in range [1, 105].\n * The input string will only contain the character '*' and digits '0' - '9'.\n */\n\n\npublic class DecodeWaysII639 {\n    public int numDecodings(String s) {\n        if (s == null || s.length() == 0) return 0;\n        long[] dp = new long[s.length()+1];\n        dp[0] = 1;\n        dp[1] = s.charAt(0) == '0' ? 0 : (s.charAt(0) == '*' ? 9 : 1);\n        for (int i=2; i<=s.length(); i++) {\n            char c = s.charAt(i-1);\n            char pc = s.charAt(i-2);\n            if (c == '*') {\n                dp[i] += dp[i-1]*9;\n                dp[i] += pc == '*' ? dp[i-2]*15 : (pc == '1' ? dp[i-2]*9 : (pc == '2' ? dp[i-2]*6 : 0));\n            } else {\n                dp[i] += c == '0' ? 0 : dp[i-1];\n                if (pc == '*') {\n                    dp[i] += dp[i-2] * (c <= '6' ? 2 : 1);\n                } else {\n                    int two = (pc - '0') * 10 + (c - '0');\n                    dp[i] += (two >= 10 && two <= 26) ? dp[i-2] : 0;\n                }\n            }\n            dp[i] %= 1000000007;\n        }\n\n        return (int) dp[s.length()];\n    }\n\n\n    public int numDecodings2(String s) {\n        if (s == null || s.length() == 0) return 0;\n        long n0 = 1;\n        long n1 = s.charAt(0) == '0' ? 0 : (s.charAt(0) == '*' ? 9 : 1);\n        long n2 = 0;\n        for (int i=2; i<=s.length(); i++) {\n            n2 = 0;\n            char c = s.charAt(i-1);\n            char pc = s.charAt(i-2);\n            if (c == '*') {\n                n2 += n1*9;\n                n2 += pc == '*' ? n0*15 : (pc == '1' ? n0*9 : (pc == '2' ? n0*6 : 0));\n            } else {\n                n2 += c == '0' ? 0 : n1;\n                if (pc == '*') {\n                    n2 += n0 * (c <= '6' ? 2 : 1);\n                } else {\n                    int two = (pc - '0') * 10 + (c - '0');\n                    n2 += (two >= 10 && two <= 26) ? n0 : 0;\n                }\n            }\n            n2 %= 1000000007;\n            n0 = n1;\n            n1 = n2;\n        }\n\n        return (int) n1;\n    }\n\n}\n"
  },
  {
    "path": "src/DecodedStringAtIndex884.java",
    "content": "/**\n * An encoded string S is given.  To find and write the decoded string to a\n * tape, the encoded string is read one character at a time and the following\n * steps are taken:\n * \n * If the character read is a letter, that letter is written onto the tape.\n * If the character read is a digit (say d), the entire current tape is\n * repeatedly written d-1 more times in total.\n * Now for some encoded string S, and an index K, find and return the K-th\n * letter (1 indexed) in the decoded string.\n * \n * Example 1:\n * Input: S = \"leet2code3\", K = 10\n * Output: \"o\"\n * Explanation: \n * The decoded string is \"leetleetcodeleetleetcodeleetleetcode\".\n * The 10th letter in the string is \"o\".\n * \n * Example 2:\n * Input: S = \"ha22\", K = 5\n * Output: \"h\"\n * Explanation: \n * The decoded string is \"hahahaha\".  The 5th letter is \"h\".\n * \n * Example 3:\n * Input: S = \"a2345678999999999999999\", K = 1\n * Output: \"a\"\n * Explanation: \n * The decoded string is \"a\" repeated 8301530446056247680 times.\n * The 1st letter is \"a\".\n * \n * Note:\n * 2 <= S.length <= 100\n * S will only contain lowercase letters and digits 2 through 9.\n * S starts with a letter.\n * 1 <= K <= 10^9\n * The decoded string is guaranteed to have less than 2^63 letters.\n */\n\npublic class DecodedStringAtIndex884 {\n    public String decodeAtIndex(String S, int K) {\n        char[] chars = S.toCharArray();\n        int N = chars.length;\n        long[] lens = new long[N];\n        long len = 0;\n        for (int i=0; i<N; i++) {\n            char c = chars[i];\n            if (c >= 'a' && c <= 'z') {\n                len++;\n            } else {\n                int re = Character.getNumericValue(c);\n                len *= re;\n            }\n            lens[i] = len;\n        }\n\n        for (int i=N-1; i>=0; i--) {\n            char c = chars[i];\n            if (c >= 'a' && c <= 'z') {\n                if (lens[i] == K) return Character.toString(c);\n            } else {\n                K %= lens[i-1];\n                if (K == 0) {\n                    int j = i-1;\n                    while (!(chars[j] >= 'a' && chars[j] <= 'z')) {\n                        j--;\n                    }\n                    return Character.toString(chars[j]);\n                }\n            }\n        }\n\n        return Character.toString(chars[0]);\n    }\n\n}\n"
  },
  {
    "path": "src/DeleteAndEarn740.java",
    "content": "/**\n * Given an array nums of integers, you can perform operations on the array.\n * \n * In each operation, you pick any nums[i] and delete it to earn nums[i]\n * points. After, you must delete every element equal to nums[i] - 1 or\n * nums[i] + 1.\n * \n * You start with 0 points. Return the maximum number of points you can earn\n * by applying such operations.\n * \n * Example 1:\n * Input: nums = [3, 4, 2]\n * Output: 6\n * Explanation: \n * Delete 4 to earn 4 points, consequently 3 is also deleted.\n * Then, delete 2 to earn 2 points. 6 total points are earned.\n * \n * Example 2:\n * Input: nums = [2, 2, 3, 3, 3, 4]\n * Output: 9\n * Explanation: \n * Delete 3 to earn 3 points, deleting both 2's and the 4.\n * Then, delete 3 again to earn 3 points, and 3 again to earn 3 points.\n * 9 total points are earned.\n * \n * Note:\n * The length of nums is at most 20000.\n * Each element nums[i] is an integer in the range [1, 10000].\n */\n\npublic class DeleteAndEarn740 {\n    public int deleteAndEarn(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        int[] count = new int[10001];\n        int max = 0;\n        for (int n: nums) {\n            max = Math.max(max, n);\n            count[n]++;\n        }\n        int[] dp = new int[max + 1];\n        dp[0] = 0;\n        dp[1] = count[1];\n        for (int i=2; i<=max; i++) {\n            if (count[i] == 0) {\n                dp[i] = Math.max(dp[i-1], dp[i-2]);\n            } else {\n                dp[i] = Math.max(dp[i-1], dp[i-2] + count[i] * i);\n            }\n        }\n        return dp[max];\n    }\n\n\n    public int deleteAndEarn2(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        int[] count = new int[10001];\n        int max = 0;\n        for (int n: nums) {\n            max = Math.max(max, n);\n            count[n]++;\n        }\n        \n        int dp0 = 0;\n        int dp1 = count[1];\n        for (int i=2; i<=max; i++) {\n            int tmp = dp1;\n            if (count[i] == 0) {\n                dp1 = Math.max(dp1, dp0);\n            } else {\n                dp1 = Math.max(dp1, dp0 + count[i] * i);\n            }\n            dp0 = tmp;\n        }\n        \n        return dp1;\n    }\n\n}\n"
  },
  {
    "path": "src/DeleteNodeInABST450.java",
    "content": "/**\n * Given a root node reference of a BST and a key, delete the node with the given\n * key in the BST. Return the root node reference (possibly updated) of the BST.\n *\n * Basically, the deletion can be divided into two stages:\n *\n * Search for a node to remove.\n * If the node is found, delete the node.\n * Note: Time complexity should be O(height of tree).\n *\n * Example:\n *\n * root = [5,3,6,2,4,null,7]\n * key = 3\n *\n *     5\n *    / \\\n *   3   6\n *  / \\   \\\n * 2   4   7\n *\n * Given key to delete is 3. So we find the node with value 3 and delete it.\n *\n * One valid answer is [5,4,6,2,null,null,7], shown in the following BST.\n *\n *     5\n *    / \\\n *   4   6\n *  /     \\\n * 2       7\n *\n * Another valid answer is [5,2,6,null,4,null,7].\n *\n *     5\n *    / \\\n *   2   6\n *   \\   \\\n *     4   7\n *\n */\n\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\n\n\npublic class DeleteNodeInABST450 {\n    public TreeNode deleteNode(TreeNode root, int key) {\n        if (root == null) return null;\n\n        if (key < root.val) {\n            root.left = deleteNode(root.left, key);\n            return root;\n        }\n\n        if (key > root.val) {\n            root.right = deleteNode(root.right, key);\n            return root;\n        }\n\n        return delete(root);\n    }\n\n    private TreeNode delete(TreeNode node) {\n        if (node.left == null) return node.right;\n        if (node.right == null) return node.left;\n        return moveNext(node);\n    }\n\n    private TreeNode moveNext(TreeNode node) {\n        TreeNode min = node.right;\n        if (min.left == null) {\n            node.val = min.val;\n            node.right = min.right;\n            return node;\n        }\n\n        while (min.left != null && min.left.left != null) {\n            System.out.println(min.val);\n            min = min.left;\n        }\n\n        node.val = min.left.val;\n        min.left = delete(min.left);\n        return node;\n    }\n\n\n\n    public TreeNode deleteNode2(TreeNode root, int key) {\n        /* Base Case: If the tree is empty */\n        if (root == null)  return root;\n\n        /* Otherwise, recur down the tree */\n        if (key < root.val) {\n            root.left = deleteNode(root.left, key);\n        } else if (key > root.val) {\n            root.right = deleteNode(root.right, key);\n        } else {\n            // node with only one child or no child\n            if (root.left == null) {\n                return root.right;\n            } else if (root.right == null) {\n                return root.left;\n            }\n\n            // node with two children: Get the inorder successor (smallest\n            // in the right subtree)\n            root.val = minValue(root.right);\n\n            // Delete the inorder successor\n            root.right = deleteNode(root.right, root.val);\n        }\n\n        return root;\n    }\n\n    private int minValue(TreeNode root) {\n        int minv = root.val;\n        while (root.left != null) {\n            minv = root.left.val;\n            root = root.left;\n        }\n        return minv;\n    }\n\n}\n"
  },
  {
    "path": "src/DeleteNodeInALinkedList237.java",
    "content": "/**\n * Write a function to delete a node (except the tail) in a singly linked list,\n * given only access to that node.\n *\n * Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third\n * node with value 3, the linked list should become 1 -> 2 -> 4 after calling\n * your function.\n */\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\npublic class DeleteNodeInALinkedList237 {\n    public void deleteNode(ListNode node) {\n        if (node != null && node.next != null) {\n            node.val = node.next.val;\n            node.next = node.next.next;\n        }\n    }\n}\n"
  },
  {
    "path": "src/DesignCircularDeque641.java",
    "content": "/**\n * Design your implementation of the circular double-ended queue (deque).\n * \n * Your implementation should support following operations:\n * \n * MyCircularDeque(k): Constructor, set the size of the deque to be k.\n * insertFront(): Adds an item at the front of Deque. Return true if the operation is successful.\n * insertLast(): Adds an item at the rear of Deque. Return true if the operation is successful.\n * deleteFront(): Deletes an item from the front of Deque. Return true if the operation is successful.\n * deleteLast(): Deletes an item from the rear of Deque. Return true if the operation is successful.\n * getFront(): Gets the front item from the Deque. If the deque is empty, return -1.\n * getRear(): Gets the last item from Deque. If the deque is empty, return -1.\n * isEmpty(): Checks whether Deque is empty or not. \n * isFull(): Checks whether Deque is full or not.\n * \n * Example:\n * \n * MyCircularDeque circularDeque = new MycircularDeque(3); // set the size to be 3\n * circularDeque.insertLast(1);\t\t\t// return true\n * circularDeque.insertLast(2);\t\t\t// return true\n * circularDeque.insertFront(3);\t\t\t// return true\n * circularDeque.insertFront(4);\t\t\t// return false, the queue is full\n * circularDeque.getRear();  \t\t\t// return 2\n * circularDeque.isFull();\t\t\t\t// return true\n * circularDeque.deleteLast();\t\t\t// return true\n * circularDeque.insertFront(4);\t\t\t// return true\n * circularDeque.getFront();\t\t\t// return 4 \n * \n * Note:\n * \n * All values will be in the range of [0, 1000].\n * The number of operations will be in the range of [1, 1000].\n * Please do not use the built-in Deque library.\n */\n\npublic class DesignCircularDeque641 {\n\n    class MyCircularDeque {\n        private Node head;\n        private int capacity;\n        private int size;\n        \n        /** Initialize your data structure here. Set the size of the deque to be k. */\n        public MyCircularDeque(int k) {\n            this.head = new Node(-1);\n            this.head.next = this.head;\n            this.head.prev = this.head;\n            this.capacity = k;\n            this.size = 0;\n        }\n        \n        /** Adds an item at the front of Deque. Return true if the operation is successful. */\n        public boolean insertFront(int value) {\n            if (this.size >= this.capacity) return false;\n            Node newNode = new Node(value);\n            newNode.next = this.head.next;\n            newNode.prev = this.head;\n            this.head.next.prev = newNode;\n            this.head.next = newNode;\n            this.size++;\n            return true;\n        }\n        \n        /** Adds an item at the rear of Deque. Return true if the operation is successful. */\n        public boolean insertLast(int value) {\n            if (this.size >= this.capacity) return false;\n            Node newNode = new Node(value);\n            newNode.next = this.head;\n            newNode.prev = this.head.prev;\n            this.head.prev.next = newNode;\n            this.head.prev = newNode;\n            this.size++;\n            return true;\n        }\n        \n        /** Deletes an item from the front of Deque. Return true if the operation is successful. */\n        public boolean deleteFront() {\n            if (isEmpty()) return false;\n            Node toBeRemoved = this.head.next;\n            dislink(toBeRemoved);\n            this.size--;\n            return true;\n        }\n        \n        /** Deletes an item from the rear of Deque. Return true if the operation is successful. */\n        public boolean deleteLast() {\n            if (isEmpty()) return false;\n            Node toBeRemoved = this.head.prev;\n            dislink(toBeRemoved);\n            this.size--;\n            return true;\n        }\n        \n        private void dislink(Node node) {\n            node.next.prev = node.prev;\n            node.prev.next = node.next;\n        }\n        \n        /** Get the front item from the deque. */\n        public int getFront() {\n            if (isEmpty()) return -1;\n            return this.head.next.value;\n        }\n        \n        /** Get the last item from the deque. */\n        public int getRear() {\n            if (isEmpty()) return -1;\n            return this.head.prev.value;\n        }\n        \n        /** Checks whether the circular deque is empty or not. */\n        public boolean isEmpty() {\n            return this.size == 0;\n        }\n        \n        /** Checks whether the circular deque is full or not. */\n        public boolean isFull() {\n            return this.size >= this.capacity;\n        }\n        \n        class Node {\n            Node prev;\n            Node next;\n            int value;\n            Node(int value) {\n                this.value = value;\n            }\n        }\n    }\n\n\n    class MyCircularDeque2 {\n        private int[] cache;\n        private int capacity;\n        private int size;\n        private int head;\n        \n        /** Initialize your data structure here. Set the size of the deque to be k. */\n        public MyCircularDeque(int k) {\n            this.cache = new int[k+1];\n            this.capacity = k;\n            this.size = 0;\n            this.head = 0;\n        }\n    \n        /** Adds an item at the front of Deque. Return true if the operation is successful. */\n        public boolean insertFront(int value) {\n            if (this.size >= this.capacity) return false;\n            this.cache[this.head--] = value;\n            if (this.head < 0) this.head += this.cache.length;\n            this.size++;\n            return true;\n        }\n    \n        /** Adds an item at the rear of Deque. Return true if the operation is successful. */\n        public boolean insertLast(int value) {\n            if (this.size >= this.capacity) return false;\n            this.cache[(this.head + this.size + 1) % this.cache.length] = value;\n            this.size++;\n            return true;\n        }\n        \n        /** Deletes an item from the front of Deque. Return true if the operation is successful. */\n        public boolean deleteFront() {\n            if (isEmpty()) return false;\n            this.head++;\n            this.head %= this.cache.length;\n            this.size--;\n            return true;\n        }\n        \n        /** Deletes an item from the rear of Deque. Return true if the operation is successful. */\n        public boolean deleteLast() {\n            if (isEmpty()) return false;\n            this.size--;\n            return true;\n        }\n    \n        /** Get the front item from the deque. */\n        public int getFront() {\n            if (isEmpty()) return -1;\n            return this.cache[(this.head + 1) % this.cache.length];\n        }\n        \n        /** Get the last item from the deque. */\n        public int getRear() {\n            if (isEmpty()) return -1;\n            return this.cache[(this.head + this.size) % this.cache.length];\n        }\n        \n        /** Checks whether the circular deque is empty or not. */\n        public boolean isEmpty() {\n            return this.size == 0;\n        }\n        \n        /** Checks whether the circular deque is full or not. */\n        public boolean isFull() {\n            return this.size >= this.capacity;\n        }\n    \n    }\n\n\n/**\n * Your MyCircularDeque object will be instantiated and called as such:\n * MyCircularDeque obj = new MyCircularDeque(k);\n * boolean param_1 = obj.insertFront(value);\n * boolean param_2 = obj.insertLast(value);\n * boolean param_3 = obj.deleteFront();\n * boolean param_4 = obj.deleteLast();\n * int param_5 = obj.getFront();\n * int param_6 = obj.getRear();\n * boolean param_7 = obj.isEmpty();\n * boolean param_8 = obj.isFull();\n */\n\n}\n\n\n"
  },
  {
    "path": "src/DesignCircularQueue622.java",
    "content": "/**\n * Design your implementation of the circular queue. The circular queue is a\n * linear data structure in which the operations are performed based on FIFO\n * (First In First Out) principle and the last position is connected back to\n * the first position to make a circle. It is also called \"Ring Buffer\".\n * \n * One of the benefits of the circular queue is that we can make use of the\n * spaces in front of the queue. In a normal queue, once the queue becomes\n * full, we cannot insert the next element even if there is a space in front\n * of the queue. But using the circular queue, we can use the space to store\n * new values.\n * \n * Your implementation should support following operations:\n * \n * MyCircularQueue(k): Constructor, set the size of the queue to be k.\n * Front: Get the front item from the queue. If the queue is empty, return -1.\n * Rear: Get the last item from the queue. If the queue is empty, return -1.\n * enQueue(value): Insert an element into the circular queue. Return true if the operation is successful.\n * deQueue(): Delete an element from the circular queue. Return true if the operation is successful.\n * isEmpty(): Checks whether the circular queue is empty or not.\n * isFull(): Checks whether the circular queue is full or not.\n * \n * Example:\n * \n * MyCircularQueue circularQueue = new MycircularQueue(3); // set the size to be 3\n * circularQueue.enQueue(1);  // return true\n * circularQueue.enQueue(2);  // return true\n * circularQueue.enQueue(3);  // return true\n * circularQueue.enQueue(4);  // return false, the queue is full\n * circularQueue.Rear();  // return 3\n * circularQueue.isFull();  // return true\n * circularQueue.deQueue();  // return true\n * circularQueue.enQueue(4);  // return true\n * circularQueue.Rear();  // return 4\n * \n * Note:\n * All values will be in the range of [0, 1000].\n * The number of operations will be in the range of [1, 1000].\n * Please do not use the built-in Queue library.\n */\n\npublic class DesignCircularQueue622 {\n\n    class MyCircularQueue {\n        private Node head;\n        private int capacity;\n        private int size;\n        \n        /** Initialize your data structure here. Set the size of the queue to be k. */\n        public MyCircularQueue(int k) {\n            this.head = new Node();\n            this.head.prev = head;\n            this.head.next = head;\n            this.capacity = k;\n            this.size = 0;\n        }\n        \n        /** Insert an element into the circular queue. Return true if the operation is successful. */\n        public boolean enQueue(int value) {\n            if (isFull()) return false;\n            Node newNode = new Node(value);\n            newNode.next = this.head;\n            newNode.prev = this.head.prev;\n            this.head.prev.next = newNode;\n            this.head.prev = newNode;\n            this.size++;\n            return true;\n        }\n        \n        /** Delete an element from the circular queue. Return true if the operation is successful. */\n        public boolean deQueue() {\n            if (isEmpty()) return false;\n            dislink(this.head.next);\n            this.size--;\n            return true;\n        }\n        \n        private void dislink(Node node) {\n            node.next.prev = node.prev;\n            node.prev.next = node.next;\n        }\n        \n        /** Get the front item from the queue. */\n        public int Front() {\n            if (isEmpty()) return -1;\n            return this.head.next.value;\n        }\n        \n        /** Get the last item from the queue. */\n        public int Rear() {\n            if (isEmpty()) return -1;\n            return this.head.prev.value;\n        }\n        \n        /** Checks whether the circular queue is empty or not. */\n        public boolean isEmpty() {\n            return this.size == 0;\n        }\n        \n        /** Checks whether the circular queue is full or not. */\n        public boolean isFull() {\n            return this.size == this.capacity;\n        }\n        \n        class Node {\n            Node prev;\n            Node next;\n            int value;\n            Node() {\n                this.value = -1;\n            }\n            Node(int value) {\n                this.value = value;\n            }\n        }\n    }\n\n\n    class MyCircularQueue2 {\n        private int[] cache;\n        private int head;\n        private int capacity;\n        private int size;\n        \n        /** Initialize your data structure here. Set the size of the queue to be k. */\n        public MyCircularQueue(int k) {\n            this.cache = new int[k + 1];\n            this.head = 0;\n            this.capacity = k;\n            this.size = 0;\n        }\n        \n        /** Insert an element into the circular queue. Return true if the operation is successful. */\n        public boolean enQueue(int value) {\n            if (isFull()) return false;\n            this.size++;\n            this.cache[(this.head + this.size) % this.cache.length] = value;\n            return true;\n        }\n        \n        /** Delete an element from the circular queue. Return true if the operation is successful. */\n        public boolean deQueue() {\n            if (isEmpty()) return false;\n            this.head++;\n            this.head = this.head % this.cache.length;\n            this.size--;\n            return true;\n        }\n        \n        /** Get the front item from the queue. */\n        public int Front() {\n            if (isEmpty()) return -1;\n            return this.cache[(this.head + 1) % this.cache.length];\n        }\n        \n        /** Get the last item from the queue. */\n        public int Rear() {\n            if (isEmpty()) return -1;\n            return this.cache[(this.head + this.size) % this.cache.length];\n        }\n        \n        /** Checks whether the circular queue is empty or not. */\n        public boolean isEmpty() {\n            return this.size == 0;\n        }\n        \n        /** Checks whether the circular queue is full or not. */\n        public boolean isFull() {\n            return this.size == this.capacity;\n        }\n    \n    }\n\n/**\n * Your MyCircularQueue object will be instantiated and called as such:\n * MyCircularQueue obj = new MyCircularQueue(k);\n * boolean param_1 = obj.enQueue(value);\n * boolean param_2 = obj.deQueue();\n * int param_3 = obj.Front();\n * int param_4 = obj.Rear();\n * boolean param_5 = obj.isEmpty();\n * boolean param_6 = obj.isFull();\n */\n\n}\n\n\n"
  },
  {
    "path": "src/DesignCompressedStringIterator604.java",
    "content": "/**\n * Design and implement a data structure for a compressed string iterator. It\n * should support the following operations: next and hasNext.\n * \n * The given compressed string will be in the form of each letter followed by\n * a positive integer representing the number of this letter existing in the\n * original uncompressed string.\n * \n * next() - if the original string still has uncompressed characters, return\n * the next letter; Otherwise return a white space.\n * hasNext() - Judge whether there is any letter needs to be uncompressed.\n * \n * Note:\n * Please remember to RESET your class variables declared in StringIterator,\n * as static/class variables are persisted across multiple test cases.\n * Please see here for more details.\n * \n * Example:\n * \n * StringIterator iterator = new StringIterator(\"L1e2t1C1o1d1e1\");\n * \n * iterator.next(); // return 'L'\n * iterator.next(); // return 'e'\n * iterator.next(); // return 'e'\n * iterator.next(); // return 't'\n * iterator.next(); // return 'C'\n * iterator.next(); // return 'o'\n * iterator.next(); // return 'd'\n * iterator.hasNext(); // return true\n * iterator.next(); // return 'e'\n * iterator.hasNext(); // return false\n * iterator.next(); // return ' '\n */\n\npublic class DesignCompressedStringIterator604 {\n\n    class StringIterator {\n\n        private int index;\n        private int count;\n        private int countLen;\n        private char[] chars;\n        private int len;\n\n        public StringIterator(String compressedString) {\n            chars = compressedString.toCharArray();\n            len = chars.length;\n            index = 0;\n            move();\n        }\n        \n        public char next() {\n            if (index >= len) return ' ';\n            char returned = chars[index];\n            count--;\n            if (count == 0) {\n                index += countLen + 1;\n                move();\n            }\n            return returned;\n        }\n\n        public boolean hasNext() {\n            return index < len;\n        }\n        \n        private void move() {\n            if (index < len) {\n                int i = index + 1;\n                while (i < len && isNumeric(chars[i])) {\n                    i++;\n                }\n                countLen = i - index - 1;\n                count = Integer.parseInt(new String(chars, index + 1, countLen));\n            }\n        }\n        \n        private boolean isNumeric(char c) {\n            return c >= '0' && c <= '9';\n        }\n        \n    }\n\n\n    /**\n     * https://leetcode.com/problems/design-compressed-string-iterator/discuss/103828/Java-Concise-Single-Queue-Solution\n     */\n    class StringIterator2 {\n        Queue<int[]> queue = new LinkedList<>();\n        \n        public StringIterator(String s) {\n            int i = 0, n = s.length();\n            while (i < n) {\n                int j = i+1;\n                while (j < n && s.charAt(j) - 'A' < 0) j++;\n                queue.add(new int[]{s.charAt(i) - 'A',  Integer.parseInt(s.substring(i+1, j))});\n                i = j;\n            }\n        }\n        \n        public char next() {\n            if (queue.isEmpty()) return ' ';\n            int[] top = queue.peek();\n            if (--top[1] == 0) queue.poll();\n            return (char) ('A' + top[0]);\n        }\n        \n        public boolean hasNext() {\n            return !queue.isEmpty();\n        }\n    }\n\n\n/**\n * Your StringIterator object will be instantiated and called as such:\n * StringIterator obj = new StringIterator(compressedString);\n * char param_1 = obj.next();\n * boolean param_2 = obj.hasNext();\n */\n\n\n}\n"
  },
  {
    "path": "src/DesignHashMap706.java",
    "content": "/**\n * Design a HashMap without using any built-in hash table libraries.\n * \n * To be specific, your design should include these functions:\n * \n * put(key, value) : Insert a (key, value) pair into the HashMap. If the value\n * already exists in the HashMap, update the value.\n * \n * get(key): Returns the value to which the specified key is mapped, or -1 if\n * this map contains no mapping for the key.\n * \n * remove(key) : Remove the mapping for the value key if this map contains the\n * mapping for the key.\n * \n * Example:\n * MyHashMap hashMap = new MyHashMap();\n * hashMap.put(1, 1);          \n * hashMap.put(2, 2);         \n * hashMap.get(1);            // returns 1\n * hashMap.get(3);            // returns -1 (not found)\n * hashMap.put(2, 1);          // update the existing value\n * hashMap.get(2);            // returns 1 \n * hashMap.remove(2);          // remove the mapping for 2\n * hashMap.get(2);            // returns -1 (not found) \n * \n * Note:\n * All keys and values will be in the range of [0, 1000000].\n * The number of operations will be in the range of [1, 10000].\n * Please do not use the built-in HashMap library.\n */\n\npublic class DesignHashMap706 {\n    class MyHashMap {\n        private Integer[] cache = new Integer[1000000];\n        \n        /** Initialize your data structure here. */\n        public MyHashMap() {\n        }\n        \n        /** value will always be non-negative. */\n        public void put(int key, int value) {\n            cache[key] = value;\n        }\n        \n        /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */\n        public int get(int key) {\n            if (cache[key] == null) return -1;\n            return cache[key];\n        }\n        \n        /** Removes the mapping of the specified value key if this map contains a mapping for the key */\n        public void remove(int key) {\n            cache[key] = null;\n        }\n    }\n  \n\n    class MyHashMap2 {\n\n        private static final int K = 100000;\n        private ListNode[] cache = new ListNode[100000];\n        \n        /** Initialize your data structure here. */\n        public MyHashMap() {\n        }\n        \n        /** value will always be non-negative. */\n        public void put(int key, int value) {\n            int k = key % K;\n            if (cache[k] == null) {\n                cache[k] = new ListNode(key, value);\n            } else {\n                ListNode head = cache[k];\n                while (true) {\n                    if (head.key == key) {\n                        head.value = value;\n                        return;\n                    }\n                    if (head.next == null) {\n                        ListNode newNode = new ListNode(key, value);\n                        head.next = newNode;\n                        newNode.prev = head;\n                        return;\n                    }\n                    head = head.next;\n                }\n            }\n        }\n        \n        /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */\n        public int get(int key) {\n            int k = key % K;\n            if (cache[k] == null) return -1;\n            ListNode head = cache[k];\n            while (true) {\n                if (head.key == key) {\n                    return head.value;\n                }\n                if (head.next == null) {\n                    return -1;\n                }\n                head = head.next;\n            }\n        }\n        \n        /** Removes the mapping of the specified value key if this map contains a mapping for the key */\n        public void remove(int key) {\n            int k = key % K;\n            if (cache[k] == null) return;\n            ListNode head = cache[k];\n            while (true) {\n                if (head.key == key) {\n                    if (head.prev == null) {\n                        cache[k] = head.next;\n                    } else {\n                        if (head.next != null) head.next.prev = head.prev;\n                        head.prev.next = head.next;\n                    }\n                    return;\n                }\n                if (head.next == null) {\n                    return;\n                }\n                head = head.next;\n            }\n        }\n        \n        class ListNode {\n            ListNode prev;\n            ListNode next;\n            Integer key;\n            Integer value;\n            ListNode (int key, int value) {\n                this.key = key;\n                this.value = value;\n            }\n        }\n    }\n\n\n    class MyHashMap3 {\n\n        private static final int K = 100000;\n        private TreeNode[] cache = new TreeNode[100000];\n        \n        /** Initialize your data structure here. */\n        public MyHashMap() {\n        }\n        \n        /** value will always be non-negative. */\n        public void put(int key, int value) {\n            int k = key % K;\n            if (cache[k] == null) {\n                cache[k] = new TreeNode(key, value);\n            } else {\n                TreeNode head = cache[k];\n                while (true) {\n                    if (head.key == key) {\n                        head.value = value;\n                        return;\n                    }\n                    if (head.key > key) {\n                        if (head.left == null) {\n                            head.left = new TreeNode(key, value);\n                            return;\n                        }\n                        head = head.left;\n                    } else {\n                        if (head.right == null) {\n                            head.right = new TreeNode(key, value);\n                            return;\n                        }\n                        head = head.right;\n                    }\n                    if (head == null) return;\n                }\n            }\n        }\n        \n        /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */\n        public int get(int key) {\n            int k = key % K;\n            if (cache[k] == null) return -1;\n            TreeNode head = cache[k];\n            while (true) {\n                if (head.key == key) {\n                    return head.value;\n                }\n                if (head.key > key) {\n                    if (head.left == null) {\n                        return -1;\n                    }\n                    head = head.left;\n                } else {\n                    if (head.right == null) {\n                        return -1;\n                    }\n                    head = head.right;\n                }\n                if (head == null) return -1;\n            }\n        }\n        \n        /** Removes the mapping of the specified value key if this map contains a mapping for the key */\n        public void remove(int key) {\n            int k = key % K;\n            cache[k] = delete(cache[k], key);\n        }\n    \n        private TreeNode delete(TreeNode head, int key) {\n            if (head == null)  return head;\n    \n            if (key < head.key) {\n                head.left = delete(head.left, key);\n            } else if (key > head.key) {\n                head.right = delete(head.right, key);\n            } else {\n                if (head.left == null) {\n                    return head.right;\n                } else if (head.right == null) {\n                    return head.left;\n                }\n    \n                head.key = minValue(head.right);\n                head.right = delete(head.right, head.key);\n            }\n    \n            return head;\n        }\n     \n        private int minValue(TreeNode head) {\n            int minv = head.key;\n            while (head.left != null) {\n                minv = head.left.key;\n                head = head.left;\n            }\n            return minv;\n        }\n        \n        class TreeNode {\n            TreeNode left;\n            TreeNode right;\n            Integer key;\n            Integer value;\n            TreeNode (int key, int value) {\n                this.key = key;\n                this.value = value;\n            }\n        }\n    }\n\n/**\n * Your MyHashMap object will be instantiated and called as such:\n * MyHashMap obj = new MyHashMap();\n * obj.put(key,value);\n * int param_2 = obj.get(key);\n * obj.remove(key);\n */\n\n}\n"
  },
  {
    "path": "src/DesignHashSet705.java",
    "content": "/**\n * Design a HashSet without using any built-in hash table libraries.\n * \n * To be specific, your design should include these functions:\n * add(value): Insert a value into the HashSet. \n * contains(value) : Return whether the value exists in the HashSet or not.\n * remove(value): Remove a value in the HashSet. If the value does not exist\n * in the HashSet, do nothing.\n * \n * Example:\n * MyHashSet hashSet = new MyHashSet();\n * hashSet.add(1);         \n * hashSet.add(2);         \n * hashSet.contains(1);    // returns true\n * hashSet.contains(3);    // returns false (not found)\n * hashSet.add(2);          \n * hashSet.contains(2);    // returns true\n * hashSet.remove(2);          \n * hashSet.contains(2);    // returns false (already removed)\n * \n * Note:\n * All values will be in the range of [0, 1000000].\n * The number of operations will be in the range of [1, 10000].\n * Please do not use the built-in HashSet library.\n */\n\npublic class DesignHashSet705 {\n\n    class MyHashSet {\n        private static final int K = 10000;\n        private List<Integer>[] cache = new List[K];\n        \n        /** Initialize your data structure here. */\n        public MyHashSet() {\n            \n        }\n        \n        public void add(int key) {\n            int k = key % K;\n            if (cache[k] == null) {\n                cache[k] = new ArrayList<>();\n            }\n            List<Integer> list = cache[k];\n            for (int el: list) {\n                if (el == key) return;\n            }\n            list.add(key);\n        }\n        \n        public void remove(int key) {\n            int k = key % K;\n            if (cache[k] == null) return;\n            List<Integer> list = cache[k];\n            \n            for (int i=0; i<list.size(); i++) {\n                if (list.get(i) == key) {\n                    list.remove(i);\n                    return;\n                }\n            }\n        }\n        \n        /** Returns true if this set contains the specified element */\n        public boolean contains(int key) {\n            int k = key % K;\n            if (cache[k] == null) return false;\n            List<Integer> list = cache[k];\n            for (int el: list) {\n                if (el == key) return true;\n            }\n            return false;\n        }\n    }\n\n\n\n    class MyHashSet2 {\n        private static final int K = 10000;\n        private TreeNode[] cache = new TreeNode[K];\n        \n        /** Initialize your data structure here. */\n        public MyHashSet2() {\n            \n        }\n        \n        public void add(int key) {\n            int k = key % K;\n            cache[k] = addNode(cache[k], key);\n        }\n        \n        TreeNode addNode(TreeNode root, int key) {\n            if (root == null) return new TreeNode(key);\n            if (root.key > key) {\n                root.left = addNode(root.left, key);\n            } else if (root.key < key) {\n                root.right = addNode(root.right, key);\n            }\n            return root;\n        }\n        \n        public void remove(int key) {\n            int k = key % K;\n            cache[k] = removeNode(cache[k], key);\n        }\n        \n        TreeNode removeNode(TreeNode root, int key) {\n            if (root == null) return null;\n            if (root.key > key) {\n                root.left = removeNode(root.left, key);\n            } else if (root.key < key) {\n                root.right = removeNode(root.right, key);\n            } else {\n                if (root.left == null) {\n                    return root.right;\n                } else if (root.right == null) {\n                    return root.left;\n                } else {\n                    root.key = findMin(root.right);\n                    root.right = removeNode(root.right, root.key);\n                }\n            }\n            return root;\n        }\n        \n        int findMin(TreeNode root) {\n            while (root.left != null) {\n                root = root.left;\n            }\n            return root.key;\n        }\n        \n        /** Returns true if this set contains the specified element */\n        public boolean contains(int key) {\n            return containNode(cache[key % K], key);\n        }\n        \n        boolean containNode(TreeNode root, int key) {\n            if (root == null) return false;\n            if (root.key == key) return true;\n            return containNode(root.left, key) || containNode(root.right, key);\n        }\n        \n        class TreeNode {\n            TreeNode left;\n            TreeNode right;\n            int key;\n            TreeNode(int key) {\n                this.key = key;\n            }\n        }\n        \n    }\n\n\n/**\n * Your MyHashSet object will be instantiated and called as such:\n * MyHashSet obj = new MyHashSet();\n * obj.add(key);\n * obj.remove(key);\n * boolean param_3 = obj.contains(key);\n */\n\n}\n"
  },
  {
    "path": "src/DesignHitCounter362.java",
    "content": "/**\n * Design a hit counter which counts the number of hits received in the\n * past 5 minutes.\n * \n * Each function accepts a timestamp parameter (in seconds granularity) and you\n * may assume that calls are being made to the system in chronological order\n * (ie, the timestamp is monotonically increasing). You may assume that the\n * earliest timestamp starts at 1.\n * \n * It is possible that several hits arrive roughly at the same time.\n * \n * Example:\n * HitCounter counter = new HitCounter();\n * \n * // hit at timestamp 1.\n * counter.hit(1);\n * \n * // hit at timestamp 2.\n * counter.hit(2);\n * \n * // hit at timestamp 3.\n * counter.hit(3);\n * \n * // get hits at timestamp 4, should return 3.\n * counter.getHits(4);\n * \n * // hit at timestamp 300.\n * counter.hit(300);\n * \n * // get hits at timestamp 300, should return 4.\n * counter.getHits(300);\n * \n * // get hits at timestamp 301, should return 3.\n * counter.getHits(301); \n * \n * Follow up:\n * What if the number of hits per second could be very large?\n * Does your design scale?\n */\n\n\npublic class DesignHitCounter362 {\n    class HitCounter {\n        private int FIVE_MINUTES = 300;\n        private LinkedList<Integer> cache = new LinkedList<>();\n        \n        /** Initialize your data structure here. */\n        public HitCounter() {\n        }\n        \n        /** Record a hit.\n            @param timestamp - The current timestamp (in seconds granularity). */\n        public void hit(int timestamp) {\n            removeOldHits(timestamp);\n            this.cache.add(timestamp);\n        }\n        \n        /** Return the number of hits in the past 5 minutes.\n            @param timestamp - The current timestamp (in seconds granularity). */\n        public int getHits(int timestamp) {\n            removeOldHits(timestamp);\n            return this.cache.size();\n        }\n\n        private void removeOldHits(int timestamp) {\n            while (!this.cache.isEmpty() && this.cache.getFirst() + FIVE_MINUTES <= timestamp) {\n                this.cache.removeFirst();\n            }\n        }\n    }\n    \n\n    class HitCounter2 {\n        private int FIVE_MINUTES = 300;\n        private int[] buckets = new int[FIVE_MINUTES];\n        private int counts = 0;\n        private int lastTS = 0;\n    \n        /** Initialize your data structure here. */\n        public HitCounter() {\n        }\n        \n        /** Record a hit.\n            @param timestamp - The current timestamp (in seconds granularity). */\n        public void hit(int timestamp) {\n            removeOldHits(timestamp);\n            this.buckets[bucketIndex(timestamp)]++;\n            this.counts++;\n            this.lastTS = timestamp;\n        }\n        \n        /** Return the number of hits in the past 5 minutes.\n            @param timestamp - The current timestamp (in seconds granularity). */\n        public int getHits(int timestamp) {\n            removeOldHits(timestamp);\n            this.lastTS = timestamp;\n            return this.counts;\n        }\n    \n        private void removeOldHits(int timestamp) {\n            int tsDiff = timestamp - this.lastTS;\n            int diff = tsDiff >= FIVE_MINUTES ? FIVE_MINUTES : tsDiff;\n            for (int i=1; i<=diff; i++) {\n                int idx = bucketIndex(this.lastTS+i);\n                this.counts -= this.buckets[idx];\n                this.buckets[idx] = 0;\n            }\n        }\n        \n        private int bucketIndex(int timestamp) {\n            return (timestamp - 1) % FIVE_MINUTES;\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/design-hit-counter/discuss/83483/Super-easy-design-O(1)-hit()-O(s)-getHits()-no-fancy-data-structure-is-needed!\n     */\n    class HitCounter3 {\n        private int[] times;\n        private int[] hits;\n        /** Initialize your data structure here. */\n        public HitCounter() {\n            times = new int[300];\n            hits = new int[300];\n        }\n        \n        /** Record a hit.\n            @param timestamp - The current timestamp (in seconds granularity). */\n        public void hit(int timestamp) {\n            int index = timestamp % 300;\n            if (times[index] != timestamp) {\n                times[index] = timestamp;\n                hits[index] = 1;\n            } else {\n                hits[index]++;\n            }\n        }\n        \n        /** Return the number of hits in the past 5 minutes.\n            @param timestamp - The current timestamp (in seconds granularity). */\n        public int getHits(int timestamp) {\n            int total = 0;\n            for (int i = 0; i < 300; i++) {\n                if (timestamp - times[i] < 300) {\n                    total += hits[i];\n                }\n            }\n            return total;\n        }\n    }\n\n/**\n * Your HitCounter object will be instantiated and called as such:\n * HitCounter obj = new HitCounter();\n * obj.hit(timestamp);\n * int param_2 = obj.getHits(timestamp);\n */\n\n}\n\n"
  },
  {
    "path": "src/DesignInMemoryFileSystem588.java",
    "content": "/**\n * Design an in-memory file system to simulate the following functions:\n * \n * ls: Given a path in string format. If it is a file path, return a list that\n * only contains this file's name. If it is a directory path, return the list\n * of file and directory names in this directory. Your output (file and\n * directory names together) should in lexicographic order.\n * \n * mkdir: Given a directory path that does not exist, you should make a new\n * directory according to the path. If the middle directories in the path\n * don't exist either, you should create them as well. This function has void\n * return type.\n * \n * addContentToFile: Given a file path and file content in string format. If\n * the file doesn't exist, you need to create that file containing given\n * content. If the file already exists, you need to append given content to\n * original content. This function has void return type.\n * \n * readContentFromFile: Given a file path, return its content in string format.\n * \n * Example:\n * \n * Input: \n * [\"FileSystem\",\"ls\",\"mkdir\",\"addContentToFile\",\"ls\",\"readContentFromFile\"]\n * [[],[\"/\"],[\"/a/b/c\"],[\"/a/b/c/d\",\"hello\"],[\"/\"],[\"/a/b/c/d\"]]\n * Output:\n * [null,[],null,null,[\"a\"],\"hello\"]\n * Explanation:\n * https://leetcode.com/static/images/problemset/filesystem.png\n * \n * Note:\n * You can assume all file or directory paths are absolute paths which begin\n * with / and do not end with / except that the path is just \"/\".\n * You can assume that all operations will be passed valid parameters and users\n * will not attempt to retrieve file content or list a directory or file that\n * does not exist.\n * You can assume that all directory names and file names only contain\n * lower-case letters, and same names won't exist in the same directory.\n */\n\n\npublic class DesignInMemoryFileSystem588 {\n\n    class FileSystem {\n        private Trie root = new Trie();\n\n        public FileSystem() {\n        }\n\n        public List<String> ls(String path) {\n            return root.find(path.split(\"/\"));\n        }\n\n        public void mkdir(String path) {\n            root.addDir(path.split(\"/\"));\n        }\n\n        public void addContentToFile(String filePath, String content) {\n            root.addFile(filePath.split(\"/\"), content);\n        }\n\n        public String readContentFromFile(String filePath) {\n            return root.retrieve(filePath.split(\"/\"));\n        }\n\n        class Trie {\n            Map<String, Trie> children = new HashMap<>();\n            boolean isDirectory = true;\n            String name = \"\";\n            List<String> contents = new ArrayList<>();\n\n            private int startPos(String[] path) {\n                return (path.length > 0 && path[0].length() == 0) ? 1 : 0;\n            }\n\n            List<String> find(String[] path) {\n                return find(path, startPos(path));\n            }\n\n            List<String> find(String[] path, int i) {\n                if (path.length == i) {\n                    if (isDirectory) {\n                        List<String> list = new ArrayList<>(children.keySet());\n                        Collections.sort(list);\n                        return list;\n                    } else {\n                        List<String> list = new ArrayList<>();\n                        list.add(name);\n                        return list;\n                    }\n                }\n                if (!children.containsKey(path[i])) {\n                    return new ArrayList<>();\n                }\n                return children.get(path[i]).find(path, i+1); \n            }\n\n            void addDir(String[] path) {\n                addDir(path, startPos(path));\n            }\n\n            void addDir(String[] path, int i) {\n                name = path[i-1];\n                if (path.length == i) {\n                    return;\n                }\n                children.computeIfAbsent(path[i], k -> new Trie()).addDir(path, i+1); \n            }\n\n            void addFile(String[] path, String content) {\n                addFile(path, startPos(path), content);\n            }\n\n            void addFile(String[] path, int i, String content) {\n                name = path[i-1];\n                if (path.length == i) {\n                    isDirectory = false;\n                    contents.add(content);\n                    return;\n                }\n                children.computeIfAbsent(path[i], k -> new Trie()).addFile(path, i+1, content); \n            }\n\n            String retrieve(String[] path) {\n                return retrieve(path, startPos(path));\n            }\n\n            String retrieve(String[] path, int i) {\n                if (path.length == i) {\n                    StringBuilder sb = new StringBuilder();\n                    for (String c: contents) sb.append(c);\n                    return sb.toString();\n                }\n                if (!children.containsKey(path[i])) {\n                    return \"\";\n                }\n                return children.get(path[i]).retrieve(path, i+1); \n            }\n        }\n    }\n\n/**\n * Your FileSystem object will be instantiated and called as such:\n * FileSystem obj = new FileSystem();\n * List<String> param_1 = obj.ls(path);\n * obj.mkdir(path);\n * obj.addContentToFile(filePath,content);\n * String param_4 = obj.readContentFromFile(filePath);\n */\n\n}\n"
  },
  {
    "path": "src/DesignLinkedList707.java",
    "content": "/**\n * Design your implementation of the linked list. You can choose to use the\n * singly linked list or the doubly linked list. A node in a singly linked list\n * should have two attributes: val and next. val is the value of the current\n * node, and next is a pointer/reference to the next node. If you want to use\n * the doubly linked list, you will need one more attribute prev to indicate\n * the previous node in the linked list. Assume all nodes in the linked list\n * are 0-indexed.\n * \n * Implement these functions in your linked list class:\n * \n * get(index) : Get the value of the index-th node in the linked list. If the\n * index is invalid, return -1.\n * addAtHead(val) : Add a node of value val before the first element of the\n * linked list. After the insertion, the new node will be the first node of\n * the linked list.\n * addAtTail(val) : Append a node of value val to the last element of the\n * linked list.\n * addAtIndex(index, val) : Add a node of value val before the index-th node\n * in the linked list. If index equals to the length of linked list, the node\n * will be appended to the end of linked list. If index is greater than the\n * length, the node will not be inserted.\n * deleteAtIndex(index) : Delete the index-th node in the linked list, if the\n * index is valid.\n * \n * Example:\n * MyLinkedList linkedList = new MyLinkedList();\n * linkedList.addAtHead(1);\n * linkedList.addAtTail(3);\n * linkedList.addAtIndex(1, 2);  // linked list becomes 1->2->3\n * linkedList.get(1);            // returns 2\n * linkedList.deleteAtIndex(1);  // now the linked list is 1->3\n * linkedList.get(1);            // returns 3\n * \n * Note:\n * All values will be in the range of [1, 1000].\n * The number of operations will be in the range of [1, 1000].\n * Please do not use the built-in LinkedList library.\n */\n\npublic class DesignLinkedList707 {\n    class MyLinkedList {\n        private Node head;\n\n        /** Initialize your data structure here. */\n        public MyLinkedList() {\n            head = new Node(0);\n        }\n\n        /** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */\n        public int get(int index) {\n            int i = 0;\n            Node p = head.next;\n            while (i < index && p != null) {\n                p = p.next;\n                i++;\n            }\n            if (p == null) return -1;\n            return p.val;\n        }\n\n        /** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */\n        public void addAtHead(int val) {\n            Node newNode = new Node(val);\n            newNode.next = head.next;\n            head.next = newNode;\n        }\n\n        /** Append a node of value val to the last element of the linked list. */\n        public void addAtTail(int val) {\n            Node p = head;\n            while (p.next != null) {\n                p = p.next;\n            }\n            Node newNode = new Node(val);\n            newNode.next = p.next;\n            p.next = newNode;\n        }\n\n        /** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */\n        public void addAtIndex(int index, int val) {\n            int i = 0;\n            Node p = head;\n            while (i < index && p != null) {\n                p = p.next;\n                i++;\n            }\n            if (p == null) return;\n            Node newNode = new Node(val);\n            newNode.next = p.next;\n            p.next = newNode;\n        }\n\n        /** Delete the index-th node in the linked list, if the index is valid. */\n        public void deleteAtIndex(int index) {\n            int i = 0;\n            Node p = head;\n            while (i < index && p != null) {\n                p = p.next;\n                i++;\n            }\n            if (p == null || p.next == null) return;\n            p.next = p.next.next;\n        }\n\n        class Node {\n            Node next;\n            int val;\n            Node (int x) {\n                this.val = x;\n            }\n        }\n\n    }\n\n\n    class MyLinkedList2 {\n        private Node head;\n\n        /** Initialize your data structure here. */\n        public MyLinkedList() {\n            head = new Node(0);\n        }\n\n        /** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */\n        public int get(int index) {\n            int i = 0;\n            Node p = head.next;\n            while (i < index && p != null) {\n                p = p.next;\n                i++;\n            }\n            if (p == null) return -1;\n            return p.val;\n        }\n\n        /** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */\n        public void addAtHead(int val) {\n            Node newNode = new Node(val);\n            newNode.next = head.next;\n            if (head.next != null) head.next.prev = newNode;\n            head.next = newNode;\n            newNode.prev = head;\n        }\n\n        /** Append a node of value val to the last element of the linked list. */\n        public void addAtTail(int val) {\n            Node p = head;\n            while (p.next != null) {\n                p = p.next;\n            }\n            Node newNode = new Node(val);\n            newNode.next = p.next;\n            if (p.next != null) p.next.prev = newNode;\n            p.next = newNode;\n            newNode.prev = p;\n        }\n\n        /** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */\n        public void addAtIndex(int index, int val) {\n            int i = 0;\n            Node p = head;\n            while (i < index && p != null) {\n                p = p.next;\n                i++;\n            }\n            if (p == null) return;\n            Node newNode = new Node(val);\n            newNode.next = p.next;\n            if (p.next != null) p.next.prev = newNode;\n            p.next = newNode;\n            newNode.prev = p;\n        }\n\n        /** Delete the index-th node in the linked list, if the index is valid. */\n        public void deleteAtIndex(int index) {\n            int i = 0;\n            Node p = head;\n            while (i < index && p != null) {\n                p = p.next;\n                i++;\n            }\n            if (p == null || p.next == null) return;\n            p.next = p.next.next;\n            if (p.next != null) p.next.prev = p;\n        }\n\n        class Node {\n            Node prev;\n            Node next;\n            int val;\n            Node (int x) {\n                this.val = x;\n            }\n        }\n    }\n\n\n/**\n * Your MyLinkedList object will be instantiated and called as such:\n * MyLinkedList obj = new MyLinkedList();\n * int param_1 = obj.get(index);\n * obj.addAtHead(val);\n * obj.addAtTail(val);\n * obj.addAtIndex(index,val);\n * obj.deleteAtIndex(index);\n */\n\n}\n"
  },
  {
    "path": "src/DesignLogStorageSystem635.java",
    "content": "/**\n * You are given several logs that each log contains a unique id and timestamp.\n * Timestamp is a string that has the following format:\n * Year:Month:Day:Hour:Minute:Second, for example, 2017:01:01:23:59:59.\n * All domains are zero-padded decimal numbers.\n * \n * Design a log storage system to implement the following functions:\n * \n * void Put(int id, string timestamp): Given a log's unique id and timestamp,\n * store the log in your storage system.\n * \n * int[] Retrieve(String start, String end, String granularity): Return the\n * id of logs whose timestamps are within the range from start to end. Start\n * and end all have the same format as timestamp. However, granularity means\n * the time level for consideration. For example,\n * start = \"2017:01:01:23:59:59\", end = \"2017:01:02:23:59:59\",\n * granularity = \"Day\", it means that we need to find the logs within the range\n * from Jan. 1st 2017 to Jan. 2nd 2017.\n * \n * Example 1:\n * put(1, \"2017:01:01:23:59:59\");\n * put(2, \"2017:01:01:22:59:59\");\n * put(3, \"2016:01:01:00:00:00\");\n * retrieve(\"2016:01:01:01:01:01\",\"2017:01:01:23:00:00\",\"Year\");\n * // return [1,2,3], because you need to return all logs within 2016 and 2017.\n * retrieve(\"2016:01:01:01:01:01\",\"2017:01:01:23:00:00\",\"Hour\");\n * // return [1,2], because you need to return all logs start from\n * 2016:01:01:01 to 2017:01:01:23, where log 3 is left outside the range.\n * \n * Note:\n * There will be at most 300 operations of Put or Retrieve.\n * Year ranges from [2000,2017]. Hour ranges from [00,23].\n * Output for Retrieve has no order required.\n */\n\nimport java.time.format.DateTimeFormatter;\nimport java.time.LocalDateTime;\nimport java.time.temporal.ChronoUnit;\n  \n\npublic class DesignLogStorageSystem635 {\n    class LogSystem {\n        private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(\"yyyy:MM:dd:HH:mm:ss\");\n        private static final int K = 6;\n        private TreeMap<String, Integer> treeMap;\n        \n        public LogSystem() {\n            Comparator<String> comp = (s1, s2) -> s1.compareTo(s2);\n            treeMap = new TreeMap<>(comp);\n        }\n        \n        public void put(int id, String timestamp) {\n            treeMap.put(timestamp, id);\n        }\n        \n        public List<Integer> retrieve(String s, String e, String gra) {\n            String start = roundLeft(s, gra);\n            String end = roundRight(e, gra);\n            Map<String, Integer> subMap = treeMap.subMap(start, end);\n            List<Integer> res = new ArrayList<>();\n            for (Integer id: subMap.values()) {\n                res.add(id);\n            }\n            return res;\n        }\n        \n        private String roundLeft(String timestamp, String gra) {\n            TimeUnit unit = TimeUnit.valueOf(gra);\n            return roundLeft(timestamp, unit);\n        }\n        \n        private String roundLeft(String timestamp, TimeUnit unit) {\n            String[] times = timestamp.split(\":\");\n            for (int k=K-1; k>unit.pos; k--) {\n                times[k] = \"00\";\n            }\n            return String.join(\":\", times);\n        }\n        \n        private String plus(String timestamp, TimeUnit unit) {\n            LocalDateTime newTime = LocalDateTime.parse(timestamp, formatter).plus(1, ChronoUnit.valueOf(unit.chrono));\n            return formatter.format(newTime);\n        }\n        \n        private String roundRight(String timestamp, String gra) {\n            TimeUnit unit = TimeUnit.valueOf(gra);\n            String newTs = plus(timestamp, unit);\n            return roundLeft(newTs, unit);\n        }\n    }\n\n    enum TimeUnit {\n        Year(0, \"YEARS\"),\n        Month(1, \"MONTHS\"),\n        Day(2, \"DAYS\"),\n        Hour(3, \"HOURS\"),\n        Minute(4, \"MINUTES\"),\n        Second(5, \"SECONDS\");\n\n        int pos;\n        String chrono;\n        TimeUnit(int position, String chrono) {\n            this.pos = position;\n            this.chrono = chrono;\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/design-log-storage-system/discuss/105008/Concise-Java-Solution\n     */\n    class LogSystem2 {\n        List<String[]> timestamps = new LinkedList<>();\n        List<String> units = Arrays.asList(\"Year\", \"Month\", \"Day\", \"Hour\", \"Minute\", \"Second\");\n        int[] indices = new int[]{4,7,10,13,16,19};\n        \n        public void put(int id, String timestamp) { timestamps.add(new String[]{Integer.toString(id), timestamp}); }\n    \n        public List<Integer> retrieve(String s, String e, String gra) {\n            List<Integer> res = new LinkedList<>();\n            int idx = indices[units.indexOf(gra)];\n            for (String[] timestamp : timestamps) {\n                if (timestamp[1].substring(0, idx).compareTo(s.substring(0, idx)) >= 0 &&\n                    timestamp[1].substring(0, idx).compareTo(e.substring(0, idx)) <= 0) res.add(Integer.parseInt(timestamp[0]));\n            }\n            return res;\n        }\n    }\n\n\n\n/**\n * Your LogSystem object will be instantiated and called as such:\n * LogSystem obj = new LogSystem();\n * obj.put(id,timestamp);\n * List<Integer> param_2 = obj.retrieve(s,e,gra);\n */\n\n}\n"
  },
  {
    "path": "src/DesignSearchAutocompleteSystem642.java",
    "content": "/**\n * Design a search autocomplete system for a search engine. Users may input a\n * sentence (at least one word and end with a special character '#'). For each\n * character they type except '#', you need to return the top 3 historical hot\n * sentences that have prefix the same as the part of sentence already typed.\n * Here are the specific rules:\n * \n * The hot degree for a sentence is defined as the number of times a user typed\n * the exactly same sentence before.\n * The returned top 3 hot sentences should be sorted by hot degree (The first is\n * the hottest one). If several sentences have the same degree of hot, you need\n * to use ASCII-code order (smaller one appears first).\n * If less than 3 hot sentences exist, then just return as many as you can.\n * When the input is a special character, it means the sentence ends, and in this\n * case, you need to return an empty list.\n * Your job is to implement the following functions:\n * \n * The constructor function:\n * \n * AutocompleteSystem(String[] sentences, int[] times): This is the constructor.\n * The input is historical data. Sentences is a string array consists of\n * previously typed sentences. Times is the corresponding times a sentence\n * has been typed. Your system should record these historical data.\n * \n * Now, the user wants to input a new sentence. The following function will\n * provide the next character the user types:\n * \n * List<String> input(char c): The input c is the next character typed by the\n * user. The character will only be lower-case letters ('a' to 'z'), blank\n * space (' ') or a special character ('#'). Also, the previously typed\n * sentence should be recorded in your system. The output will be the top 3\n * historical hot sentences that have prefix the same as the part of sentence\n * already typed.\n * \n * Example:\n * Operation: AutocompleteSystem([\"i love you\", \"island\",\"ironman\", \"i love leetcode\"], [5,3,2,2]) \n * The system have already tracked down the following sentences and their corresponding times: \n * \"i love you\" : 5 times \n * \"island\" : 3 times \n * \"ironman\" : 2 times \n * \"i love leetcode\" : 2 times \n * Now, the user begins another search: \n * \n * Operation: input('i') \n * Output: [\"i love you\", \"island\",\"i love leetcode\"] \n * Explanation: \n * There are four sentences that have prefix \"i\". Among them, \"ironman\" and\n * \"i love leetcode\" have same hot degree. Since ' ' has ASCII code 32 and 'r'\n * has ASCII code 114, \"i love leetcode\" should be in front of \"ironman\". Also\n * we only need to output top 3 hot sentences, so \"ironman\" will be ignored. \n * \n * Operation: input(' ') \n * Output: [\"i love you\",\"i love leetcode\"] \n * Explanation: \n * There are only two sentences that have prefix \"i \". \n * \n * Operation: input('a') \n * Output: [] \n * Explanation: \n * There are no sentences that have prefix \"i a\". \n * \n * Operation: input('#') \n * Output: [] \n * Explanation: \n * The user finished the input, the sentence \"i a\" should be saved as a\n * historical sentence in system. And the following input will be counted as a\n * new search. \n * \n * Note:\n * The input sentence will always start with a letter and end with '#', and\n * only one blank space will exist between two words.\n * The number of complete sentences that to be searched won't exceed 100. The\n * length of each sentence including those in the historical data won't exceed\n * 100.\n * Please use double-quote instead of single-quote when you write test cases\n * even for a character input.\n * Please remember to RESET your class variables declared in class\n * AutocompleteSystem, as static/class variables are persisted across multiple\n * test cases. Please see here for more details.\n */\n\npublic class DesignSearchAutocompleteSystem642 {\n    // Trie\n    class AutocompleteSystem {\n        private Map<String, Integer> freq;\n        private StringBuilder currSent;\n        private Trie trie;\n        private Trie currTrie;\n\n        public AutocompleteSystem(String[] sentences, int[] times) {\n            this.freq = new HashMap<>();\n            this.trie = new Trie();\n            for (int i=0; i<sentences.length; i++) {\n                this.freq.put(sentences[i], times[i]);\n                this.trie.add(sentences[i]);\n            }\n            this.currTrie = this.trie;\n            this.currSent = new StringBuilder();\n        }\n\n        public List<String> input(char c) {\n            if (c == '#') {\n                String newSent = this.currSent.toString();\n                this.currSent = new StringBuilder();\n                this.freq.put(newSent, this.freq.getOrDefault(newSent, 0) + 1);\n                this.currTrie.sentence = newSent;\n                this.currTrie = this.trie;\n                return new ArrayList<>();\n            } else {\n                this.currSent.append(c);\n                int pos = charPos(c);\n                if (this.currTrie.children[pos] == null) {\n                    this.currTrie.children[pos] = new Trie();\n                }\n                this.currTrie = this.currTrie.children[pos];\n                PriorityQueue<String> pq = new PriorityQueue<>(3, (s1, s2) -> {\n                    int freqDiff = Integer.compare(this.freq.get(s1), this.freq.get(s2));\n                    if (freqDiff != 0) return freqDiff;\n                    return -asciiOrder(s1, s2);\n                });\n                getAllSents(this.currTrie, pq);\n                LinkedList<String> res = new LinkedList<>();\n                while (!pq.isEmpty()) {\n                    res.addFirst(pq.poll());\n                }\n                return res;\n            }\n        }\n\n        private void getAllSents(Trie t, PriorityQueue<String> pq) {\n            if (t.sentence != null) {\n                pq.add(t.sentence);\n                if (pq.size() > 3) pq.poll();\n            }\n            for (Trie child: t.children) {\n                if (child != null) {\n                    getAllSents(child, pq);\n                }\n            }\n        }\n\n        private int asciiOrder(String s1, String s2) {\n            int i = 0;\n            int len1 = s1.length();\n            int len2 = s2.length();\n            char[] chars1 = s1.toCharArray();\n            char[] chars2 = s2.toCharArray();\n            while (i < len1 && i < len2) {\n                if (chars1[i] == chars2[i]) {\n                    i++;\n                    continue;\n                }\n                return Integer.compare(chars1[i], chars2[i]);\n            }\n            return Integer.compare(len1, len2);\n        }\n\n        private int charPos(char ch) {\n            if (ch == ' ') return 26;\n            return ch - 'a';\n        }\n\n        class Trie {\n            Trie[] children = new Trie[27];\n            String sentence;\n\n            void add(String sen) {\n                add(sen.toCharArray(), 0);\n            }\n\n            void add(char[] chars, int i) {\n                if (i == chars.length) {\n                    this.sentence = new String(chars);\n                    return;\n                }\n                int pos = charPos(chars[i]);\n                if (this.children[pos] == null) {\n                    this.children[pos] = new Trie();\n                }\n                this.children[pos].add(chars, i+1);\n            }\n        }\n    }\n\n\n    // Tenary Search Tree\n    class AutocompleteSystem2 {\n        private StringBuilder sb;\n        private Map<String, Integer> freq;\n        private Node root;\n        private Node currNode;\n\n        Comparator<String> comp = (s1, s2) -> {\n            int freqDiff = Integer.compare(this.freq.get(s1), this.freq.get(s2));\n            if (freqDiff != 0) return freqDiff;\n            return -s1.compareTo(s2);\n        };\n\n        public AutocompleteSystem2(String[] sentences, int[] times) {\n            int N = sentences.length;\n            this.freq = new HashMap<>();\n            for (int i=0; i<N; i++) {\n                this.freq.put(sentences[i], times[i]);\n                this.root = addNode(this.root, sentences[i]);\n            }\n            this.currNode = this.root;\n            this.sb = new StringBuilder();\n        }\n\n        private Node addNode(Node n, String s) {\n            return addNode(n, s.toCharArray(), 0);\n        }\n\n        private Node addNode(Node n, char[] chars, int i) {\n            if (i == chars.length) {\n                return n;\n            }\n            char ch = chars[i];\n            if (n == null) {\n                n = new Node(ch);\n            }\n\n            if (ch < n.ch) {\n                n.left = addNode(n.left, chars, i);\n            } else if (ch > n.ch) {\n                n.right = addNode(n.right, chars, i);\n            } else {\n                if (i+1 < chars.length) {\n                    n.eq = addNode(n.eq, chars, i+1);\n                } else {\n                    n.sent = new String(chars);\n                }\n            }\n            return n;\n        }\n\n        public List<String> input(char c) {\n            if (c == '#') {\n                String newSent = this.sb.toString();\n                this.sb = new StringBuilder();\n                this.freq.put(newSent, this.freq.getOrDefault(newSent, 0) + 1);\n                this.root = addNode(this.root, newSent);\n                this.currNode = this.root;\n                return new ArrayList<>();\n            } else {\n                this.sb.append(c);\n                if (this.currNode == null) {\n                    return new ArrayList<>();\n                }\n                Node nn = next(this.currNode, c);\n                this.currNode = nn;\n                PriorityQueue<String> pq = new PriorityQueue<>(3, comp);\n                if (nn != null) {\n                    this.currNode = nn.eq;\n                    if (nn.sent != null) {\n                        pq.add(nn.sent);\n                    }\n                    nn = nn.eq;\n                }\n                getAllSents(nn, pq);\n                LinkedList<String> res = new LinkedList<>();\n                while (!pq.isEmpty()) {\n                    res.addFirst(pq.poll());\n                }\n                return res;\n            }\n        }\n\n        private Node next(Node n, char c) {\n            if (n == null) return null;\n            if (c < n.ch) {\n                return next(n.left, c);\n            } else if (c > n.ch) {\n                return next(n.right, c);\n            } else {\n                return n;\n            }\n        }\n\n        private void getAllSents(Node n, PriorityQueue<String> pq) {\n            if (n == null) return;\n            if (n.sent != null) {\n                pq.add(n.sent);\n                if (pq.size() > 3) pq.poll();\n            }\n            getAllSents(n.left, pq);\n            getAllSents(n.eq, pq);\n            getAllSents(n.right, pq);\n        }\n\n        class Node {\n            char ch;\n            Node left;\n            Node eq;\n            Node right;\n            String sent;\n            Node (char c) {\n                this.ch = c;\n            }\n        }\n    }\n\n\n/**\n * Your AutocompleteSystem object will be instantiated and called as such:\n * AutocompleteSystem obj = new AutocompleteSystem(sentences, times);\n * List<String> param_1 = obj.input(c);\n */\n\n}\n"
  },
  {
    "path": "src/DesignSnakeGame353.java",
    "content": "/**\n * Design a Snake game that is played on a device with screen\n * size = width x height. Play the game online if you are not familiar with\n * the game.\n * \n * The snake is initially positioned at the top left corner (0,0) with\n * length = 1 unit.\n * \n * You are given a list of food's positions in row-column order. When a snake\n * eats the food, its length and the game's score both increase by 1.\n * \n * Each food appears one by one on the screen. For example, the second food\n * will not appear until the first food was eaten by the snake.\n * \n * When a food does appear on the screen, it is guaranteed that it will not\n * appear on a block occupied by the snake.\n * \n * Example:\n * \n * Given width = 3, height = 2, and food = [[1,2],[0,1]].\n * \n * Snake snake = new Snake(width, height, food);\n * \n * Initially the snake appears at position (0,0) and the food at (1,2).\n * \n * |S| | |\n * | | |F|\n * \n * snake.move(\"R\"); -> Returns 0\n * \n * | |S| |\n * | | |F|\n * \n * snake.move(\"D\"); -> Returns 0\n * \n * | | | |\n * | |S|F|\n * \n * snake.move(\"R\"); -> Returns 1 (Snake eats the first food and right after\n * that, the second food appears at (0,1) )\n * \n * | |F| |\n * | |S|S|\n * \n * snake.move(\"U\"); -> Returns 1\n * \n * | |F|S|\n * | | |S|\n * \n * snake.move(\"L\"); -> Returns 2 (Snake eats the second food)\n * \n * | |S|S|\n * | | |S|\n * \n * snake.move(\"U\"); -> Returns -1 (Game over because snake collides with border)\n */\n\npublic class DesignSnakeGame353 {\n\n    class SnakeGame {\n        private static Map<String, int[]> directions = new HashMap<>();\n        \n        private Set<Integer> snake = new HashSet<>();\n        private Node head;\n        private Node tail;\n        private int score = 0;\n        private int width;\n        private int height;\n        private int[][] food;\n        private int nextFood = 0;\n\n        /** Initialize your data structure here.\n            @param width - screen width\n            @param height - screen height \n            @param food - A list of food positions\n            E.g food = [[1,1], [1,0]] means the first food is positioned at [1,1], the second is at [1,0]. */\n        public SnakeGame(int width, int height, int[][] food) {\n            this.width = width;\n            this.height = height;\n            this.snake.add(0);\n            this.head = new Node(0, 0);\n            this.tail = new Node(0, 0);\n            this.tail.prev = this.head;\n            this.head.next = this.tail;\n            this.food = food;\n            directions.put(\"U\", new int[]{-1, 0});\n            directions.put(\"L\", new int[]{0, -1});\n            directions.put(\"R\", new int[]{0, 1});\n            directions.put(\"D\", new int[]{1, 0});\n        }\n\n        /** Moves the snake.\n            @param direction - 'U' = Up, 'L' = Left, 'R' = Right, 'D' = Down \n            @return The game's score after the move. Return -1 if game over. \n            Game over when snake crosses the screen boundary or bites its body. */\n        public int move(String direction) {\n            int[] dir = directions.get(direction);\n            int nextX = head.x + dir[0];\n            int nextY = head.y + dir[1];\n            if (nextX < 0 || nextY < 0 || nextX >= this.height || nextY >= this.width) return -1;\n            Node newHead = new Node(nextX, nextY);\n            newHead.next = this.head;\n            this.head.prev = newHead;\n            this.head = newHead;\n            if (isFood(nextX, nextY)) {\n                this.score++;\n                moveNextFood();\n            } else {\n                this.tail = this.tail.prev;\n                this.tail.next = null;\n                this.snake.remove(this.tail.x * this.width + this.tail.y);\n            }\n            int nextPos = nextX * this.width + nextY;\n            if (this.snake.contains(nextPos)) return -1;\n            this.snake.add(nextPos);\n            return this.score;\n        }\n\n        private void moveNextFood() {\n            if (this.nextFood < this.food.length) {\n                this.nextFood++;\n            }\n        }\n\n        private boolean isFood(int nextX, int nextY) {\n            if (this.nextFood >= this.food.length) return false;\n            return this.food[this.nextFood][0] == nextX && this.food[this.nextFood][1] == nextY;\n        }\n\n        class Node {\n            int x;\n            int y;\n            Node prev;\n            Node next;\n            Node(int i, int j) {\n                this.x = i;\n                this.y = j;\n            }\n        }\n    }\n\n\n/**\n * Your SnakeGame object will be instantiated and called as such:\n * SnakeGame obj = new SnakeGame(width, height, food);\n * int param_1 = obj.move(direction);\n */\n\n}\n\n"
  },
  {
    "path": "src/DesignTicTacToe348.java",
    "content": "/**\n * Design a Tic-tac-toe game that is played between two players on a n x n grid.\n * \n * You may assume the following rules:\n * \n * A move is guaranteed to be valid and is placed on an empty block.\n * Once a winning condition is reached, no more moves is allowed.\n * A player who succeeds in placing n of their marks in a horizontal, vertical,\n * or diagonal row wins the game.\n * \n * Example:\n * Given n = 3, assume that player 1 is \"X\" and player 2 is \"O\" in the board.\n * \n * TicTacToe toe = new TicTacToe(3);\n * \n * toe.move(0, 0, 1); -> Returns 0 (no one wins)\n * |X| | |\n * | | | |    // Player 1 makes a move at (0, 0).\n * | | | |\n * \n * toe.move(0, 2, 2); -> Returns 0 (no one wins)\n * |X| |O|\n * | | | |    // Player 2 makes a move at (0, 2).\n * | | | |\n * \n * toe.move(2, 2, 1); -> Returns 0 (no one wins)\n * |X| |O|\n * | | | |    // Player 1 makes a move at (2, 2).\n * | | |X|\n * \n * toe.move(1, 1, 2); -> Returns 0 (no one wins)\n * |X| |O|\n * | |O| |    // Player 2 makes a move at (1, 1).\n * | | |X|\n * \n * toe.move(2, 0, 1); -> Returns 0 (no one wins)\n * |X| |O|\n * | |O| |    // Player 1 makes a move at (2, 0).\n * |X| |X|\n * \n * toe.move(1, 0, 2); -> Returns 0 (no one wins)\n * |X| |O|\n * |O|O| |    // Player 2 makes a move at (1, 0).\n * |X| |X|\n * \n * toe.move(2, 1, 1); -> Returns 1 (player 1 wins)\n * |X| |O|\n * |O|O| |    // Player 1 makes a move at (2, 1).\n * |X|X|X|\n * \n * Follow up:\n * Could you do better than O(n2) per move() operation?\n */\n\n\npublic class DesignTicTacToe348 {\n    class TicTacToe {\n        private Set<Integer>[] player1Rows;\n        private Set<Integer>[] player1Cols;\n        private Set<Integer>[] player1Dias;\n        \n        private Set<Integer>[] player2Rows;\n        private Set<Integer>[] player2Cols;\n        private Set<Integer>[] player2Dias;\n        \n        private int n;\n        \n        /** Initialize your data structure here. */\n        public TicTacToe(int n) {\n            this.n = n;\n            this.player1Rows = new Set[n];\n            for (int i=0; i<n; i++) this.player1Rows[i] = new HashSet<>();\n            this.player1Cols = new Set[n];\n            for (int i=0; i<n; i++) this.player1Cols[i] = new HashSet<>();\n            this.player1Dias = new Set[2];\n            for (int i=0; i<2; i++) this.player1Dias[i] = new HashSet<>();\n            \n            this.player2Rows = new Set[n];\n            for (int i=0; i<n; i++) this.player2Rows[i] = new HashSet<>();\n            this.player2Cols = new Set[n];\n            for (int i=0; i<n; i++) this.player2Cols[i] = new HashSet<>();\n            this.player2Dias = new Set[2];\n            for (int i=0; i<2; i++) this.player2Dias[i] = new HashSet<>();\n        }\n        \n        /** Player {player} makes a move at ({row}, {col}).\n            @param row The row of the board.\n            @param col The column of the board.\n            @param player The player, can be either 1 or 2.\n            @return The current winning condition, can be either:\n                    0: No one wins.\n                    1: Player 1 wins.\n                    2: Player 2 wins. */\n        public int move(int row, int col, int player) {\n            if (player == 1) {\n                this.player1Rows[row].add(col);\n                if (this.player1Rows[row].size() == n) return 1;\n                this.player1Cols[col].add(row);\n                if (this.player1Cols[col].size() == n) return 1;\n                if (row == col) {\n                    this.player1Dias[0].add(row);\n                    if (this.player1Dias[0].size() == n) return 1;\n                }\n                if (row == n-col-1) {\n                    this.player1Dias[1].add(row);\n                    if (this.player1Dias[1].size() == n) return 1;\n                }\n            } else if (player == 2) {\n                this.player2Rows[row].add(col);\n                if (this.player2Rows[row].size() == n) return 2;\n                this.player2Cols[col].add(row);\n                if (this.player2Cols[col].size() == n) return 2;\n                if (row == col) {\n                    this.player2Dias[0].add(row);\n                    if (this.player2Dias[0].size() == n) return 2;\n                }\n                if (row == n-col-1) {\n                    this.player2Dias[1].add(row);\n                    if (this.player2Dias[1].size() == n) return 2;\n                }\n            }\n            return 0;\n        }\n    }\n    \n\n    /**\n     * https://leetcode.com/problems/design-tic-tac-toe/discuss/81898/Java-O(1)-solution-easy-to-understand\n     */\n    class TicTacToe2 {\n        private int[] rows;\n        private int[] cols;\n        private int diagonal;\n        private int antiDiagonal;\n        \n        /** Initialize your data structure here. */\n        public TicTacToe(int n) {\n            rows = new int[n];\n            cols = new int[n];\n        }\n        \n        /** Player {player} makes a move at ({row}, {col}).\n            @param row The row of the board.\n            @param col The column of the board.\n            @param player The player, can be either 1 or 2.\n            @return The current winning condition, can be either:\n                    0: No one wins.\n                    1: Player 1 wins.\n                    2: Player 2 wins. */\n        public int move(int row, int col, int player) {\n            int toAdd = player == 1 ? 1 : -1;\n            \n            rows[row] += toAdd;\n            cols[col] += toAdd;\n            if (row == col)\n            {\n                diagonal += toAdd;\n            }\n            \n            if (col == (cols.length - row - 1))\n            {\n                antiDiagonal += toAdd;\n            }\n            \n            int size = rows.length;\n            if (Math.abs(rows[row]) == size ||\n                Math.abs(cols[col]) == size ||\n                Math.abs(diagonal) == size  ||\n                Math.abs(antiDiagonal) == size)\n            {\n                return player;\n            }\n            \n            return 0;\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/design-tic-tac-toe/discuss/81896/78-lines-O(1)-JavaPython\n     */\n    class TicTacToe3 {\n        public TicTacToe(int n) {\n            count = new int[6*n][3];\n        }\n\n        public int move(int row, int col, int player) {\n            int n = count.length / 6;\n            for (int x : new int[]{row, n+col, 2*n+row+col, 5*n+row-col})\n                if (++count[x][player] == n)\n                    return player;\n            return 0;\n        }\n\n        int[][] count;\n    }\n\n    class TicTacToe4 {\n        private int[] rows;\n        private int[] cols;\n        private int diag1;\n        private int diag2;\n        private int N;\n\n        /** Initialize your data structure here. */\n        public TicTacToe4(int n) {\n            this.rows = new int[n];\n            this.cols = new int[n];\n            this.diag1 = 0;\n            this.diag2 = 0;\n            this.N = n;\n        }\n\n        /** Player {player} makes a move at ({row}, {col}).\n            @param row The row of the board.\n            @param col The column of the board.\n            @param player The player, can be either 1 or 2.\n            @return The current winning condition, can be either:\n                    0: No one wins.\n                    1: Player 1 wins.\n                    2: Player 2 wins. */\n        public int move(int row, int col, int player) {\n            int diff = player == 1 ? 1 : -1;\n            this.rows[row] += diff;\n            this.cols[col] += diff;\n            if (row == col) this.diag1 += diff;\n            if (row + col == N-1) this.diag2 += diff;\n            if (this.rows[row] == N || this.cols[col] == N || this.diag1 == N || this.diag2 == N) return 1;\n            if (this.rows[row] == -N || this.cols[col] == -N || this.diag1 == -N || this.diag2 == -N) return 2;\n            return 0;\n        }\n    }\n\n/**\n * Your TicTacToe object will be instantiated and called as such:\n * TicTacToe obj = new TicTacToe(n);\n * int param_1 = obj.move(row,col,player);\n */\n  \n\n}\n\n"
  },
  {
    "path": "src/DesignTwitter355.java",
    "content": "/**\n * Design a simplified version of Twitter where users can post tweets,\n * follow/unfollow another user and is able to see the 10 most recent tweets\n * in the user's news feed. Your design should support the following methods:\n * \n * postTweet(userId, tweetId): Compose a new tweet.\n *\n * getNewsFeed(userId): Retrieve the 10 most recent tweet ids in the user's\n * news feed. Each item in the news feed must be posted by users who the user\n * followed or by the user herself. Tweets must be ordered from most recent to\n * least recent.\n *\n * follow(followerId, followeeId): Follower follows a followee.\n *\n * unfollow(followerId, followeeId): Follower unfollows a followee.\n * \n * Example:\n * \n * Twitter twitter = new Twitter();\n * \n * // User 1 posts a new tweet (id = 5).\n * twitter.postTweet(1, 5);\n * \n * // User 1's news feed should return a list with 1 tweet id -> [5].\n * twitter.getNewsFeed(1);\n * \n * // User 1 follows user 2.\n * twitter.follow(1, 2);\n * \n * // User 2 posts a new tweet (id = 6).\n * twitter.postTweet(2, 6);\n * \n * // User 1's news feed should return a list with 2 tweet ids -> [6, 5].\n * // Tweet id 6 should precede tweet id 5 because it is posted after tweet id 5.\n * twitter.getNewsFeed(1);\n * \n * // User 1 unfollows user 2.\n * twitter.unfollow(1, 2);\n * \n * // User 1's news feed should return a list with 1 tweet id -> [5],\n * // since user 1 is no longer following user 2.\n * twitter.getNewsFeed(1);\n */\n\n\npublic class DesignTwitter355 {\n    class Twitter {\n        private int time = 0;\n        private Map<Integer, User> map = new HashMap<>();\n        private static final Comparator<Tweet> comp = (t1, t2) -> Long.compare(t2.timestamp, t1.timestamp);\n        \n        /** Initialize your data structure here. */\n        public Twitter() {\n        }\n\n        /** Compose a new tweet. */\n        public void postTweet(int userId, int tweetId) {\n            if (!map.containsKey(userId)) map.put(userId, new User(userId));\n            map.get(userId).addTweet(tweetId, time++);\n        }\n\n        /**\n         * Retrieve the 10 most recent tweet ids in the user's news feed. Each\n         * item in the news feed must be posted by users who the user followed\n         * or by the user herself. Tweets must be ordered from most recent to\n         * least recent.\n         */\n        public List<Integer> getNewsFeed(int userId) {\n            PriorityQueue<Tweet> pq = new PriorityQueue<>(10, comp);\n            if (!map.containsKey(userId)) return new ArrayList<Integer>();\n            User me = map.get(userId);\n            for (Integer uid: me.following) {\n                pq.addAll(map.get(uid).tweets);\n            }\n            pq.addAll(me.tweets);\n            List<Integer> ids = new ArrayList<>();\n            int size = pq.size();\n            for (int i=0; i<10 && i<size; i++) {\n                ids.add(pq.poll().id);\n            }\n            return ids;\n        }\n\n        /**\n         * Follower follows a followee. If the operation is invalid,\n         * it should be a no-op.\n         */\n        public void follow(int followerId, int followeeId) {\n            if (!map.containsKey(followerId)) map.put(followerId, new User(followerId));\n            if (!map.containsKey(followeeId)) map.put(followeeId, new User(followeeId));\n            if (followerId == followeeId) return;\n            map.get(followerId).follow(followeeId);\n        }\n\n        /**\n         * Follower unfollows a followee. If the operation is invalid,\n         * it should be a no-op.\n         */\n        public void unfollow(int followerId, int followeeId) {\n            if (!map.containsKey(followerId)) map.put(followerId, new User(followerId));\n            if (!map.containsKey(followeeId)) map.put(followeeId, new User(followeeId));\n            if (followerId == followeeId) return;\n            map.get(followerId).unfollow(followeeId);\n        }\n\n        class User {\n            int id;\n            LinkedList<Tweet> tweets = new LinkedList<>();\n            Set<Integer> following = new HashSet<>();\n            User(int i) {\n                id = i;\n            }\n\n            public void addTweet(int i, int ts) {\n                tweets.add(new Tweet(i, ts));\n                while (tweets.size() > 10) {\n                    tweets.removeFirst();\n                }\n            }\n\n            public void follow(int userId) {\n                following.add(userId);\n            }\n\n            public void unfollow(int userId) {\n                if (following.contains(userId)) {\n                    following.remove(userId);\n                }\n            }\n        }\n\n        class Tweet {\n            int id;\n            int timestamp;\n            Tweet(int i, int ts) {\n                id = i;\n                timestamp = ts;\n            }\n        }\n    }\n\n/**\n * Your Twitter object will be instantiated and called as such:\n * Twitter obj = new Twitter();\n * obj.postTweet(userId,tweetId);\n * List<Integer> param_2 = obj.getNewsFeed(userId);\n * obj.follow(followerId,followeeId);\n * obj.unfollow(followerId,followeeId);\n */\n\n}\n"
  },
  {
    "path": "src/DiagonalTraverse498.java",
    "content": "/**\n * Given a matrix of M x N elements (M rows, N columns), return all elements\n * of the matrix in diagonal order as shown in the below image.\n * \n * Example:\n * Input:\n * [\n *  [ 1, 2, 3 ],\n *  [ 4, 5, 6 ],\n *  [ 7, 8, 9 ]\n * ]\n * Output:  [1,2,4,7,5,3,6,8,9]\n * \n * Explanation:\n *    https://leetcode.com/static/images/problemset/diagonal_traverse.png\n * \n * Note:\n * The total number of elements of the given matrix will not exceed 10,000.\n */\n\n\npublic class DiagonalTraverse498 {\n    public int[] findDiagonalOrder(int[][] matrix) {\n        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return new int[0];\n        int M = matrix.length;\n        int N = matrix[0].length;\n        int total = M * N;\n        int[] res = new int[total];\n        int i = 0;\n        int[] pos = new int[2];\n        res[i++] = matrix[0][0];\n        while (i < total) {\n            pos = next(pos, M, N);\n            res[i++] = matrix[pos[0]][pos[1]];\n        }\n        return res;\n    }\n\n    private int[] next(int[] pos, int M, int N) {\n        int i = pos[0];\n        int j = pos[1];\n        if (isEven(i+j)) { // top-right\n            int ni = i - 1;\n            int nj = j + 1;\n            if (nj == N) {\n                nj = N - 1;\n                ni = i + 1;\n            } else if (ni < 0) {\n                ni = 0;\n            }\n            return new int[]{ni, nj};\n        } else { // bottom-left\n            int ni = i + 1;\n            int nj = j - 1;\n            if (ni == M) {\n                ni = M - 1;\n                nj = j + 1;\n            } else if (nj < 0) {\n                nj = 0;\n            }\n            return new int[]{ni, nj};\n        }\n    }\n    \n    private boolean isEven(int x) {\n        return x % 2 == 0;\n    }\n\n}\n"
  },
  {
    "path": "src/DiameterOfBinaryTree543.java",
    "content": "/**\n * Given a binary tree, you need to compute the length of the diameter of the\n * tree. The diameter of a binary tree is the length of the longest pathbetween\n * any two nodes in a tree. This path may or may not pass through the root.\n *\n * Example:\n * Given a binary tree\n *           1\n *          / \\\n *         2   3\n *        / \\\n *       4   5\n * Return 3, which is the length of the path [4,2,1,3] or [5,2,1,3].\n *\n * Note: The length of path between two nodes is represented by the number of\n * edges between them.\n *\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class DiameterOfBinaryTree543 {\n    public int diameterOfBinaryTree(TreeNode root) {\n        return helper(root)[0];\n    }\n\n    private int[] helper(TreeNode root) {\n        if (root == null) return new int[]{0, 0};\n\n        int[] l = helper(root.left);\n        int[] r = helper(root.right);\n\n        return new int[]{Math.max(Math.max(l[0], r[0]), l[1] + r[1]), Math.max(l[1], r[1]) + 1};\n    }\n\n}\n"
  },
  {
    "path": "src/DifferentWaysToAddParentheses241.java",
    "content": "/**\n * Given a string of numbers and operators, return all possible results from\n * computing all the different possible ways to group numbers and operators.\n * The valid operators are +, - and *.\n *\n * Example 1\n * Input: \"2-1-1\".\n *\n * ((2-1)-1) = 0\n * (2-(1-1)) = 2\n * Output: [0, 2]\n *\n *\n * Example 2\n * Input: \"2*3-4*5\"\n *\n * (2*(3-(4*5))) = -34\n * ((2*3)-(4*5)) = -14\n * ((2*(3-4))*5) = -10\n * (2*((3-4)*5)) = -10\n * (((2*3)-4)*5) = 10\n * Output: [-34, -14, -10, -10, 10]\n *\n */\n\n\npublic class DifferentWaysToAddParentheses241 {\n    public List<Integer> diffWaysToCompute(String input) {\n        List<Integer> res = new LinkedList<Integer>();\n        for (int i=0; i<input.length(); i++) {\n            char c = input.charAt(i);\n            if (c != '-' && c != '*' && c != '+' ) continue;\n            List<Integer> res1 = diffWaysToCompute(input.substring(0, i));\n            List<Integer> res2 = diffWaysToCompute(input.substring(i+1));\n            for (Integer int1: res1) {\n                for (Integer int2: res2) {\n                    res.add(cal(int1, int2, c));\n                }\n            }\n        }\n        if (res.size() == 0) {\n            res.add(Integer.valueOf(input));\n        }\n        return res;\n    }\n\n    private Integer cal(Integer int1, Integer int2, Character op) {\n        switch (op) {\n            case '+':\n                return int1 + int2;\n            case '-':\n                return int1 - int2;\n            case '*':\n                return int1 * int2;\n        }\n        return 0;\n    }\n}\n"
  },
  {
    "path": "src/DivideTwoIntegers29.java",
    "content": "/**\n * Divide two integers without using multiplication, division and mod operator.\n *\n * If it is overflow, return MAX_INT.\n */\n\npublic class DivideTwoIntegers29 {\n    public int divide(int dividend, int divisor) {\n        if (divisor == 0) return Integer.MAX_VALUE;\n        if (dividend == 0) return 0;\n        long result = helper(dividend, divisor);\n        return result > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) result;\n    }\n\n    public long helper(long dividend, long divisor) {\n        boolean isNegative = dividend < 0 != divisor < 0;\n        dividend = Math.abs(dividend);\n        divisor = Math.abs(divisor);\n        if (dividend < divisor) return 0;\n\n        long res = 0;\n        while (dividend >= divisor) {\n            long t = divisor;\n            long p = 1;\n            long tt = t << 1;\n            while (dividend > tt) {\n                t = tt;\n                p <<= 1;\n                tt <<= 1;\n            }\n            res += p;\n            dividend -= t;\n        }\n        return isNegative ? -res : res;\n    }\n\n}\n"
  },
  {
    "path": "src/DominoAndTrominoTiling790.java",
    "content": "/**\n * We have two types of tiles: a 2x1 domino shape, and an \"L\" tromino shape.\n * These shapes may be rotated.\n * \n * XX  <- domino\n * \n * XX  <- \"L\" tromino\n * X\n * Given N, how many ways are there to tile a 2 x N board? Return your answer\n * modulo 10^9 + 7.\n * \n * (In a tiling, every square must be covered by a tile. Two tilings are\n * different if and only if there are two 4-directionally adjacent cells on\n * the board such that exactly one of the tilings has both squares occupied\n * by a tile.)\n * \n * Example:\n * Input: 3\n * Output: 5\n * Explanation: \n * The five different ways are listed below, different letters indicates\n * different tiles:\n * XYZ XXZ XYY XXY XYY\n * XYZ YYZ XZZ XYY XXY\n */\n\npublic class DominoAndTrominoTiling790 {\n\n    private static int MOD = 1000000007;\n\n    public int numTilings(int N) {\n        long[][] dp = new long[N+1][3];\n        dp[0][0] = 1;\n        dp[1][0] = 1;\n        for (int i=2; i<=N; i++) {\n            dp[i][0] = (dp[i-1][0] + dp[i-2][0] + dp[i-1][1] + dp[i-1][2]) % MOD;\n            dp[i][1] = (dp[i-2][0] + dp[i-1][2]) % MOD;\n            dp[i][2] = (dp[i-2][0] + dp[i-1][1]) % MOD;\n        }\n        return (int) dp[N][0];\n    }\n\n\n    public int numTilings2(int N) {\n        long[][] dp = new long[N+1][2];\n        dp[0][0] = 1;\n        dp[1][0] = 1;\n        for (int i=2; i<=N; i++) {\n            dp[i][0] = (dp[i-1][0] + dp[i-2][0] + 2 * dp[i-1][1]) % MOD;\n            dp[i][1] = (dp[i-2][0] + dp[i-1][1]) % MOD;\n        }\n        return (int) dp[N][0];\n    }\n\n\n    public int numTilings3(int N) {\n        long[][] dp = new long[3][2];\n        dp[0][0] = 1;\n        dp[1][0] = 1;\n        for (int i=2; i<=N; i++) {\n            dp[i%3][0] = (dp[(i+2)%3][0] + dp[(i+1)%3][0] + 2 * dp[(i+2)%3][1]) % MOD;\n            dp[i%3][1] = (dp[(i+1)%3][0] + dp[(i+2)%3][1]) % MOD;\n        }\n        return (int) dp[N%3][0];\n    }\n\n\n    public int numTilings4(int N) {\n        if (N == 0) return 1;\n        if (N == 1 || N == 2) return N; \n        long[] dp = new long[N+1];\n        dp[0] = 1;\n        dp[1] = 1;\n        dp[2] = 2;\n        for (int i=3; i<=N; i++) {\n            dp[i] = (dp[i - 3] + dp[i - 1] * 2) % MOD;\n        }\n        return (int) dp[N];\n    }\n\n\n    public int numTilings5(int N) {\n        if (N == 0) return 1;\n        if (N == 1 || N == 2) return N; \n        long[] dp = new long[4];\n        dp[0] = 1;\n        dp[1] = 1;\n        dp[2] = 2;\n        for (int i=3; i<=N; i++) {\n            dp[i%4] = (dp[(i+1)%4] + dp[(i+3)%4] * 2) % MOD;\n        }\n        return (int) dp[N%4];\n    }\n\n\n    /**\n     * https://leetcode.com/problems/domino-and-tromino-tiling/solution/\n     */\n    public int numTilings6(int N) {\n        long[] dp = new long[]{1, 0, 0, 0};\n        for (int i = 0; i < N; ++i) {\n            long[] ndp = new long[4];\n            ndp[0b00] = (dp[0b00] + dp[0b11]) % MOD;\n            ndp[0b01] = (dp[0b00] + dp[0b10]) % MOD;\n            ndp[0b10] = (dp[0b00] + dp[0b01]) % MOD;\n            ndp[0b11] = (dp[0b00] + dp[0b01] + dp[0b10]) % MOD;\n            dp = ndp;\n        }\n        return (int) dp[0];\n    }\n\n}\n"
  },
  {
    "path": "src/EditDistance72.java",
    "content": "/**\n * Given two words word1 and word2, find the minimum number of steps required\n * to convert word1 to word2. (each operation is counted as 1 step.)\n *\n * You have the following 3 operations permitted on a word:\n *\n * a) Insert a character\n * b) Delete a character\n * c) Replace a character\n */\n\nimport java.util.Arrays;\n\npublic class EditDistance72 {\n    // time: O(mn); space: O(mn)\n    public int minDistance(String word1, String word2) {\n        int m = word1.length();\n        int n = word2.length();\n        int[][] d = new int[m + 1][n + 1];\n        for (int i = 0; i <= m; i++) d[i][0] = i;\n        for (int i = 1; i <= n; i++) d[0][i] = i;\n\n        for (int i = 1; i <= m; i++) {\n            for (int j = 1; j <= n; j++) {\n                if (word1.charAt(i-1) == word2.charAt(j-1)) {\n                    d[i][j] = d[i-1][j-1];\n                } else {\n                    d[i][j] = Math.min(d[i-1][j], d[i][j-1]) + 1;\n                    d[i][j] = Math.min(d[i][j], d[i-1][j-1] + 1);\n                }\n            }\n        }\n\n        return d[m][n];\n    }\n\n\n    // time: O(mn); space: O(n)\n    public int minDistance2(String word1, String word2) {\n        int m = word1.length();\n        int n = word2.length();\n\n        if (n == 0) {\n            return m;\n        }\n\n        int[] d = new int[n + 1];\n\n        for (int j = 0; j <= n; j++)\n            d[j] = j;\n\n        for (int i = 1; i <= m; i++) {\n            int last = d[0];\n            for (int j = 1; j <= n; j++) {\n                int saveLast = d[j];\n                d[0] = i;\n                if (word1.charAt(i-1) == word2.charAt(j-1)) {\n                    d[j] = last;\n                } else {\n                    d[j] = Math.min(d[j], d[j-1]) + 1;\n                    d[j] = Math.min(d[j], last + 1);\n                }\n                last = saveLast;\n            }\n        }\n\n        return d[n];\n    }\n\n\n    public int minDistance3(String word1, String word2) {\n        int len1 = word1.length();\n        int len2 = word2.length();\n        if (len1 == 0) return len2;\n        if (len2 == 0) return len1;\n\n        int[] dp = new int[len2+1];\n        for (int j=0; j<=len2; j++) dp[j] = j;\n        \n        for (int i=1; i<=len1; i++) {\n            int pre = dp[0];\n            dp[0] = i;\n            for (int j=1; j<=len2; j++) {\n                int nextPre = dp[j];\n                dp[j] = Math.min(pre + (word1.charAt(i-1) == word2.charAt(j-1) ? 0 : 1),\n                                   Math.min(dp[j], dp[j-1]) + 1);\n                pre = nextPre;\n            }\n            \n        }\n        return dp[len2];\n    }\n\n    public static void main(String[] args) {\n        EditDistance72 ed = new EditDistance72();\n\n        System.out.println(ed.minDistance2(\"word1\", \"word3\"));\n        System.out.println(ed.minDistance2(\"aaabbb\", \"aababb\"));\n        System.out.println(ed.minDistance2(\"b\", \"\"));\n        System.out.println(ed.minDistance2(\"\", \"b\"));\n    }\n}\n"
  },
  {
    "path": "src/EmployeeFreeTime759.java",
    "content": "/**\n * We are given a list schedule of employees, which represents the working time\n * for each employee.\n * \n * Each employee has a list of non-overlapping Intervals, and these intervals\n * are in sorted order.\n * \n * Return the list of finite intervals representing common, positive-length\n * free time for all employees, also in sorted order.\n * \n * Example 1:\n * Input: schedule = [[[1,2],[5,6]],[[1,3]],[[4,10]]]\n * Output: [[3,4]]\n * Explanation:\n * There are a total of three employees, and all common\n * free time intervals would be [-inf, 1], [3, 4], [10, inf].\n * We discard any intervals that contain inf as they aren't finite.\n * \n * Example 2:\n * Input: schedule = [[[1,3],[6,7]],[[2,4]],[[2,5],[9,12]]]\n * Output: [[5,6],[7,9]]\n * (Even though we are representing Intervals in the form [x, y], the objects\n * inside are Intervals, not lists or arrays. For example,\n * schedule[0][0].start = 1, schedule[0][0].end = 2, and\n * schedule[0][0][0] is not defined.)\n * \n * Also, we wouldn't include intervals like [5, 5] in our answer, as they have\n * zero length.\n * \n * Note:\n * schedule and schedule[i] are lists with lengths in range [1, 50].\n * 0 <= schedule[i].start < schedule[i].end <= 10^8.\n */\n\n/**\n * Definition for an interval.\n * public class Interval {\n *     int start;\n *     int end;\n *     Interval() { start = 0; end = 0; }\n *     Interval(int s, int e) { start = s; end = e; }\n * }\n */\n\npublic class EmployeeFreeTime759 {\n    public List<Interval> employeeFreeTime(List<List<Interval>> schedule) {\n        if (schedule == null || schedule.size() == 0) return new ArrayList<>();\n        LinkedList<Integer> starts = new LinkedList<>();\n        LinkedList<Integer> ends = new LinkedList<>();\n        for (List<Interval> emp: schedule) {\n            for (Interval inv: emp) {\n                starts.add(inv.start);\n                ends.add(inv.end);\n            }\n        }\n        Collections.sort(starts);\n        Collections.sort(ends);\n        List<Interval> res = new ArrayList<>();\n        int count = 0;\n        int time = Integer.MIN_VALUE;\n        while (!starts.isEmpty() && !ends.isEmpty()) {\n            if (starts.getFirst() <= ends.getFirst()) {\n                count++;\n                time = starts.getFirst();\n                starts.removeFirst();\n            } else {\n                count--;\n                time = ends.getFirst();\n                ends.removeFirst();\n            }\n\n            if (count == 0 && !starts.isEmpty() && time < starts.getFirst()) {\n                res.add(new Interval(time, starts.getFirst()));\n            }\n        }\n        return res;\n    }\n\n\n\n    public List<Interval> employeeFreeTime2(List<List<Interval>> schedule) {\n        if (schedule == null || schedule.size() == 0) return new ArrayList<>();\n        Comparator<Interval> comp = (i1, i2) -> Integer.compare(i1.start ,i2.start);\n        PriorityQueue<Interval> pq = new PriorityQueue<>(1, comp);\n        for (List<Interval> emp: schedule) {\n            for (Interval inv: emp) {\n                pq.add(inv);\n            }\n        }\n        List<Interval> res = new ArrayList<>();\n        if (pq.isEmpty()) return res;\n        int maxEnd = pq.poll().end;\n        while (!pq.isEmpty()) {\n            Interval curr = pq.poll();\n            if (curr.start <= maxEnd) {\n                maxEnd = Math.max(maxEnd, curr.end);\n            } else {\n                res.add(new Interval(maxEnd, curr.start));\n                maxEnd = curr.end;\n            }\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/EncodeAndDecodeStrings271.java",
    "content": "/**\n * Design an algorithm to encode a list of strings to a string. The encoded\n * string is then sent over the network and is decoded back to the original\n * list of strings.\n * \n * Machine 1 (sender) has the function:\n * \n * string encode(vector<string> strs) {\n *   // ... your code\n *   return encoded_string;\n * }\n * \n * \n * Machine 2 (receiver) has the function:\n * vector<string> decode(string s) {\n *   //... your code\n *   return strs;\n * }\n * \n * \n * So Machine 1 does:\n * string encoded_string = encode(strs);\n * \n * and Machine 2 does:\n * vector<string> strs2 = decode(encoded_string);\n * \n * strs2 in Machine 2 should be the same as strs in Machine 1.\n * \n * Implement the encode and decode methods.\n * \n * Note:\n * The string may contain any possible characters out of 256 valid ascii\n * characters. Your algorithm should be generalized enough to work on any\n * possible characters.\n * Do not use class member/global/static variables to store states. Your\n * encode and decode algorithms should be stateless.\n * Do not rely on any library method such as eval or serialize methods. You\n * should implement your own encode/decode algorithm.\n */\n\npublic class EncodeAndDecodeStrings271 {\n    public class Codec {\n\n        // Encodes a list of strings to a single string.\n        public String encode(List<String> strs) {\n            StringBuilder sb = new StringBuilder();\n            for (String str: strs) {\n                sb.append(str.length()).append('|').append(str);\n            }\n            return sb.toString();\n        }\n\n        // Decodes a single string to a list of strings.\n        public List<String> decode(String s) {\n            List<String> list = new ArrayList<>();\n            int i=0;\n            while (i < s.length()) {\n                int j = i;\n                while (s.charAt(j) != '|') j++;\n                String sizeString = s.substring(i, j);\n                int size = Integer.valueOf(sizeString);\n                String str = s.substring(j+1, j+size+1);\n                list.add(str);\n                i += sizeString.length() + 1 + size;\n            }\n            return list;\n        }\n    }\n\n    // Your Codec object will be instantiated and called as such:\n    // Codec codec = new Codec();\n    // codec.decode(codec.encode(strs));\n\n}\n"
  },
  {
    "path": "src/EncodeAndDecodeTinyURL535.java",
    "content": "/**\n * Note: This is a companion problem to the System Design problem:\n * Design TinyURL (https://leetcode.com/problems/design-tinyurl/)\n *\n * TinyURL is a URL shortening service where you enter a URL such as\n * https://leetcode.com/problems/design-tinyurl and it returns a short URL\n * such as http://tinyurl.com/4e9iAk.\n *\n * Design the encode and decode methods for the TinyURL service. There is no\n * restriction on how your encode/decode algorithm should work. You just need\n * to ensure that a URL can be encoded to a tiny URL and the tiny URL can be\n * decoded to the original URL.\n *\n */\n\npublic class EncodeAndDecodeTinyURL535 {\n    public class Codec {\n        public static final char[] ALPHABETS = {\n            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',\n            'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',\n            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',\n            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '-', '_'\n        };\n        public static final int BASE = 64;\n        public static final Random rand = new Random();\n\n        private Map<String, String> lookup = new HashMap<>();\n\n        // Encodes a URL to a shortened URL.\n        public String encode(String longUrl) {\n            StringBuilder str = new StringBuilder();\n            for (int i=0; i<7; i++) {\n                str.append(ALPHABETS[rand.nextInt(BASE)]);\n            }\n            String key = str.toString();\n            lookup.put(key, longUrl);\n            return key;\n        }\n\n        // Decodes a shortened URL to its original URL.\n        public String decode(String shortUrl) {\n            return lookup.get(shortUrl);\n        }\n    }\n\n\n    public class Codec2 {\n\n        private char[] BASE62 = new char[]{\n            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',\n            'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',\n            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',\n            'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',\n            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'\n        };\n        \n        Map<String, String> map = new HashMap<>();\n        int id = 0;\n        \n        // Encodes a URL to a shortened URL.\n        public String encode(String longUrl) {\n            StringBuilder sb = new StringBuilder();\n            int n = id;\n            while (n != 0) {\n                sb.append(BASE62[n % 26]);\n                n /= 62;\n            }\n            sb.append(BASE62[n % 26]);\n            String key = sb.toString();\n            if (!map.containsKey(key)) {\n                map.put(key, longUrl);\n                id++;\n            }\n            return key;\n        }\n    \n        // Decodes a shortened URL to its original URL.\n        public String decode(String shortUrl) {\n            return map.get(shortUrl);\n        }\n    }\n\n\n    // Your Codec object will be instantiated and called as such:\n    // Codec codec = new Codec();\n    // codec.decode(codec.encode(url));\n\n}\n"
  },
  {
    "path": "src/EqualTreePartition663.java",
    "content": "/**\n * Given a binary tree with n nodes, your task is to check if it's possible to\n * partition the tree to two trees which have the equal sum of values after\n * removing exactly one edge on the original tree.\n * \n * Example 1:\n * Input:     \n *     5\n *    / \\\n *   10 10\n *     /  \\\n *    2   3\n * \n * Output: True\n * \n * Explanation: \n *     5\n *    / \n *   10\n * Sum: 15\n * \n *    10\n *   /  \\\n *  2    3\n * Sum: 15\n * \n * Example 2:\n * \n * Input:     \n *     1\n *    / \\\n *   2  10\n *     /  \\\n *    2   20\n * \n * Output: False\n * \n * Explanation: You can't split the tree into two trees with equal sum after\n * removing exactly one edge on the tree.\n * \n * Note:\n * The range of tree node value is in the range of [-100000, 100000].\n * 1 <= n <= 10000\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class EqualTreePartition663 {\n    public boolean checkEqualTree(TreeNode root) {\n        Set<Integer> set = new HashSet<>();\n        int total = sum(root, set, true);\n        return total % 2 == 0 && set.contains(total / 2);\n    }\n\n    private int sum(TreeNode root, Set<Integer> set, boolean isRoot) {\n        if (root == null) return 0;\n        int left = sum(root.left, set, false);\n        int right = sum(root.right, set, false);\n        int s = left + root.val + right;\n        if (!isRoot) set.add(s);\n        return s;\n    }\n\n}\n"
  },
  {
    "path": "src/EvaluateDivision399.java",
    "content": "/**\n * Equations are given in the format A / B = k, where A and B are variables\n * represented as strings, and k is a real number (floating point number).\n * Given some queries, return the answers. If the answer does not exist,\n * return -1.0.\n *\n * Example:\n * Given a / b = 2.0, b / c = 3.0.\n * queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? .\n * return [6.0, 0.5, -1.0, 1.0, -1.0 ].\n *\n * The input is: vector<pair<string, string>> equations, vector<double>& values,\n * vector<pair<string, string>> queries , where equations.size() == values.size(),\n * and the values are positive. This represents the equations.\n * Return vector<double>.\n *\n * According to the example above:\n *\n * equations = [ [\"a\", \"b\"], [\"b\", \"c\"] ],\n * values = [2.0, 3.0],\n * queries = [ [\"a\", \"c\"], [\"b\", \"a\"], [\"a\", \"e\"], [\"a\", \"a\"], [\"x\", \"x\"] ].\n *\n * The input is always valid. You may assume that evaluating the queries will\n * result in no division by zero and there is no contradiction.\n *\n */\n\n\npublic class EvaluateDivision399 {\n    public double[] calcEquation(String[][] equations, double[] values, String[][] queries) {\n        double[] res = new double[queries.length];\n        Map<String, Set<String>> graph = new HashMap<>();\n        Map<String, Map<String, Double>> weights = new HashMap<>();\n        initGraph(equations, values, graph, weights);\n\n        for (int i=0; i<queries.length; i++) {\n            String[] q = queries[i];\n            if (!graph.containsKey(q[0]) || !graph.containsKey(q[1])){\n                res[i] = -1.0;\n            } else {\n                Set<String> visited = new HashSet<>();\n                res[i] = dfs(graph, weights, q[0], q[1], visited, 1.0);\n            }\n        }\n\n        return res;\n    }\n\n    private double dfs(Map<String, Set<String>> graph, Map<String, Map<String, Double>> weights, String from, String to, Set<String> visited, double pre) {\n        if (from.equals(to)) return 1.0;\n\n        visited.add(from);\n        Set<String> set = graph.get(from);\n\n        if (set.contains(to)) {\n            return (weights.get(from).get(to) == -1.0) ? -1.0 : weights.get(from).get(to) * pre;\n        }\n\n        for (String next: set) {\n            if (visited.contains(next)) continue;\n            Double newVal = dfs(graph, weights, next, to, visited, pre);\n            if (newVal == -1.0) continue;\n            return pre * weights.get(from).get(next) * newVal;\n        }\n\n        visited.remove(from);\n        return -1.0;\n    }\n\n\n    private void initGraph(String[][] equations, double[] values, Map<String, Set<String>> graph, Map<String, Map<String, Double>> weights) {\n        for (int i=0; i<values.length; i++) {\n            String[] edge = equations[i];\n            double weight = values[i];\n            addToValueMap(weights, edge[0], edge[1], weight);\n            addToValueMap(weights, edge[1], edge[0], (weight == 0.0) ? -1.0 : (1.0 / weight));\n            addToValueSet(graph, edge[0], edge[1]);\n            addToValueSet(graph, edge[1], edge[0]);\n        }\n    }\n\n    private void addToValueMap(Map<String, Map<String, Double>> weights, String from, String to, Double weight) {\n        Map<String, Double> map = weights.getOrDefault(from, new HashMap<String, Double>());\n        map.put(to, weight);\n        weights.put(from, map);\n    }\n\n    private void addToValueSet(Map<String, Set<String>> graph, String from, String to) {\n        Set<String> set = graph.getOrDefault(from, new HashSet<String>());\n        set.add(to);\n        graph.put(from, set);\n    }\n\n\n    public double[] calcEquation2(String[][] equations, double[] values, String[][] queries) {\n        UnionFind uf = new UnionFind();\n        int N = equations.length;\n        \n        for (int i = 0; i<N; i++) {\n            uf.union(equations[i][0], equations[i][1], values[i]);\n        }\n        \n        int M = queries.length;\n        double[] res = new double[M];\n        for (int i=0; i<M; i++) {\n            String[] q = queries[i];\n            Parent PA = uf.find(q[0]);\n            Parent PB = uf.find(q[1]);\n            if (PA == null || PB == null || !PA.parent.equals(PB.parent)) {\n                res[i] = -1.0;\n            } else {\n                res[i] = PB.times / PA.times;\n            }\n        }\n        \n        return res;\n    }\n    \n    class UnionFind {\n        Map<String, Parent> parents = new HashMap<>();\n\n        private Parent find(String A) {\n            if (!parents.containsKey(A)) return null;\n            Parent pa = parents.get(A);\n            if (!pa.parent.equals(A)) {\n                Parent p = find(pa.parent);\n                pa.parent = p.parent;\n                pa.times *= p.times;\n            }\n            return pa;\n        }\n\n        private void union(String A, String B, double times) {\n            boolean hasA = parents.containsKey(A);\n            boolean hasB = parents.containsKey(B);\n            if (!hasA && !hasB) {\n                parents.put(A, new Parent(A, 1.0));\n                parents.put(B, new Parent(A, times));\n            } else if (!hasA) {\n                parents.put(A, new Parent(B, 1.0 / times));\n            } else if (!hasB) {\n                parents.put(B, new Parent(A, times));\n            } else {\n                Parent pa = find(A);\n                Parent pb = find(B);\n                pb.parent = pa.parent;\n                pb.times = (pa.times / pb.times) * times;\n            }\n        }\n    }\n    \n    class Parent {\n        String parent;\n        Double times;\n        Parent(String parent, Double times) {\n            this.parent = parent;\n            this.times = times;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/EvaluateReversePolishNotation150.java",
    "content": "/**\n * Evaluate the value of an arithmetic expression in Reverse Polish Notation.\n * \n * Valid operators are +, -, *, /. Each operand may be an integer or another expression.\n * \n * Note:\n * \n * Division between two integers should truncate toward zero.\n * The given RPN expression is always valid. That means the expression would\n * always evaluate to a result and there won't be any divide by zero operation.\n * \n * Example 1:\n * Input: [\"2\", \"1\", \"+\", \"3\", \"*\"]\n * Output: 9\n * Explanation: ((2 + 1) * 3) = 9\n * \n * Example 2:\n * Input: [\"4\", \"13\", \"5\", \"/\", \"+\"]\n * Output: 6\n * Explanation: (4 + (13 / 5)) = 6\n * \n * Example 3:\n * Input: [\"10\", \"6\", \"9\", \"3\", \"+\", \"-11\", \"*\", \"/\", \"*\", \"17\", \"+\", \"5\", \"+\"]\n * Output: 22\n * Explanation: \n *   ((10 * (6 / ((9 + 3) * -11))) + 17) + 5\n * = ((10 * (6 / (12 * -11))) + 17) + 5\n * = ((10 * (6 / -132)) + 17) + 5\n * = ((10 * 0) + 17) + 5\n * = (0 + 17) + 5\n * = 17 + 5\n * = 22\n */\n\npublic class EvaluateReversePolishNotation150 {\n    public int evalRPN(String[] tokens) {\n        Stack<Integer> stack = new Stack<>();\n        \n        for (String t: tokens) {\n            switch (t) {\n                case \"+\":\n                    Integer i1 = stack.pop();\n                    Integer i2 = stack.pop();\n                    stack.push(i2 + i1);\n                    break;\n                case \"-\":\n                    Integer i3 = stack.pop();\n                    Integer i4 = stack.pop();\n                    stack.push(i4 - i3);\n                    break;\n                case \"*\":\n                    Integer i5 = stack.pop();\n                    Integer i6 = stack.pop();\n                    stack.push(i6 * i5);\n                    break;\n                case \"/\":\n                    Integer i7 = stack.pop();\n                    Integer i8 = stack.pop();\n                    stack.push(i8 / i7);\n                    break;\n                default:\n                    stack.push(Integer.valueOf(t));\n            }\n        }\n        return stack.pop();\n    }\n\n}\n\n"
  },
  {
    "path": "src/ExamRoom855.java",
    "content": "/**\n * In an exam room, there are N seats in a single row, numbered 0, 1, 2, ..., N-1.\n * \n * When a student enters the room, they must sit in the seat that maximizes the\n * distance to the closest person.  If there are multiple such seats, they sit\n * in the seat with the lowest number.  (Also, if no one is in the room, then\n * the student sits at seat number 0.)\n * \n * Return a class ExamRoom(int N) that exposes two functions: ExamRoom.seat()\n * returning an int representing what seat the student sat in, and\n * ExamRoom.leave(int p) representing that the student in seat number p now\n * leaves the room.  It is guaranteed that any calls to ExamRoom.leave(p) have\n * a student sitting in seat p.\n * \n * Example 1:\n * Input: [\"ExamRoom\",\"seat\",\"seat\",\"seat\",\"seat\",\"leave\",\"seat\"], [[10],[],[],[],[],[4],[]]\n * Output: [null,0,9,4,2,null,5]\n * \n * Explanation:\n * ExamRoom(10) -> null\n * seat() -> 0, no one is in the room, then the student sits at seat number 0.\n * seat() -> 9, the student sits at the last seat number 9.\n * seat() -> 4, the student sits at the last seat number 4.\n * seat() -> 2, the student sits at the last seat number 2.\n * leave(4) -> null\n * seat() -> 5, the student​​​​​​​ sits at the last seat number 5.\n​​​​​​​ * \n * Note:\n * 1 <= N <= 10^9\n * ExamRoom.seat() and ExamRoom.leave() will be called at most 10^4 times across all test cases.\n * Calls to ExamRoom.leave(p) are guaranteed to have a student currently sitting in seat number p.\n */\n\n\npublic class ExamRoom855 {\n    class ExamRoom {\n        private PriorityQueue<Range> pq;\n        private Map<Integer, Range> lefts;\n        private Map<Integer, Range> rights;\n        private int N;\n\n        public ExamRoom(int N) {\n            this.pq = new PriorityQueue(1, new Comparator<Range>() {\n                @Override\n                public int compare(Range r1, Range r2) {\n                    int rangeDiff = Integer.compare(dis(r2), dis(r1));\n                    if (rangeDiff != 0) return rangeDiff;\n                    return Integer.compare(r1.left, r2.left);\n                }\n            });\n            this.lefts = new HashMap<>();\n            this.rights = new HashMap<>();\n            this.N = N;\n            \n            Range first = new Range(-1, N);\n            this.pq.add(first);\n            this.lefts.put(first.left, first);\n            this.rights.put(first.right, first);\n        }\n\n        public int seat() {\n            if (this.pq.isEmpty()) return -1;\n            Range curr = this.pq.poll();\n            this.lefts.remove(curr.left);\n            this.rights.remove(curr.right);\n\n            int pos = sitPos(curr);\n            Range l = new Range(curr.left, pos);\n            this.lefts.put(l.left, l);\n            this.rights.put(l.right, l);\n            if (curr.left + 1 < pos) {\n                this.pq.add(l);\n            }\n\n            Range r = new Range(pos, curr.right);\n            this.lefts.put(r.left, r);\n            this.rights.put(r.right, r);\n            if (pos + 1 < curr.right) {\n                this.pq.add(r);\n            }\n            return pos;\n        }\n\n        public void leave(int p) {\n            Range r = this.lefts.get(p);\n            Range l = this.rights.get(p);\n            this.pq.remove(r);\n            this.pq.remove(l);\n\n            Range merged = new Range(l.left, r.right);\n            this.pq.add(merged);\n            this.lefts.put(merged.left, merged);\n            this.rights.put(merged.right, merged);\n        }\n\n        private int sitPos(Range r) {\n            return sitPos(r.left, r.right);\n        }\n\n        private int sitPos(int left, int right) {\n            if (left + 1 >= right) return -1;\n            if (left < 0) return 0;\n            if (right >= this.N) return this.N - 1;\n            return (right - left) / 2 + left;\n        }\n\n        private int dis(Range r) {\n            return dis(r.left, r.right);\n        }\n\n        private int dis(int left, int right) {\n            if (left < 0) return right;\n            if (right >= this.N) return this.N - 1 - left;\n            return (right - left) / 2;\n        }\n    }\n\n    class Range {\n        int left;\n        int right;\n        Range (int l, int r) {\n            this.left = l;\n            this.right = r;\n        }\n    }\n\n/**\n * Your ExamRoom object will be instantiated and called as such:\n * ExamRoom obj = new ExamRoom(N);\n * int param_1 = obj.seat();\n * obj.leave(p);\n */\n\n}\n"
  },
  {
    "path": "src/ExclusiveTimeOfFunctions636.java",
    "content": "/**\n * Given the running logs of n functions that are executed in a nonpreemptive\n * single threaded CPU, find the exclusive time of these functions.\n * \n * Each function has a unique id, start from 0 to n-1. A function may be called\n * recursively or by another function.\n * \n * A log is a string has this format : function_id:start_or_end:timestamp. For\n * example, \"0:start:0\" means function 0 starts from the very beginning of\n * time 0. \"0:end:0\" means function 0 ends to the very end of time 0.\n * \n * Exclusive time of a function is defined as the time spent within this\n * function, the time spent by calling other functions should not be considered\n * as this function's exclusive time. You should return the exclusive time of\n * each function sorted by their function id.\n * \n * Example 1:\n * Input:\n * n = 2\n * logs = \n * [\"0:start:0\",\n *  \"1:start:2\",\n *  \"1:end:5\",\n *  \"0:end:6\"]\n * Output:[3, 4]\n * \n * Explanation:\n * Function 0 starts at time 0, then it executes 2 units of time and reaches\n * the end of time 1. \n * Now function 0 calls function 1, function 1 starts at time 2, executes 4\n * units of time and end at time 5.\n * Function 0 is running again at time 6, and also end at the time 6, thus\n * executes 1 unit of time. \n * So function 0 totally execute 2 + 1 = 3 units of time, and function 1\n * totally execute 4 units of time.\n * \n * Note:\n * Input logs will be sorted by timestamp, NOT log id.\n * Your output should be sorted by function id, which means the 0th element of\n * your output corresponds to the exclusive time of function 0.\n * Two functions won't start or end at the same time.\n * Functions could be called recursively, and will always end.\n * 1 <= n <= 100\n */\n\npublic class ExclusiveTimeOfFunctions636 {\n    public int[] exclusiveTime(int n, List<String> logs) {\n        int[] res = new int[n];\n        Stack<Integer> actives = new Stack<>();\n        int preTime = 0;\n        boolean preIsStart = true;\n        for (String log: logs) {\n            String[] strs = log.split(\":\");\n            int id = Integer.valueOf(strs[0]);\n            boolean isStart = strs[1].equals(\"start\");\n            int now = Integer.valueOf(strs[2]);\n            if (isStart) {\n                if (!actives.isEmpty()) {\n                    res[actives.peek()] += now - preTime - (preIsStart ? 0 : 1);\n                }\n                actives.push(id);\n            } else {\n                res[actives.peek()] += now - preTime + (preIsStart ? 1 : 0);\n                actives.pop();\n            }\n            preTime = now;\n            preIsStart = isStart;\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/ExpressionAddOperators282.java",
    "content": "/**\n * Given a string that contains only digits 0-9 and a target value, return all\n * possibilities to add binary operators (not unary) +, -, or * between the\n * digits so they evaluate to the target value.\n *\n * Examples:\n * \"123\", 6 -> [\"1+2+3\", \"1*2*3\"]\n * \"232\", 8 -> [\"2*3+2\", \"2+3*2\"]\n * \"105\", 5 -> [\"1*0+5\",\"10-5\"]\n * \"00\", 0 -> [\"0+0\", \"0-0\", \"0*0\"]\n * \"3456237490\", 9191 -> []\n *\n */\n\n\npublic class ExpressionAddOperators282 {\n    public List<String> addOperators(String num, int target) {\n        List<String> res = new ArrayList<>();\n        if (num == null || num.length() == 0) return res;\n        if (num.charAt(0) == '0') {\n            helper(num, target, res, \"0\", 1, 1, 0, 0L);\n        } else {\n           for (int i=0; i<num.length(); i++) {\n                String first = num.substring(0, i+1);\n                helper(num, target, res, first, i+1, i+1, 0, Long.parseLong(first));\n            }\n        }\n        return res;\n    }\n\n    private void helper(String num, int target, List<String> res, String s, int i1, int i2, long pre, long last) {\n        if (i2 >= num.length()) {\n            if (i1 == i2 && (pre + last) == target) res.add(s);\n            return;\n        }\n\n        String curr = num.substring(i1, i2+1);\n        Long i = Long.parseLong(curr);\n        if (!(i1 == i2 && curr.charAt(0) == '0')) {\n            helper(num, target, res, s, i1, i2+1, pre, last);\n        }\n        helper(num, target, res, s+\"+\"+curr, i2+1, i2+1, pre+last, i);\n        helper(num, target, res, s+\"-\"+curr, i2+1, i2+1, pre+last, -i);\n        helper(num, target, res, s+\"*\"+curr, i2+1, i2+1, pre, last*i);\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/35942/java-ac-solution-19ms-beat-100-00\n     */\n    public List<String> addOperators2(String num, int target) {\n        List<String> ret = new LinkedList<>();\n        if (num.length() == 0) return ret;\n        char[] path = new char[num.length() * 2 - 1];\n        char[] digits = num.toCharArray();\n        long n = 0;\n        for (int i = 0; i < digits.length; i++) {\n            n = n * 10 + digits[i] - '0';\n            path[i] = digits[i];\n            dfs(ret, path, i + 1, 0, n, digits, i + 1, target);\n            if (n == 0) break;\n        }\n        return ret;\n    }\n\n    private void dfs(List<String> ret, char[] path, int len, long left, long cur, char[] digits, int pos, int target) {\n        if (pos == digits.length) {\n            if (left + cur == target) ret.add(new String(path, 0, len));\n            return;\n        }\n        long n = 0;\n        int j = len + 1;\n        for (int i = pos; i < digits.length; i++) {\n            n = n * 10 + digits[i] - '0';\n            path[j++] = digits[i];\n            path[len] = '+';\n            dfs(ret, path, j, left + cur, n, digits, i + 1, target);\n            path[len] = '-';\n            dfs(ret, path, j, left + cur, -n, digits, i + 1, target);\n            path[len] = '*';\n            dfs(ret, path, j, left, cur * n, digits, i + 1, target);\n            if (digits[pos] == '0') break;\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "src/FindAllAnagramsInAString438.java",
    "content": "/**\n * Given a string s and a non-empty string p, find all the start indices of\n * p's anagrams in s.\n * \n * Strings consists of lowercase English letters only and the length of both\n * strings s and p will not be larger than 20,100.\n * \n * The order of output does not matter.\n * \n * Example 1:\n * Input:\n * s: \"cbaebabacd\" p: \"abc\"\n * Output:\n * [0, 6]\n * Explanation:\n * The substring with start index = 0 is \"cba\", which is an anagram of \"abc\".\n * The substring with start index = 6 is \"bac\", which is an anagram of \"abc\".\n * \n * Example 2:\n * Input:\n * s: \"abab\" p: \"ab\"\n * Output:\n * [0, 1, 2]\n * Explanation:\n * The substring with start index = 0 is \"ab\", which is an anagram of \"ab\".\n * The substring with start index = 1 is \"ba\", which is an anagram of \"ab\".\n * The substring with start index = 2 is \"ab\", which is an anagram of \"ab\".\n */\n\npublic class FindAllAnagramsInAString438 {\n    public List<Integer> findAnagrams(String s, String p) {\n        int[] map = new int[26];\n        for (char c: p.toCharArray()) {\n            map[c - 'a']++;\n        }\n\n        List<Integer> res = new ArrayList<>();\n        int lenS = s.length();\n        int count = p.length();\n        if (lenS < count) return res;\n        char[] chars = s.toCharArray();\n        int i = 0;\n        int j = 0;\n        while (j < lenS) {\n            char c = chars[j];\n            while (i <= j && map[c - 'a'] <= 0) {\n                map[chars[i] - 'a']++;\n                i++;\n            }\n            map[c - 'a']--;\n            j++;\n            if (j - i == count) {\n                res.add(i);\n                map[chars[i] - 'a']++;\n                i++;\n            }\n        }\n\n        return res;\n    }\n\n\n    public List<Integer> findAnagrams2(String s, String p) {\n        int[] map = new int[26];\n        for (char c: p.toCharArray()) {\n            map[c - 'a']++;\n        }\n\n        List<Integer> res = new ArrayList<>();\n        int lenS = s.length();\n        int lenP = p.length();\n        if (lenS < lenP) return res;\n        char[] chars = s.toCharArray();\n        int[] window = new int[26];\n        for (int i=0; i<lenP; i++) {\n            window[chars[i] - 'a']++;\n        }\n        if (compare(map, window)) res.add(0);\n        for (int i=0; i<(lenS-lenP); i++) {\n            window[chars[i] - 'a']--;\n            window[chars[i+lenP] - 'a']++;\n            if (compare(map, window)) res.add(i+1);\n        }\n        return res;\n    }\n\n    private boolean compare(int[] map, int[] window) {\n        for (int i=0; i<26; i++) {\n            if (map[i] != window[i]) return false;\n        }\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/find-all-anagrams-in-a-string/discuss/92015/ShortestConcise-JAVA-O(n)-Sliding-Window-Solution\n     */\n    public List<Integer> findAnagrams3(String s, String p) {\n        List<Integer> list = new ArrayList<>();\n        if (s == null || s.length() == 0 || p == null || p.length() == 0) return list;\n        int[] hash = new int[256]; //character hash\n        //record each character in p to hash\n        for (char c : p.toCharArray()) {\n            hash[c]++;\n        }\n        //two points, initialize count to p's length\n        int left = 0, right = 0, count = p.length();\n        while (right < s.length()) {\n            //move right everytime, if the character exists in p's hash, decrease the count\n            //current hash value >= 1 means the character is existing in p\n            if (hash[s.charAt(right++)]-- >= 1) count--; \n            \n            //when the count is down to 0, means we found the right anagram\n            //then add window's left to result list\n            if (count == 0) list.add(left);\n        \n            //if we find the window's size equals to p, then we have to move left (narrow the window) to find the new match window\n            //++ to reset the hash because we kicked out the left\n            //only increase the count if the character is in p\n            //the count >= 0 indicate it was original in the hash, cuz it won't go below 0\n            if (right - left == p.length() && hash[s.charAt(left++)]++ >= 0) count++;\n        }\n        return list;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/find-all-anagrams-in-a-string/discuss/92007/Sliding-Window-algorithm-template-to-solve-all-the-Leetcode-substring-search-problem.\n     */\n    public List<Integer> findAnagrams4(String s, String t) {\n        List<Integer> result = new LinkedList<>();\n        if(t.length()> s.length()) return result;\n        Map<Character, Integer> map = new HashMap<>();\n        for(char c : t.toCharArray()){\n            map.put(c, map.getOrDefault(c, 0) + 1);\n        }\n        int counter = map.size();\n        int begin = 0, end = 0;\n        int head = 0;\n        int len = Integer.MAX_VALUE;\n        while(end < s.length()){\n            char c = s.charAt(end);\n            if( map.containsKey(c) ){\n                map.put(c, map.get(c)-1);\n                if(map.get(c) == 0) counter--;\n            }\n            end++;\n\n            while(counter == 0){\n                char tempc = s.charAt(begin);\n                if(map.containsKey(tempc)){\n                    map.put(tempc, map.get(tempc) + 1);\n                    if(map.get(tempc) > 0){\n                        counter++;\n                    }\n                }\n                if(end-begin == t.length()){\n                    result.add(begin);\n                }\n                begin++;\n            }\n        }\n        return result;\n    }\n\n\n    public List<Integer> findAnagrams5(String s, String p) {\n        List<Integer> res = new ArrayList<>();\n        if (s.length() < p.length()) return res;\n        int[] map = new int[26];\n        int M = 0;\n        for (char c: p.toCharArray()) {\n            if (map[c - 'a'] == 0) M++;\n            map[c - 'a']++;\n        }\n        char[] charS = s.toCharArray();\n        int N = charS.length;\n        int P = p.length();\n        int left = 0;\n        int right = 0;\n        while (right < N) {\n            char rc = charS[right++];\n            map[rc - 'a']--;\n            if (map[rc - 'a'] == 0) M--;\n            if (M == 0) res.add(left);\n            if (right - left == P) {\n                char lc = charS[left++];\n                if (map[lc - 'a'] == 0) M++;\n                map[lc - 'a']++;\n            }\n        }\n        return res;\n    }\n\n\n}\n"
  },
  {
    "path": "src/FindAllNumbersDisappearedInAnArray448.java",
    "content": "/**\n * Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some\n * elements appear twice and others appear once.\n * \n * Find all the elements of [1, n] inclusive that do not appear in this array.\n * \n * Could you do it without extra space and in O(n) runtime? You may assume the\n * returned list does not count as extra space.\n * \n * Example:\n * \n * Input:\n * [4,3,2,7,8,2,3,1]\n * \n * Output:\n * [5,6]\n */\n\npublic class FindAllNumbersDisappearedInAnArray448 {\n    public List<Integer> findDisappearedNumbers(int[] nums) {\n        if (nums == null || nums.length <= 1) return new ArrayList<>();\n        int len = nums.length;\n        int i = 0;\n        while (i < len) {\n            int curr = nums[i];\n            while (curr != i + 1) {\n                int next = nums[curr-1];\n                if (curr == next) break;\n                swap(nums, i, curr-1);\n                curr = nums[i];\n            }\n            i++;\n        }\n        List<Integer> res = new ArrayList<>();\n        for (int j=0; j<len; j++) {\n            if (nums[j] != j+1) {\n                res.add(j+1);\n            }\n        }\n        return res;\n    }\n    \n    private void swap(int[] nums, int i, int j) {\n        int temp = nums[i];\n        nums[i] = nums[j];\n        nums[j] = temp;\n    }\n  \n}\n"
  },
  {
    "path": "src/FindAnagramMappings760.java",
    "content": "/**\n * Given two lists Aand B, and B is an anagram of A. B is an anagram of A means\n * B is made by randomizing the order of the elements in A.\n * \n * We want to find an index mapping P, from A to B. A mapping P[i] = j means\n * the ith element in A appears in B at index j.\n * \n * These lists A and B may contain duplicates. If there are multiple answers,\n * output any of them.\n * \n * For example, given\n * \n * A = [12, 28, 46, 32, 50]\n * B = [50, 12, 32, 46, 28]\n * \n * We should return\n * [1, 4, 3, 2, 0]\n * as P[0] = 1 because the 0th element of A appears at B[1], and P[1] = 4\n * because the 1st element of A appears at B[4], and so on.\n * \n * Note:\n * A, B have equal lengths in range [1, 100].\n * A[i], B[i] are integers in range [0, 10^5].\n */\n\npublic class FindAnagramMappings760 {\n    /**\n     * https://leetcode.com/problems/find-anagram-mappings/solution/\n     */\n    public int[] anagramMappings(int[] A, int[] B) {\n        Map<Integer, Integer> D = new HashMap();\n        for (int i = 0; i < B.length; ++i)\n            D.put(B[i], i);\n\n        int[] ans = new int[A.length];\n        int t = 0;\n        for (int x: A)\n            ans[t++] = D.get(x);\n        return ans;\n    }\n\n}\n"
  },
  {
    "path": "src/FindAndReplacePattern890.java",
    "content": "/**\n * You have a list of words and a pattern, and you want to know which words in\n * words matches the pattern.\n * \n * A word matches the pattern if there exists a permutation of letters p so\n * that after replacing every letter x in the pattern with p(x), we get the\n * desired word.\n * \n * (Recall that a permutation of letters is a bijection from letters to\n * letters: every letter maps to another letter, and no two letters map to\n * the same letter.)\n * \n * Return a list of the words in words that match the given pattern. \n * \n * You may return the answer in any order.\n * \n * Example 1:\n * Input: words = [\"abc\",\"deq\",\"mee\",\"aqq\",\"dkd\",\"ccc\"], pattern = \"abb\"\n * Output: [\"mee\",\"aqq\"]\n * Explanation: \"mee\" matches the pattern because there is a permutation {a -> m, b -> e, ...}. \n * \"ccc\" does not match the pattern because {a -> c, b -> c, ...} is not a permutation,\n * since a and b map to the same letter.\n * \n * Note:\n * 1 <= words.length <= 50\n * 1 <= pattern.length = words[i].length <= 20\n */\n\npublic class FindAndReplacePattern890 {\n    public List<String> findAndReplacePattern(String[] words, String pattern) {\n        List<String> res = new ArrayList<>();\n        char[] pat = pattern.toCharArray();\n        int N = pattern.length();\n        for (String word: words) {\n            if (isPermutation(word.toCharArray(), pat, N)) {\n                res.add(word);\n            }\n        }\n        return res;\n    }\n\n    public boolean isPermutation(char[] word, char[] pattern, int N) {\n        Map<Character, Character> map = new HashMap<>();\n        for (int i=0; i<N; i++) {\n            if (map.containsKey(word[i])) {\n                if (map.get(word[i]) != pattern[i]) return false;\n            } else {\n                if (map.values().contains(pattern[i])) return false;\n                map.put(word[i], pattern[i]);\n            }\n        }\n        return true;\n    }\n\n\n    public List<String> findAndReplacePattern2(String[] words, String pattern) {\n        List<String> res = new ArrayList<>();\n        int code = encode(pattern);\n        for (String w: words) {\n            if (code == encode(w)) {\n                res.add(w);\n            }\n        }\n        return res;\n    }\n\n    public int encode(String s) {\n        int res = 0;\n        char[] chars = s.toCharArray();\n        char first = chars[0];\n        Map<Integer, Integer> map = new HashMap<>();\n        map.put(0, 0);\n        int i = 1;\n        for (int j=0; j<chars.length; j++) {\n            int offset = chars[j] - first;\n            if (map.containsKey(offset)) {\n                res += map.get(offset) * j;\n            } else {\n                map.put(offset, i);\n                res += i * j;\n                i++;\n            }\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/FindBottomLeftTreeValue513.java",
    "content": "/**\n * Given a binary tree, find the leftmost value in the last row of the tree.\n *\n * Example 1:\n * Input:\n *\n *     2\n *    / \\\n *   1   3\n *\n * Output:\n * 1\n *\n * Example 2:\n * Input:\n *\n *         1\n *        / \\\n *       2   3\n *      /   / \\\n *     4   5   6\n *        /\n *       7\n *\n * Output:\n * 7\n *\n * Note: You may assume the tree (i.e., the given root node) is not NULL.\n *\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\n\npublic class FindBottomLeftTreeValue513 {\n    public int findBottomLeftValue(TreeNode root) {\n        int res = root.val;\n        Queue<TreeNode> q = new LinkedList<>();\n        q.add(root);\n\n        while (!q.isEmpty()) {\n            Queue<TreeNode> ql = new LinkedList<>();\n            System.out.println(q.peek().val);\n            res = q.peek().val;\n            while (!q.isEmpty()) {\n                TreeNode n = q.poll();\n                if (n.left != null) ql.offer(n.left);\n                if (n.right != null) ql.offer(n.right);\n            }\n            q = ql;\n        }\n\n        return res;\n    }\n\n\n    public int findBottomLeftValue2(TreeNode root) {\n        int res = root.val;\n        Map<Integer, Integer> lefts = new HashMap<>();\n        int level = helper(root, 0, lefts);\n        return lefts.get(level);\n    }\n\n    private int helper(TreeNode node, int level, Map<Integer, Integer> lefts) {\n        if (node == null) return level-1;\n        if (!lefts.containsKey(level)) lefts.put(level, node.val);\n        int leftLevel = helper(node.left, level+1, lefts);\n        int rightLevel = helper(node.right, level+1, lefts);\n        return Math.max(leftLevel, rightLevel);\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/78962/simple-java-solution-beats-100-0\n     */\n    public int findBottomLeftValue3(TreeNode root) {\n        return findBottomLeftValue(root, 1, new int[]{0,0});\n    }\n    public int findBottomLeftValue(TreeNode root, int depth, int[] res) {\n        if (res[1]<depth) {res[0]=root.val;res[1]=depth;}\n        if (root.left!=null) findBottomLeftValue(root.left, depth+1, res);\n        if (root.right!=null) findBottomLeftValue(root.right, depth+1, res);\n        return res[0];\n    }\n\n\n}\n"
  },
  {
    "path": "src/FindCenterOfMassInA2DArray.java",
    "content": "/**\n * Find Center Of Mass In A 2D Array.\n * https://en.wikipedia.org/wiki/Center_of_mass\n */\n\npublic class FindCenterOfMassInA2DArray {\n    public int[] findCenterOfMass(int[][] weightMap) {\n        if (weightMap == null || weightMap.length == 0 || weightMap[0].length == 0) return new int[]{-1, -1};\n        int numRows = weightMap.length;\n        int numCols = weightMap[0].length;\n        int sumX = 0;\n        int sumY = 0;\n        int sumWeight = 0;\n        for (int i=0; i<numRows; i++) {\n            for (int j=0; j<numCols; j++) {\n                int w = weightMap[i][j];\n                if (w <= 0) continue;\n                sumX += w * i;\n                sumY += w * j;\n                sumWeight += w;\n            }\n        }\n        return new int[]{sumX / sumWeight, sumY / sumWeight};\n    }\n\n}\n"
  },
  {
    "path": "src/FindDuplicateSubtrees652.java",
    "content": "/**\n * Given a binary tree, return all duplicate subtrees. For each kind of\n * duplicate subtrees, you only need to return the root node of any one of them.\n * \n * Two trees are duplicate if they have the same structure with same node values.\n * \n * Example 1:\n * \n *         1\n *        / \\\n *       2   3\n *      /   / \\\n *     4   2   4\n *        /\n *       4\n * \n * The following are two duplicate subtrees:\n * \n *       2\n *      /\n *     4\n * \n * and\n * \n *     4\n * \n * Therefore, you need to return above trees' root in the form of a list.\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class FindDuplicateSubtrees652 {\n    public List<TreeNode> findDuplicateSubtrees(TreeNode root) {\n        List<TreeNode> res = new ArrayList<>();\n        if (root == null) return res;\n        Map<String, Boolean> visited = new HashMap<>();\n        findDuplicates(root, visited, res);\n        return res;\n    }\n\n    private String findDuplicates(TreeNode root, Map<String, Boolean> visited, List<TreeNode> res) {\n        if (root == null) {\n            return \"N\";\n        }\n        String self = Integer.toString(root.val);\n        String left = findDuplicates(root.left, visited, res);\n        String right = findDuplicates(root.right, visited, res);\n        String curr = self + \"-\" + left + \"-\" + right;\n        if (!visited.containsKey(curr)) {\n            visited.put(curr, false);\n        } else {\n            if (!visited.get(curr)) {\n                res.add(root);\n                visited.put(curr, true);\n            }\n        }\n        return curr;\n    }\n\n}\n"
  },
  {
    "path": "src/FindEventualSafeStates802.java",
    "content": "/**\n * In a directed graph, we start at some node and every turn, walk along a\n * directed edge of the graph.  If we reach a node that is terminal (that is,\n * it has no outgoing directed edges), we stop.\n * \n * Now, say our starting node is eventually safe if and only if we must\n * eventually walk to a terminal node.  More specifically, there exists a\n * natural number K so that for any choice of where to walk, we must have\n * stopped at a terminal node in less than K steps.\n * \n * Which nodes are eventually safe?  Return them as an array in sorted order.\n * \n * The directed graph has N nodes with labels 0, 1, ..., N-1, where N is the\n * length of graph.  The graph is given in the following form: graph[i] is a\n * list of labels j such that (i, j) is a directed edge of the graph.\n * \n * Example:\n * Input: graph = [[1,2],[2,3],[5],[0],[5],[],[]]\n * Output: [2,4,5,6]\n * \n * Here is a diagram of the above graph.\n * https://s3-lc-upload.s3.amazonaws.com/uploads/2018/03/17/picture1.png\n * \n * Note:\n * graph will have length at most 10000.\n * The number of edges in the graph will not exceed 32000.\n * Each graph[i] will be a sorted list of different integers, chosen within\n * the range [0, graph.length - 1].\n */\n\n\npublic class FindEventualSafeStates802 {\n    public List<Integer> eventualSafeNodes(int[][] graph) {\n        List<Integer> res = new ArrayList<>();\n        if (graph == null || graph.length == 0) return res;\n        int N = graph.length;\n        boolean[] saved = new boolean[N];\n        boolean[] visited = new boolean[N];\n        for (int i=0; i<N; i++) {\n            if (checkTermial(graph, i, visited, saved)) res.add(i);\n        }\n        \n        return res;\n    }\n\n    private boolean checkTermial(int[][] graph, int now, boolean[] visited, boolean[] saved) {\n        if (saved[now]) return true;\n        if (visited[now]) return false;\n        visited[now] = true;\n        for (int next: graph[now]) {\n            if (!checkTermial(graph, next, visited, saved)) return false;\n        }\n        visited[now] = false;\n        saved[now] = true;\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/find-eventual-safe-states/solution/\n     */\n    public List<Integer> eventualSafeNodes2(int[][] graph) {\n        int N = graph.length;\n        int[] color = new int[N];\n        List<Integer> ans = new ArrayList();\n\n        for (int i = 0; i < N; ++i)\n            if (dfs(i, color, graph))\n                ans.add(i);\n        return ans;\n    }\n\n    // colors: WHITE 0, GRAY 1, BLACK 2;\n    public boolean dfs(int node, int[] color, int[][] graph) {\n        if (color[node] > 0)\n            return color[node] == 2;\n\n        color[node] = 1;\n        for (int nei: graph[node]) {\n            if (color[node] == 2)\n                continue;\n            if (color[nei] == 1 || !dfs(nei, color, graph))\n                return false;\n        }\n\n        color[node] = 2;\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "src/FindKClosestElements658.java",
    "content": "/**\n * Given a sorted array, two integers k and x, find the k closest elements to x\n * in the array. The result should also be sorted in ascending order. If there\n * is a tie, the smaller elements are always preferred.\n * \n * Example 1:\n * Input: [1,2,3,4,5], k=4, x=3\n * Output: [1,2,3,4]\n * \n * Example 2:\n * Input: [1,2,3,4,5], k=4, x=-1\n * Output: [1,2,3,4]\n * \n * Note:\n * The value k is positive and will always be smaller than the length of the sorted array.\n * Length of the given array is positive and will not exceed 104\n * Absolute value of elements in the array and x will not exceed 104\n * \n * UPDATE (2017/9/19):\n * The arr parameter had been changed to an array of integers (instead of a\n * list of integers). Please reload the code definition to get the latest\n * changes.\n */\n\n\npublic class FindKClosestElements658 {\n    public List<Integer> findClosestElements(int[] arr, int k, int x) {\n        int pos = binarySearch(arr, x, 0, arr.length-1);\n        pos = updatePos(arr, x, pos);\n        LinkedList<Integer> res = new LinkedList<>();\n        int left = pos - 1;\n        int right = pos;\n        int i = 0;\n        while (i < k) {\n            if (left >= 0 && right < arr.length) {\n                if (Math.abs(arr[left] - x) <= Math.abs(arr[right] - x)) {\n                    res.addFirst(arr[left--]);\n                } else {\n                    res.addLast(arr[right++]);\n                }\n            } else if (left >= 0) {\n                res.addFirst(arr[left--]);\n            } else {\n                res.addLast(arr[right++]);\n            }\n            i++;\n        }\n        return res;\n    }\n\n    public int binarySearch(int[] arr, int x, int lo, int hi) {\n        if (lo == hi) return lo;\n        if (hi - lo == 1) return hi;\n        int mid = (lo + hi) / 2;\n        if (arr[mid] == x) return mid;\n        else if (arr[mid] > x) {\n            return binarySearch(arr, x, lo, mid);\n        } else {\n            return binarySearch(arr, x, mid, hi);\n        }\n    }\n    \n    private int updatePos(int[] arr, int x, int pos) {\n        if (arr[pos] == x || pos == 0) return pos;\n        return (Math.abs(arr[pos-1]-x) <= Math.abs(arr[pos]-x)) ? pos - 1 : pos;\n    }\n  \n    // /**\n    //  * https://leetcode.com/problems/find-k-closest-elements/solution/\n    //  */\n    // public List<Integer> findClosestElements2(List<Integer> arr, int k, int x) {\n    //     Collections.sort(arr, (a,b) -> a == b ? a - b : Math.abs(a-x) - Math.abs(b-x));\n    //     arr = arr.subList(0, k);\n    //     Collections.sort(arr);\n    //     return arr;\n    // }\n\n\n    public List<Integer> findClosestElements3(int[] arr, int k, int x) {\n        List<Integer> res = new ArrayList<>();\n        int N = arr.length;\n        int start = 0;\n        int end = N - k;\n\n        /*\n        0...............................mid.....|....mid+k................(N-k)\n        \n        arr[mid] >= x, end = mid\n        \n        arr[mid] < x:\n            x - arr[mid] > arr[mid+k] - x, start = mid + 1;\n            x - arr[mid] <= arr[mid+k] - x, end = mid\n        */\n\n        while (start < end) {\n            int mid = (end + start) / 2;\n            // if (arr[mid] >= x) {\n            //     end = mid;\n            // } else { // arr[mid] < x\n                if (x - arr[mid] > arr[mid+k] - x) {\n                    start = mid + 1;\n                } else {\n                    end = mid;\n                }\n            // }\n        }\n        \n        for (int i=0; i<k; i++) {\n            res.add(arr[start+i]);\n        }\n        return res;\n    }\n\n\n    public List<Integer> findClosestElements4(int[] arr, int k, int x) {\n        List<Integer> res = new ArrayList<>();\n        if (arr == null || arr.length == 0) return res;\n        int idx = binarySearch(arr, x);\n        int lo = idx - 1;\n        int hi = idx;\n        while (hi - lo - 1 < k) {\n            if (lo < 0 && hi >= arr.length) break;\n            if (lo < 0) {\n                hi++;\n            } else if (hi >= arr.length) {\n                lo--;\n            } else {\n                if (Math.abs(arr[lo] - x) <= Math.abs(arr[hi] - x)) {\n                    lo--;\n                } else {\n                    hi++;\n                }\n            }\n        }\n        \n        for (int i=lo+1; i<hi; i++) {\n            res.add(arr[i]);\n        }\n        return res;\n    }\n\n    private int binarySearch(int[] arr, int x) {\n        int lo = 0;\n        int hi = arr.length - 1;\n        while (lo < hi) {\n            int mid = lo + (hi - lo) / 2;\n            if (arr[mid] < x) {\n                lo++;\n            } else {\n                hi--;\n            }\n        }\n        return lo;\n    }\n\n}\n"
  },
  {
    "path": "src/FindKPairsWithSmallestSums373.java",
    "content": "/**\n * You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k.\n *\n * Define a pair (u,v) which consists of one element from the first array and one element from the second array.\n *\n * Find the k pairs (u1,v1),(u2,v2) ...(uk,vk) with the smallest sums.\n *\n *\n * Example 1:\n * Given nums1 = [1,7,11], nums2 = [2,4,6],  k = 3\n *\n * Return: [1,2],[1,4],[1,6]\n *\n * The first 3 pairs are returned from the sequence:\n * [1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]\n *\n *\n * Example 2:\n * Given nums1 = [1,1,2], nums2 = [1,2,3],  k = 2\n *\n * Return: [1,1],[1,1]\n *\n * The first 2 pairs are returned from the sequence:\n * [1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3]\n *\n *\n * Example 3:\n * Given nums1 = [1,2], nums2 = [3],  k = 3\n *\n * Return: [1,3],[2,3]\n *\n * All possible pairs are returned from the sequence:\n * [1,3],[2,3]\n *\n */\n\n\npublic class FindKPairsWithSmallestSums373 {\n    /**\n     * https://discuss.leetcode.com/topic/50885/simple-java-o-klogk-solution-with-explanation\n     */\n    public List<int[]> kSmallestPairs(int[] nums1, int[] nums2, int k) {\n        PriorityQueue<int[]> que = new PriorityQueue<>((a,b)->a[0]+a[1]-b[0]-b[1]);\n        List<int[]> res = new ArrayList<>();\n        if(nums1.length==0 || nums2.length==0 || k==0) return res;\n        for(int i=0; i<nums1.length && i<k; i++) que.offer(new int[]{nums1[i], nums2[0], 0});\n        while(k-- > 0 && !que.isEmpty()){\n            int[] cur = que.poll();\n            res.add(new int[]{cur[0], cur[1]});\n            if(cur[2] == nums2.length-1) continue;\n            que.offer(new int[]{cur[0], nums2[cur[2]+1], cur[2]+1});\n        }\n        return res;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/50529/java-9ms-heap-queue-solution-k-log-k\n     */\n    public List<int[]> kSmallestPairs2(int[] nums1, int[] nums2, int k) {\n        List<int[]> ret = new ArrayList<>();\n        if (nums1==null || nums2==null || nums1.length ==0 || nums2.length ==0) return ret;\n        int len1 = nums1.length, len2=nums2.length;\n\n        PriorityQueue<Pair> q = new PriorityQueue(k, new CompPair());\n        for (int i=0; i<nums1.length && i<k ; i++) { // only need first k number in nums1 to start\n            q.offer( new Pair(0, nums1[i],nums2[0]) );\n        }\n        for (int i=1; i<=k && !q.isEmpty(); i++) { // get the first k sums\n            Pair p = q.poll();\n            ret.add( p.pair );\n            if (p.idx < len2 -1 ) { // get to next value in nums2\n                int next = p.idx+1;\n                q.offer( new Pair(next, p.pair[0], nums2[next]) );\n            }\n        }\n        return ret;\n    }\n\n    class Pair{\n        int[] pair;\n        int idx; // current index to nums2\n        long sum;\n        Pair(int idx, int n1, int n2){\n            this.idx = idx;\n            pair = new int[]{n1, n2};\n            sum = (long) n1 + (long) n2;\n        }\n    }\n\n    class CompPair implements Comparator<Pair> {\n        public int compare(Pair p1, Pair p2){\n            return Long.compare(p1.sum, p2.sum);\n        }\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/52953/share-my-solution-which-beat-96-42\n     */\n    public List<int[]> kSmallestPairs3(int[] nums1, int[] nums2, int k) {\n        PriorityQueue<Tuple> pq = new PriorityQueue<Tuple>();\n        int m = nums1.length, n = nums2.length;\n        List<int[]> res = new ArrayList<int[]>();\n        if(nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0 || k <= 0) return res;\n        for(int j = 0; j <= n-1; j++) pq.offer(new Tuple(0, j, nums1[0]+nums2[j]));\n        for(int i = 0; i < Math.min(k, m *n); i++) {\n            Tuple t = pq.poll();\n            res.add(new int[]{nums1[t.x], nums2[t.y]});\n            if(t.x == m - 1) continue;\n            pq.offer(new Tuple (t.x + 1, t.y, nums1[t.x + 1] + nums2[t.y]));\n        }\n        return res;\n    }\n\n    class Tuple implements Comparable<Tuple> {\n        int x, y, val;\n        public Tuple (int x, int y, int val) {\n            this.x = x;\n            this.y = y;\n            this.val = val;\n        }\n\n        @Override\n        public int compareTo (Tuple that) {\n            return this.val - that.val;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/FindKthSmallestPairDistance719.java",
    "content": "/**\n * Given an integer array, return the k-th smallest distance among all the\n * pairs. The distance of a pair (A, B) is defined as the absolute difference\n * between A and B.\n * \n * Example 1:\n * Input:\n * nums = [1,3,1]\n * k = 1\n * Output: 0 \n * \n * Explanation:\n * Here are all the pairs:\n * (1,3) -> 2\n * (1,1) -> 0\n * (3,1) -> 2\n * \n * Then the 1st smallest distance pair is (1,1), and its distance is 0.\n * \n * Note:\n * 2 <= len(nums) <= 10000.\n * 0 <= nums[i] < 1000000.\n * 1 <= k <= len(nums) * (len(nums) - 1) / 2.\n */\n\npublic class FindKthSmallestPairDistance719 {\n    public int smallestDistancePair(int[] nums, int k) {\n        int len = nums.length;\n        int[] buckets = new int[1000000];\n        for (int i=0; i<len; i++) {\n            int a = nums[i];\n            for (int j=i+1; j<len; j++) {\n                buckets[Math.abs(a - nums[j])]++;\n            }\n        }\n        \n        int count = 0;\n        for (int i=0; i<1000000; i++) {\n            count += buckets[i];\n            if (count >= k) {\n                return i;\n            }\n        }\n        \n        return -1;\n    }\n\n\n    public int smallestDistancePair3(int[] nums, int k) {\n        int len = nums.length;\n        if (k == 0 || len == 0) return -1; \n        Arrays.sort(nums);\n        int lo = 0;\n        int hi = nums[nums.length - 1] - nums[0];\n        while (lo < hi) {\n            int mid = (lo + hi) / 2;\n            int cnt = count(nums, mid);\n            if (k <= cnt) {\n                hi = mid;\n            } else {\n                lo = mid+1;\n            }\n        }\n        return lo;\n    }\n\n    private int count(int[] nums, int x) {\n        int count = 0;\n        int left = 0;\n        int right = 0;\n        while (right < nums.length) {\n            while (nums[right] - nums[left] > x) {\n                left++;\n            }\n            count += right - left;\n            right++;\n        }\n        return count;\n    }\n\n}\n\n"
  },
  {
    "path": "src/FindLargestValueInEachTreeRow515.java",
    "content": "/**\n * You need to find the largest value in each row of a binary tree.\n * \n * Example:\n * Input: \n * \n *           1\n *          / \\\n *         3   2\n *        / \\   \\  \n *       5   3   9 \n * \n * Output: [1, 3, 9]\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class FindLargestValueInEachTreeRow515 {\n    public List<Integer> largestValues(TreeNode root) {\n        List<Integer> res = new ArrayList<>();\n        if (root == null) return res;\n        Queue<TreeNode> q = new LinkedList<>();\n        q.add(root);\n        while (!q.isEmpty()) {\n            int size = q.size();\n            int maxVal = Integer.MIN_VALUE;\n            for (int i=0; i<size; i++) {\n                TreeNode curr = q.poll();\n                if (curr.left != null) q.add(curr.left);\n                if (curr.right != null) q.add(curr.right);\n                maxVal = Math.max(maxVal, curr.val);\n            }\n            res.add(maxVal);\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/find-largest-value-in-each-tree-row/discuss/98971/9ms-JAVA-DFS-solution\n     */\n    public List<Integer> largestValues2(TreeNode root) {\n        List<Integer> res = new ArrayList<Integer>();\n        helper(root, res, 0);\n        return res;\n    }\n\n    private void helper(TreeNode root, List<Integer> res, int d){\n        if (root == null) return;\n        if (d == res.size()) { //expand list size\n            res.add(root.val);\n        } else{ //or set value\n            res.set(d, Math.max(res.get(d), root.val));\n        }\n        helper(root.left, res, d+1);\n        helper(root.right, res, d+1);\n    }\n\n}\n"
  },
  {
    "path": "src/FindMedianFromDataStream295.java",
    "content": "/**\n * Median is the middle value in an ordered integer list. If the size of the\n * list is even, there is no middle value. So the median is the mean of the two\n * middle value.\n * \n * For example,\n * [2,3,4], the median is 3\n * \n * [2,3], the median is (2 + 3) / 2 = 2.5\n * \n * Design a data structure that supports the following two operations:\n * \n * void addNum(int num) - Add a integer number from the data stream to the data structure.\n * double findMedian() - Return the median of all elements so far.\n * \n * Example:\n * addNum(1)\n * addNum(2)\n * findMedian() -> 1.5\n * addNum(3) \n * findMedian() -> 2\n */\n\n\npublic class FindMedianFromDataStream295 {\n    class MedianFinder {\n        private PriorityQueue<Integer> maxQ = new PriorityQueue<>(10, (i1, i2) -> Integer.compare(i2, i1));\n        private PriorityQueue<Integer> minQ = new PriorityQueue<>();\n        \n        /** initialize your data structure here. */\n        public MedianFinder() {\n            \n        }\n        \n        public void addNum(int num) {\n            if (maxQ.size() == 0 && minQ.size() == 0) {\n                maxQ.add(num);\n            } else if (maxQ.size() == 0) {\n                if (minQ.peek() < num) {\n                    minQ.add(num);\n                } else {\n                    maxQ.add(num);\n                }\n            } else {\n                if (maxQ.peek() > num) {\n                    maxQ.add(num);\n                } else {\n                    minQ.add(num);\n                }\n            }\n            while (maxQ.size() != 0 && maxQ.size() > minQ.size()) {\n                minQ.add(maxQ.poll());\n            }\n            while (minQ.size() != 0 && maxQ.size() < minQ.size()) {\n                maxQ.add(minQ.poll());\n            }\n        }\n      \n        public double findMedian() {\n            if (maxQ.size() == minQ.size()) {\n                return (maxQ.peek() + minQ.peek()) * 1.0 / 2;\n            } else if (maxQ.size() > minQ.size()) {\n                return maxQ.peek();\n            } else {\n                return minQ.peek();\n            }\n        }\n    }\n    \n\n    class MedianFinder2 {\n        private PriorityQueue<Integer> maxQ = new PriorityQueue<>(10, (i1, i2) -> Integer.compare(i2, i1));\n        private PriorityQueue<Integer> minQ = new PriorityQueue<>();\n        \n        /** initialize your data structure here. */\n        public MedianFinder() {\n            \n        }\n        \n        // slower than previous solution MedianFinder, but code is clearner\n        public void addNum(int num) {\n            maxQ.add(num);\n            minQ.add(maxQ.pop());\n            while (minQ.size() != 0 && maxQ.size() < minQ.size()) {\n                maxQ.add(minQ.poll());\n            }\n        }\n      \n        public double findMedian() {\n            if (maxQ.size() == minQ.size()) {\n                return (maxQ.peek() + minQ.peek()) * 1.0 / 2;\n            } else if (maxQ.size() > minQ.size()) {\n                return maxQ.peek();\n            } else {\n                return minQ.peek();\n            }\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/find-median-from-data-stream/discuss/74119/18ms-beats-100-Java-Solution-with-BST\n     */\n    class MedianFinder3 {\n        class TreeNode{\n            int val;\n            TreeNode parent,left,right;\n            TreeNode(int val, TreeNode p){\n                this.val=val;\n                this.parent=p;\n                left=null;\n                right=null;\n            }\n            void add(int num){\n                if(num>=val){\n                    if(right==null)\n                        right=new TreeNode(num,this);\n                    else\n                        right.add(num);\n                }else{\n                    if(left==null)\n                        left=new TreeNode(num,this);\n                    else\n                        left.add(num);\n                }\n            }\n            TreeNode next(){\n                TreeNode ret;\n                if(right!=null){\n                    ret=right;\n                    while(ret.left!=null)\n                        ret=ret.left;\n                }else{\n                    ret=this;\n                    while(ret.parent.right==ret)\n                        ret=ret.parent;\n                    ret=ret.parent;\n                }\n                return ret;\n            }\n            TreeNode prev(){\n                TreeNode ret;\n                if(left!=null){\n                    ret=left;\n                    while(ret.right!=null)\n                        ret=ret.right;\n                }else{\n                    ret=this;\n                    while(ret.parent.left==ret)\n                        ret=ret.parent;\n                    ret=ret.parent;\n                }\n                return ret;\n            }\n        }\n        int n;\n        TreeNode root, curr;\n        // Adds a number into the data structure.\n        public void addNum(int num) {\n            if(root==null){\n                root = new TreeNode(num,null);\n                curr=root;\n                n=1;\n            }else{\n                root.add(num);\n                n++;\n                if(n%2==1){\n                    if(curr.val<=num)\n                        curr=curr.next();\n                }else\n                    if(curr.val>num)\n                        curr=curr.prev();\n            }\n        }\n    \n        // Returns the median of current data stream\n        public double findMedian() {\n            if(n%2==0){\n                return ((double)curr.next().val+curr.val)/2;\n            }else\n                return curr.val;\n        }\n    };\n\n\n    class MedianFinder4 {\n        private PriorityQueue<Integer> left;\n        private PriorityQueue<Integer> right;\n        \n        /** initialize your data structure here. */\n        public MedianFinder() {\n            left = new PriorityQueue<>((i1, i2) -> Integer.compare(i2, i1));\n            right = new PriorityQueue<>((i1, i2) -> Integer.compare(i1, i2));\n        }\n        \n        public void addNum(int num) {\n            if (right.size() != 0 && right.peek() < num) {\n                right.add(num);\n                if (left.size() < right.size()) {\n                    left.add(right.poll());\n                }\n            } else { \n                left.add(num);\n                if (left.size() > right.size() + 1) {\n                    right.add(left.poll());\n                }\n            }\n    \n        }\n        \n        public double findMedian() {\n            if (left.size() == right.size()) {\n                return ((double) left.peek() + (double) right.peek()) / 2.0;\n            } else {\n                return (double) left.peek();\n            }\n            \n        }\n    }\n\n\n/**\n * Your MedianFinder object will be instantiated and called as such:\n * MedianFinder obj = new MedianFinder();\n * obj.addNum(num);\n * double param_2 = obj.findMedian();\n */\n\n}\n\n\n"
  },
  {
    "path": "src/FindMinimumInRotatedSortedArray153.java",
    "content": "/**\n * Suppose an array sorted in ascending order is rotated at some pivot unknown\n * to you beforehand.\n * \n * (i.e.,  [0,1,2,4,5,6,7] might become  [4,5,6,7,0,1,2]).\n * \n * Find the minimum element.\n * \n * You may assume no duplicate exists in the array.\n * \n * Example 1:\n * \n * Input: [3,4,5,1,2] \n * Output: 1\n * Example 2:\n * \n * Input: [4,5,6,7,0,1,2]\n * Output: 0\n * \n */\n\n\npublic class FindMinimumInRotatedSortedArray153 {\n    public int findMin(int[] nums) {\n        return findMin(nums, 0, nums.length-1);\n    }\n\n    public int findMin(int[] nums, int s, int e) {\n        if (nums[s] <= nums[e]) return nums[s];\n        int mid = (s + e) / 2;\n        return Math.min(findMin(nums, s, mid), findMin(nums, mid+1, e));\n    }\n\n\n    public int findMin2(int[] nums) {\n        int s = 0;\n        int e = nums.length-1;\n        while (s < e) {\n            int mid = (s + e) / 2;\n            if (nums[mid] > nums[e]) {\n                s = mid + 1;\n            } else {\n                e = mid;\n            }\n        }\n        return nums[e];\n    }\n\n\n    public int findMin3(int[] nums) {\n        int start = 0;\n        int end = nums.length - 1;\n        int startVal = nums[start];\n        int endVal = nums[end];\n        while (start + 1 < end) {\n            int mid = start + (end - start) / 2;\n            if (nums[mid] > startVal) {\n                start = mid;\n            } else if (nums[mid] < endVal) {\n                end = mid;\n            }\n        }\n        \n        return Math.min(nums[end], Math.min(nums[start], Math.min(startVal, endVal)));\n    }\n\n\n    public int findMin4(int[] nums) {\n        for (int i=1; i<nums.length; i++) {\n            if (nums[i] < nums[i-1]) return nums[i];\n        }\n        return nums[0];\n    }\n\n}\n"
  },
  {
    "path": "src/FindMinimumInRotatedSortedArrayII154.java",
    "content": "/**\n * Suppose an array sorted in ascending order is rotated at some pivot unknown\n * to you beforehand.\n * \n * (i.e.,  [0,1,2,4,5,6,7] might become  [4,5,6,7,0,1,2]).\n * \n * Find the minimum element.\n * \n * The array may contain duplicates.\n * \n * Example 1:\n * Input: [1,3,5]\n * Output: 1\n * \n * Example 2:\n * Input: [2,2,2,0,1]\n * Output: 0\n * \n * Note:\n * This is a follow up problem to Find Minimum in Rotated Sorted Array.\n * Would allow duplicates affect the run-time complexity? How and why?\n */\n\n\npublic class FindMinimumInRotatedSortedArrayII154 {\n    public int findMin(int[] nums) {\n        for (int i=1; i<nums.length; i++) {\n            if (nums[i] < nums[i-1]) return nums[i];\n        }\n        return nums[0];\n    }\n\n\n    public int findMin2(int[] nums) {\n        return findMin(nums, 0, nums.length-1);\n    }\n    \n    private int findMin(int[] nums, int i, int j) {\n        if (i == j) return nums[i];\n        if (nums[i] < nums[j]) return nums[i];\n        int mid = (i + j) / 2;\n        return Math.min(findMin(nums, i, mid), findMin(nums, mid+1, j));\n    }\n\n\n    public int findMin3(int[] nums) {\n        int s = 0;\n        int e = nums.length-1;\n        while (s < e) {\n            int mid = (s + e) / 2;\n            if (nums[mid] < nums[e]) {\n                e = mid;\n            } else if (nums[mid] > nums[e]) {\n                s = mid + 1;\n            } else {\n                e--;\n            }\n            \n        }\n        return nums[s];\n    }\n\n}\n"
  },
  {
    "path": "src/FindModeInBinarySearchTree501.java",
    "content": "/**\n * Given a binary search tree (BST) with duplicates, find all the mode(s)\n * (the most frequently occurred element) in the given BST.\n * \n * Assume a BST is defined as follows:\n *  - The left subtree of a node contains only nodes with keys less than or equal to the node's key.\n *  - The right subtree of a node contains only nodes with keys greater than or equal to the node's key.\n *  - Both the left and right subtrees must also be binary search trees.\n * For example:\n * Given BST [1,null,2,2],\n * \n *    1\n *     \\\n *      2\n *     /\n *    2\n *  \n * return [2].\n * \n * Note: If a tree has more than one mode, you can return them in any order.\n * \n * Follow up: Could you do that without using any extra space? (Assume that the\n * implicit stack space incurred due to recursion does not count).\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class FindModeInBinarySearchTree501 {\n    public int[] findMode(TreeNode root) {\n        Result result = new Result();\n        findMode(root, result);\n        int[] output = new int[result.res.size()];\n        int i = 0;\n        for (int r: result.res) {\n            output[i++] = r;\n        }\n        return output;\n    }\n\n    private void findMode(TreeNode root, Result result) {\n        if (root == null) return;\n\n        findMode(root.left, result);\n        \n        if (result.maxCount == -1) {\n            result.maxCount = 1;\n            result.currCount = 1;\n            result.curr = root.val;\n            result.res = new HashSet<>();\n            result.res.add(root.val);\n        } else if (result.curr != root.val) {\n            result.currCount = 1;\n            result.curr = root.val;\n            if (result.maxCount == result.currCount) {\n                result.res.add(root.val);\n            }\n        } else {\n            result.currCount++;\n            if (result.maxCount == result.currCount) {\n                result.res.add(root.val);\n            } else if (result.maxCount < result.currCount) {\n                result.maxCount = result.currCount;\n                result.res = new HashSet<>();\n                result.res.add(root.val);\n            }\n        }\n\n        findMode(root.right, result);\n    }\n\n    class Result {\n        int maxCount;\n        int currCount;\n        int curr;\n        Set<Integer> res;\n        Result() {\n            this.maxCount = -1;\n            this.currCount = -1;\n            this.curr = 0;\n            this.res = new HashSet<>();\n        }\n    }\n    \n\n    /**\n     * https://leetcode.com/problems/find-mode-in-binary-search-tree/discuss/98101/Proper-O(1)-space\n     */\n    public int[] findMode2(TreeNode root) {\n        inorder(root);\n        modes = new int[modeCount];\n        modeCount = 0;\n        currCount = 0;\n        inorder(root);\n        return modes;\n    }\n\n    private int currVal;\n    private int currCount = 0;\n    private int maxCount = 0;\n    private int modeCount = 0;\n    \n    private int[] modes;\n\n    private void handleValue(int val) {\n        if (val != currVal) {\n            currVal = val;\n            currCount = 0;\n        }\n        currCount++;\n        if (currCount > maxCount) {\n            maxCount = currCount;\n            modeCount = 1;\n        } else if (currCount == maxCount) {\n            if (modes != null)\n                modes[modeCount] = currVal;\n            modeCount++;\n        }\n    }\n    \n    private void inorder(TreeNode root) {\n        if (root == null) return;\n        inorder(root.left);\n        handleValue(root.val);\n        inorder(root.right);\n    }\n\n}\n"
  },
  {
    "path": "src/FindPeakElement162.java",
    "content": "/**\n * A peak element is an element that is greater than its neighbors.\n *\n * Given an input array where num[i] ≠ num[i+1], find a peak element and return\n * its index.\n *\n * The array may contain multiple peaks, in that case return the index to any\n * one of the peaks is fine.\n *\n * You may imagine that num[-1] = num[n] = -∞.\n *\n * For example, in array [1, 2, 3, 1], 3 is a peak element and your function\n * should return the index number 2.\n *\n * Note:\n * Your solution should be in logarithmic complexity.\n */\n\npublic class FindPeakElement162 {\n    public int findPeakElement(int[] nums) {\n        if (nums == null || nums.length == 0) return -1;\n        if (nums.length == 1) return 0;\n\n        if (nums[0] > nums[1]) {\n            return 0;\n        } else if (nums[nums.length-1] > nums[nums.length-2]) {\n            return nums.length-1;\n        } else {\n            for (int i=1; i<nums.length-1; i++) {\n                if (nums[i] > nums[i-1] && nums[i] > nums[i+1]) return i;\n            }\n        }\n        return -1;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/find-peak-element/solution/\n     */\n    public int findPeakElement2(int[] nums) {\n        for (int i = 0; i < nums.length - 1; i++) {\n            if (nums[i] > nums[i + 1])\n                return i;\n        }\n        return nums.length - 1;\n    }\n\n\n    public int findPeakElement3(int[] nums) {\n        return search(nums, 0, nums.length - 1);\n    }\n    public int search(int[] nums, int l, int r) {\n        if (l == r)\n            return l;\n        int mid = (l + r) / 2;\n        if (nums[mid] > nums[mid + 1])\n            return search(nums, l, mid);\n        return search(nums, mid + 1, r);\n    }\n\n\n    public int findPeakElement4(int[] nums) {\n        int l = 0, r = nums.length - 1;\n        while (l < r) {\n            int mid = (l + r) / 2;\n            if (nums[mid] > nums[mid + 1])\n                r = mid;\n            else\n                l = mid + 1;\n        }\n        return l;\n    }\n\n}\n"
  },
  {
    "path": "src/FindTheCelebrity277.java",
    "content": "/**\n * Suppose you are at a party with n people (labeled from 0 to n - 1) and among\n * them, there may exist one celebrity. The definition of a celebrity is that\n * all the other n - 1 people know him/her but he/she does not know any of them.\n *\n * Now you want to find out who the celebrity is or verify that there is not\n * one. The only thing you are allowed to do is to ask questions like:\n * \"Hi, A. Do you know B?\" to get information of whether A knows B. You need to\n * find out the celebrity (or verify there is not one) by asking as few\n * questions as possible (in the asymptotic sense).\n *\n * You are given a helper function bool knows(a, b) which tells you whether A\n * knows B. Implement a function int findCelebrity(n), your function should\n * minimize the number of calls to knows.\n *\n * Note: There will be exactly one celebrity if he/she is in the party. Return\n * the celebrity's label if there is a celebrity in the party. If there is no\n * celebrity, return -1.\n */\n\n/* The knows API is defined in the parent class Relation.\n      boolean knows(int a, int b); */\n\npublic class FindTheCelebrity277 {\n    // brutal force, accepted\n    public int findCelebrity(int n) {\n        boolean[] notCelebrity = new boolean[n];\n        int[] known = new int[n];\n\n        for (int a=0; a<n; a++) {\n            for (int b=0; b<n; b++) {\n                if (a != b && knows(a, b)) {\n                    notCelebrity[a] = true;\n                    known[b]++;\n                }\n            }\n        }\n\n        for (int i=0; i<n; i++) {\n            if (!notCelebrity[i] && known[i] == n-1) {\n                return i;\n            }\n        }\n        return -1;\n    }\n\n\n    public int findCelebrity2(int n) {\n        Set<Integer> celebrities = new HashSet<>();\n        for (int i=0; i<n; i++) celebrities.add(i);\n\n        for (int a=0; a<n; a++) {\n            for (int b=0; b<n; b++) {\n                if (a != b && knows(a, b)) {\n                    celebrities.remove(a);\n                    break;\n                }\n            }\n        }\n\n        if (celebrities.size() != 1) return -1;\n\n        int possibleC = celebrities.iterator().next();\n        for (int i=0; i<n; i++) {\n            if (i == possibleC) continue;\n            if (!knows(i, possibleC)) {\n                return -1;\n            }\n        }\n        return possibleC;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/find-the-celebrity/discuss/71227/Java-Solution.-Two-Pass\n     */\n    public int findCelebrity3(int n) {\n        int candidate = 0;\n        for(int i = 1; i < n; i++){\n            if(knows(candidate, i))\n                candidate = i;\n        }\n        for(int i = 0; i < n; i++){\n            if(i != candidate && (knows(candidate, i) || !knows(i, candidate))) return -1;\n        }\n        return candidate;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/find-the-celebrity/discuss/71228/JavaPython-O(n)-calls-O(1)-space-easy-to-understand-solution\n     */\n    public int findCelebrity4(int n) {\n        int x = 0;\n        for (int i = 0; i < n; ++i) if (knows(x, i)) x = i;\n        for (int i = 0; i < x; ++i) if (knows(x, i)) return -1;\n        for (int i = 0; i < n; ++i) if (!knows(i, x)) return -1;\n        return x;\n    }\n\n\n    public int findCelebrity5(int n) {\n        if (n == 0) return -1;\n        if (n == 1) return 0;\n        \n        int left = 0;\n        int right = 1;\n        while (left < n) {\n            if (!knows(left, right) && knows(right, left)) {\n                right++;\n            } else {\n                left = right;\n                right++;\n            }\n            while (right == n) {\n                boolean found = true;\n                for (int i=0; i<left; i++) {\n                    if (knows(left, i) || !knows(i, left)) {\n                        found = false;\n                        break;\n                    }\n                }\n                if (found) return left;\n                left++;\n                right = left + 1;\n            }\n        }\n        \n        return -1;\n    }\n\n}\n"
  },
  {
    "path": "src/FindTheDuplicateNumber287.java",
    "content": "/**\n * Given an array nums containing n + 1 integers where each integer is between\n * 1 and n (inclusive), prove that at least one duplicate number must exist.\n * Assume that there is only one duplicate number, find the duplicate one.\n * \n * Example 1:\n * Input: [1,3,4,2,2]\n * Output: 2\n * \n * Example 2:\n * Input: [3,1,3,4,2]\n * Output: 3\n * \n *  Note:\n * You must not modify the array (assume the array is read only).\n * You must use only constant, O(1) extra space.\n * Your runtime complexity should be less than O(n2).\n * There is only one duplicate number in the array, but it could be repeated\n * more than once.\n */\n\npublic class FindTheDuplicateNumber287 {\n    public int findDuplicate(int[] nums) {\n      int low = 1, high = nums.length - 1;\n        while (low < high) {\n            int mid = (int) (low + (high - low) * 0.5);\n            int cnt = 0;\n            for (int a : nums) {\n                if (a <= mid) ++cnt;\n            }\n            if (cnt <= mid) low = mid + 1;\n            else high = mid;\n        }\n        return low;\n    }\n\n    public int findDuplicate2(int[] nums) {\n        int fast = nums[0];\n        int slow = nums[0];\n        while (true) {\n            // System.out.println(\"slow: \" + slow + \"; \" + \"fast: \" + fast);\n            fast = nums[nums[fast]];\n            slow = nums[slow];\n            if (slow == fast) break;\n        }\n        \n        fast = nums[0];\n        while (fast != slow) {\n            fast = nums[fast];\n            slow = nums[slow];\n        }\n        return slow;\n    }\n\n\n    // This modified the input array!\n    // public int findDuplicate(int[] nums) {\n    //     int N = nums.length;\n    //     Arrays.sort(nums);\n        \n    //     for (int i=0; i<N-1; i++) {\n    //         if (nums[i] == nums[i+1]) return nums[i];\n    //     }\n    //     return nums[0];\n    // }\n\n}\n"
  },
  {
    "path": "src/FirstBadVersion278.java",
    "content": "/**\n * You are a product manager and currently leading a team to develop a new\n * product. Unfortunately, the latest version of your product fails the quality\n * check. Since each version is developed based on the previous version, all\n * the versions after a bad version are also bad.\n *\n * Suppose you have n versions [1, 2, ..., n] and you want to find out the first\n * bad one, which causes all the following ones to be bad.\n *\n * You are given an API bool isBadVersion(version) which will return whether\n * sversion is bad. Implement a function to find the first bad version. You\n * should minimize the number of calls to the API.\n *\n */\n\n\n/* The isBadVersion API is defined in the parent class VersionControl.\n      boolean isBadVersion(int version); */\n\npublic class FirstBadVersion278 extends VersionControl {\n    // time limited\n    public int firstBadVersion(int n) {\n        return firstBadVersion(1, n);\n    }\n\n    private int firstBadVersion(int i, int j) {\n        if (i == j) return isBadVersion(i) ? i : -1;\n\n        int mid = i+(j-i)/2;\n        int f = firstBadVersion(i, mid);\n\n        return (f != -1) ? f : firstBadVersion(mid+1, j);\n    }\n\n\n    public int firstBadVersion2(int n) {\n        int i = 1;\n        int j = n;\n        int mid = 0;\n        while (i <= j) {\n            if (i == j) return i;\n            mid = i+(j-i)/2;\n            if (isBadVersion(mid)) j = mid;\n            else i = mid+1;\n        }\n        return -1;\n    }\n\n}\n"
  },
  {
    "path": "src/FirstMissingPositive41.java",
    "content": "/**\n * Given an unsorted integer array, find the first missing positive integer.\n *\n * For example,\n * Given [1,2,0] return 3,\n * and [3,4,-1,1] return 2.\n *\n * Your algorithm should run in O(n) time and uses constant space.\n */\n\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n\npublic class FirstMissingPositive41 {\n    public int firstMissingPositive(int[] nums) {\n\n        List<Boolean> isMissing = new ArrayList<>();\n        isMissing.add(false);\n\n        int firstMissing = 1;\n\n        for (int i = 0; i < nums.length; i++) {\n            int now = nums[i];\n            if (now > 0) {\n                try {\n\n                    if (isMissing.get(now)) {\n                        isMissing.set(now, false);\n                    }\n\n                } catch (IndexOutOfBoundsException e) {\n\n\n                    while (isMissing.size() < now) {\n                        isMissing.add(true);\n                    }\n\n                    isMissing.add(false);\n                }\n\n\n            }\n            try {\n                while (!isMissing.get(firstMissing)) {\n                    firstMissing++;\n                }\n            } catch (IndexOutOfBoundsException e) {\n                isMissing.add(true);\n            }\n\n\n        }\n\n        return firstMissing;\n\n    }\n\n\n    /**\n     * \n     */\n    public int firstMissingPositive2(int[] nums) {\n        if (nums == null || nums.length == 0) {\n            return 1;\n        }\n\n        for (int i = 0; i < nums.length; ++i) {\n            while (nums[i] > 0 && nums[i] <= nums.length && nums[i] - 1 != i) {\n                int tmp = nums[nums[i] - 1];\n                if (tmp == nums[i]) {\n                    break;\n                }\n                nums[nums[i] - 1] = nums[i];\n                nums[i] = tmp;\n            }\n        }\n\n        for (int i = 0; i < nums.length; ++i) {\n            if (nums[i] != i + 1) {\n                return i + 1;\n            }\n        }\n\n        return nums.length + 1;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/first-missing-positive/discuss/17083/O(1)-space-Java-Solution\n     */\n    public int firstMissingPositive3(int[] A) {\n        int i = 0;\n        while(i < A.length){\n            if(A[i] == i+1 || A[i] <= 0 || A[i] > A.length) i++;\n            else if (A[A[i]-1] != A[i]) swap(A, i, A[i]-1);\n            else i++;\n        }\n        i = 0;\n        while(i < A.length && A[i] == i+1) i++;\n        return i+1;\n    }\n    \n    private void swap(int[] A, int i, int j){\n        int temp = A[i];\n        A[i] = A[j];\n        A[j] = temp;\n    }\n\n\n    public int firstMissingPositive4(int[] nums) {\n        if (nums == null || nums.length == 0) return 1;\n        int N = nums.length;\n        for (int i=0; i<N; i++) {\n            int idx = i;\n            int val = nums[idx];\n            while (idx >= 0 && idx < N && val > 0 && val <= N && nums[idx] != idx + 1) {\n                int newVal = nums[val - 1];\n                nums[val - 1] = val;\n                idx = newVal - 1;\n                val = newVal;\n            }\n        }\n        \n        for (int i=0; i<N; i++) {\n            if (nums[i] != i + 1) {\n                return i + 1;\n            }\n        }\n        return N + 1;\n    }\n\n}\n"
  },
  {
    "path": "src/FirstUniqueCharacterInAString387.java",
    "content": "/**\n * Given a string, find the first non-repeating character in it and return it's\n * index. If it doesn't exist, return -1.\n *\n * Examples:\n *\n * s = \"leetcode\"\n * return 0.\n *\n * s = \"loveleetcode\",\n * return 2.\n *\n * Note: You may assume the string contain only lowercase letters.\n *\n */\n\n\npublic class FirstUniqueCharacterInAString387 {\n    public int firstUniqChar(String s) {\n        if (s == null || s.length() == 0) return -1;\n        if (s.length() == 1) return 0;\n        int len = s.length();\n\n        int[] pos = new int[26];\n        boolean[] bs = new boolean[26];\n        for (int j=0; j<26; j++) pos[j] = -1;\n\n        char[] arr = s.toCharArray();\n        for (int i=0; i<len; i++) {\n            int p = arr[i] - 'a';\n            if (pos[p] == -1) {\n                pos[p] = i;\n            } else {\n                bs[p] = true;\n            }\n        }\n\n        int res = Integer.MAX_VALUE;\n        for (int j=0; j<26; j++) {\n            if (!bs[j] && pos[j] != -1) {\n                res = Math.min(res, pos[j]);\n            }\n        }\n\n        return res == Integer.MAX_VALUE ? -1 : res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/first-unique-character-in-a-string/discuss/86348/Java-7-lines-solution-29ms\n     */\n    public int firstUniqChar2(String s) {\n        int[] alp =new int[26];\n        char[] arr =s.toCharArray();\n\n        for(char c : arr ){\n            alp[c-'a']++;\n        }\n\n        for(int i=0;i<arr.length;i++){\n            if (alp[arr[i]-'a']==1) return i;\n        }\n\n        return -1;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/first-unique-character-in-a-string/discuss/86340/Java-two-pointers-(slow-and-fast)-solution-(18-ms)\n     */\n    public int firstUniqChar3(String s) {\n        if (s==null || s.length()==0) return -1;\n        int len = s.length();\n        if (len==1) return 0;\n        char[] cc = s.toCharArray();\n        int slow =0, fast=1;\n        int[] count = new int[256];\n        count[cc[slow]]++;\n        while (fast < len) {\n            count[cc[fast]]++;\n            // if slow pointer is not a unique character anymore, move to the next unique one\n            while (slow < len && count[cc[slow]] > 1) slow++;\n            if (slow >= len) return -1; // no unique character exist\n            if (count[cc[slow]]==0) { // not yet visited by the fast pointer\n                count[cc[slow]]++;\n                fast=slow; // reset the fast pointer\n            }\n            fast++;\n        }\n        return slow;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/first-unique-character-in-a-string/discuss/86359/my-4-lines-Java-solution\n     */\n    public static int firstUniqChar4(String s) {\n        char[] a = s.toCharArray();\n\n        for(int i=0; i<a.length;i++){\n            if(s.indexOf(a[i])==s.lastIndexOf(a[i])){return i;}\n        }\n        return -1;\n    }\n\n\n    public int firstUniqChar5(String s) {\n        int[] map = new int[26];\n        char[] chars = s.toCharArray();\n        int slow = 0;\n        int fast = 0;\n        int N = chars.length;\n        while (slow < N) {\n            while (slow < fast && map[chars[slow]-'a'] > 1) slow++;\n            if (fast == N) break;\n            map[chars[fast]-'a']++;\n            fast++;\n        }\n        return slow == N ? -1 : slow;\n    }\n\n\n    public int firstUniqChar6(String s) {\n        int[] map = new int[26];\n        char[] chars = s.toCharArray();\n        int slow = 0;\n        int fast = 0;\n        int N = chars.length;\n        while (slow < N) {\n            map[chars[fast]-'a']++;\n            fast++;\n            while (slow < fast && map[chars[slow]-'a'] > 1) slow++;\n            if (fast == N) break;\n        }\n        return slow == N ? -1 : slow;\n    }\n\n}\n"
  },
  {
    "path": "src/FizzBuzz412.java",
    "content": "/**\n * Write a program that outputs the string representation of numbers from 1 to n.\n * \n * But for multiples of three it should output “Fizz” instead of the number and\n * for the multiples of five output “Buzz”. For numbers which are multiples of\n * both three and five output “FizzBuzz”.\n * \n * Example: n = 15,\n * Return:\n * [\n *     \"1\",\n *     \"2\",\n *     \"Fizz\",\n *     \"4\",\n *     \"Buzz\",\n *     \"Fizz\",\n *     \"7\",\n *     \"8\",\n *     \"Fizz\",\n *     \"Buzz\",\n *     \"11\",\n *     \"Fizz\",\n *     \"13\",\n *     \"14\",\n *     \"FizzBuzz\"\n * ]\n */\n\npublic class FizzBuzz412 {\n    public List<String> fizzBuzz(int n) {\n        List<String> res = new ArrayList<>();\n        for (int i=1; i<=n; i++) {\n            boolean isFizz = i % 3 == 0;\n            boolean isBuzz = i % 5 == 0;\n            if (isFizz && isBuzz) {\n                res.add(\"FizzBuzz\");\n            } else if (isFizz) {\n                res.add(\"Fizz\");\n            } else if (isBuzz) {\n                res.add(\"Buzz\");\n            } else {\n                res.add(Integer.toString(i));\n            }\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/Flatten2DVector251.java",
    "content": "/**\n * Implement an iterator to flatten a 2d vector.\n * \n * Example:\n * \n * Input: 2d vector =\n * [\n *   [1,2],\n *   [3],\n *   [4,5,6]\n * ]\n * Output: [1,2,3,4,5,6]\n * Explanation: By calling next repeatedly until hasNext returns false, \n *              the order of elements returned by next should be: [1,2,3,4,5,6].\n * \n * Follow up:\n * As an added challenge, try to code it using only iterators in C++ or\n * iterators in Java.\n */\n\npublic class Flatten2DVector251 {\n    class Vector2D implements Iterator<Integer> {\n        private Iterator<List<Integer>> iter2d;\n        private Iterator<Integer> iter;\n        \n        public Vector2D(List<List<Integer>> vec2d) {\n            iter2d = vec2d.iterator();\n            if (iter2d.hasNext()) {\n                iter = iter2d.next().iterator();\n            } else {\n                iter = (new ArrayList<Integer>()).iterator();\n            }\n        }\n\n        @Override\n        public Integer next() {\n            hasNext();\n            return iter.next();\n        }\n\n        @Override\n        public boolean hasNext() {\n            while (!iter.hasNext()) {\n                if (!iter2d.hasNext()) return false;\n                iter = iter2d.next().iterator();\n            }\n            return iter.hasNext();\n        }\n    }\n\n/**\n * Your Vector2D object will be instantiated and called as such:\n * Vector2D i = new Vector2D(vec2d);\n * while (i.hasNext()) v[f()] = i.next();\n */\n\n}\n\n"
  },
  {
    "path": "src/FlattenBinaryTreeToLinkedList114.java",
    "content": "/**\n * Given a binary tree, flatten it to a linked list in-place.\n *\n * For example,\n * Given\n *         1\n *        / \\\n *       2   5\n *      / \\   \\\n *    3   4   6\n *\n * The flattened tree should look like:\n *  1\n *   \\\n *   2\n *    \\\n *     3\n *      \\\n *       4\n *        \\\n *         5\n *          \\\n *           6\n */\n\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class FlattenBinaryTreeToLinkedList114 {\n    public void flatten(TreeNode root) {\n        flattenNode(root);\n    }\n\n    private TreeNode flattenNode(TreeNode root) {\n        if (root == null) return null;\n        TreeNode left = root.left;\n        TreeNode right = root.right;\n\n        root.left = null;\n\n        if (left == null && right == null) {\n            return root;\n        } else if (left == null && right != null) {\n            TreeNode rightEnd = flattenNode(right);\n            return rightEnd;\n        } else if (left != null && right == null) {\n            TreeNode leftEnd = flattenNode(left);\n            root.right = left;\n            return leftEnd;\n        } else {\n            TreeNode leftEnd = flattenNode(left);\n            TreeNode rightEnd = flattenNode(right);\n            leftEnd.right = right;\n            root.right = left;\n            return rightEnd;\n        }\n    }\n\n    public void flatten2(TreeNode root) {\n        helper(root);\n    }\n\n    private TreeNode helper(TreeNode root) {\n        if (root == null || (root.left == null && root.right == null)) return root;\n\n        TreeNode leftLast = helper(root.left);\n\n        if (leftLast != null) {\n            leftLast.right = root.right;\n            root.right = root.left;\n            root.left = null;\n        }\n\n        return helper(root.right);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/flatten-binary-tree-to-linked-list/discuss/37010/Share-my-simple-NON-recursive-solution-O(1)-space-complexity!\n     */\n    public void flatten3(TreeNode root) {\n    \tTreeNode cur = root;\n    \twhile (cur != null) {\n    \t\tif (cur.left != null) {\n    \t\t\tTreeNode last = cur.left;\n    \t\t\twhile (last.right != null) last = last.right;\n    \t\t\tlast.right = cur.right;\n    \t\t\tcur.right = cur.left;\n    \t\t\tcur.left = null;\n    \t\t}\n    \t\tcur = cur.right;\n    \t}\n    }\n\n\n    /**\n     * https://leetcode.com/problems/flatten-binary-tree-to-linked-list/discuss/36977/My-short-post-order-traversal-Java-solution-for-share\n     */\n    public void flatten4(TreeNode root) {\n        flatten(root,null);\n    }\n\n    private TreeNode flatten(TreeNode root, TreeNode pre) {\n        if(root==null) return pre;\n        pre=flatten(root.right,pre);\n        pre=flatten(root.left,pre);\n        root.right=pre;\n        root.left=null;\n        pre=root;\n        return pre;\n    }\n\n\n    public static void main(String[] args) {\n        FlattenBinaryTreeToLinkedList114 fbt2ll = new FlattenBinaryTreeToLinkedList114();\n\n        TreeNode n1 = new TreeNode(1);\n        TreeNode n2 = new TreeNode(2);\n        TreeNode n3 = new TreeNode(3);\n        TreeNode n4 = new TreeNode(4);\n        TreeNode n5 = new TreeNode(5);\n        TreeNode n6 = new TreeNode(6);\n\n        n1.left = n2;\n        n1.right = n5;\n        n2.left = n3;\n        n2.right = n4;\n        n5.right = n6;\n\n        fbt2ll.flatten(n1);\n        System.out.println(\"Out!\");\n        System.out.println(n1.val);\n        System.out.println(n1.right.val);\n        System.out.println(n1.right.right.val);\n        System.out.println(n1.right.right.right.val);\n        System.out.println(n1.right.right.right.right.val);\n        System.out.println(n1.right.right.right.right.right.val);\n    }\n\n}\n"
  },
  {
    "path": "src/FlipGame293.java",
    "content": "/**\n * You are playing the following Flip Game with your friend: Given a string\n * that contains only these two characters: + and -, you and your friend take\n * turns to flip two consecutive \"++\" into \"--\". The game ends when a person\n * can no longer make a move and therefore the other person will be the winner.\n * \n * Write a function to compute all possible states of the string after one\n * valid move.\n * \n * Example:\n * Input: s = \"++++\"\n * Output: \n * [\n *   \"--++\",\n *   \"+--+\",\n *   \"++--\"\n * ]\n * Note: If there is no valid move, return an empty list [].\n */\n\npublic class FlipGame293 {\n    public List<String> generatePossibleNextMoves(String s) {\n        List<String> res = new ArrayList<>();\n        if (s == null || s.length() <= 1) return res;\n        char[] chars = s.toCharArray();\n        \n        for (int i=0; i<s.length()-1; i++) {\n            if (chars[i] == chars[i+1] && chars[i] == '+') {\n                chars[i] = '-';\n                chars[i+1] = '-';\n                res.add(new String(chars));\n                chars[i] = '+';\n                chars[i+1] = '+';\n            }\n        }\n        \n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/FlippingAnImage832.java",
    "content": "/**\n * Given a binary matrix A, we want to flip the image horizontally, then invert\n * it, and return the resulting image.\n * \n * To flip an image horizontally means that each row of the image is reversed.\n * For example, flipping [1, 1, 0] horizontally results in [0, 1, 1].\n * \n * To invert an image means that each 0 is replaced by 1, and each 1 is\n * replaced by 0. For example, inverting [0, 1, 1] results in [1, 0, 0].\n * \n * Example 1:\n * Input: [[1,1,0],[1,0,1],[0,0,0]]\n * Output: [[1,0,0],[0,1,0],[1,1,1]]\n * Explanation: First reverse each row: [[0,1,1],[1,0,1],[0,0,0]].\n * Then, invert the image: [[1,0,0],[0,1,0],[1,1,1]]\n * \n * Example 2:\n * Input: [[1,1,0,0],[1,0,0,1],[0,1,1,1],[1,0,1,0]]\n * Output: [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]]\n * Explanation: First reverse each row: [[0,0,1,1],[1,0,0,1],[1,1,1,0],[0,1,0,1]].\n * Then invert the image: [[1,1,0,0],[0,1,1,0],[0,0,0,1],[1,0,1,0]]\n * \n * Notes:\n * 1 <= A.length = A[0].length <= 20\n * 0 <= A[i][j] <= 1\n */\n\npublic class FlippingAnImage832 {\n    public int[][] flipAndInvertImage(int[][] A) {\n        int N = A.length;\n        int[][] res = new int[N][N];\n        for (int i=0; i<N; i++) {\n            for (int j=0; j<N; j++) {\n                res[i][j] = 1 - A[i][N - j-1];\n            }\n        }\n        return res;\n    }\n\n\n    public int[][] flipAndInvertImage2(int[][] A) {\n        for (int i=0; i<A.length; i++) {\n            reverseAndFlip(A[i]);\n        }\n        return A;\n    }\n    \n    private void reverseAndFlip(int[] row) {\n        int lo = 0;\n        int hi = row.length - 1;\n        while (lo <= hi) {\n            swapAndFlip(row, lo++, hi--);\n        }\n    }\n    \n    private void swapAndFlip(int[] row, int i, int j) {\n        if (i == j) {\n            row[i] = 1 - row[i];\n            return;\n        }\n        int tmp = row[i];\n        row[i] = 1 - row[j];\n        row[j] = 1- tmp;\n    }\n\n}\n"
  },
  {
    "path": "src/FourSum18.java",
    "content": "/**\n * Given an array nums of n integers and an integer target, are there elements\n * a, b, c, and d in nums such that a + b + c + d = target? Find all unique\n * quadruplets in the array which gives the sum of target.\n * \n * Note:\n * \n * The solution set must not contain duplicate quadruplets.\n * \n * Example:\n * \n * Given array nums = [1, 0, -1, 0, -2, 2], and target = 0.\n * \n * A solution set is:\n * [\n *   [-1,  0, 0, 1],\n *   [-2, -1, 1, 2],\n *   [-2,  0, 0, 2]\n * ]\n */\n\npublic class FourSum18 {\n    public List<List<Integer>> fourSum(int[] nums, int target) {\n        Arrays.sort(nums);\n        List<List<Integer>> res = new ArrayList<>();\n        for (int i=0; i<nums.length-3; i++) {\n            if (i == 0 || nums[i] != nums[i-1]) {\n                for (int j=i+1; j<nums.length-2; j++) {\n                    if (j == i+1 || nums[j] != nums[j-1]) {\n                        int expected = target - nums[i] - nums[j];\n                        int lo = j + 1;\n                        int hi = nums.length - 1;\n                        while (lo < hi) {\n                            int twoSum = nums[lo] + nums[hi];\n                            if (twoSum == expected) {\n                                res.add(Arrays.asList(nums[i], nums[j], nums[lo], nums[hi]));\n                                while (lo < hi && nums[lo] == nums[lo+1]) lo++;\n                                while (lo < hi && nums[hi] == nums[hi-1]) hi--;\n                                lo++;\n                                hi--;\n                            } else if (twoSum > expected) {\n                                hi--;\n                            } else {\n                                lo++;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/4sum/discuss/8575/Clean-accepted-java-O(n3)-solution-based-on-3sum\n     */\n    public List<List<Integer>> fourSum2(int[] num, int target) {\n        ArrayList<List<Integer>> ans = new ArrayList<>();\n        if(num.length<4)return ans;\n        Arrays.sort(num);\n        for(int i=0; i<num.length-3; i++){\n            if(num[i]+num[i+1]+num[i+2]+num[i+3]>target)break; //first candidate too large, search finished\n            if(num[i]+num[num.length-1]+num[num.length-2]+num[num.length-3]<target)continue; //first candidate too small\n            if(i>0&&num[i]==num[i-1])continue; //prevents duplicate result in ans list\n            for(int j=i+1; j<num.length-2; j++){\n                if(num[i]+num[j]+num[j+1]+num[j+2]>target)break; //second candidate too large\n                if(num[i]+num[j]+num[num.length-1]+num[num.length-2]<target)continue; //second candidate too small\n                if(j>i+1&&num[j]==num[j-1])continue; //prevents duplicate results in ans list\n                int low=j+1, high=num.length-1;\n                while(low<high){\n                    int sum=num[i]+num[j]+num[low]+num[high];\n                    if(sum==target){\n                        ans.add(Arrays.asList(num[i], num[j], num[low], num[high]));\n                        while(low<high&&num[low]==num[low+1])low++; //skipping over duplicate on low\n                        while(low<high&&num[high]==num[high-1])high--; //skipping over duplicate on high\n                        low++; \n                        high--;\n                    }\n                    //move window\n                    else if(sum<target)low++; \n                    else high--;\n                }\n            }\n        }\n        return ans;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/4sum/discuss/8609/My-solution-generalized-for-kSums-in-JAVA\n     */\n    int len = 0;\n    public List<List<Integer>> fourSum3(int[] nums, int target) {\n        len = nums.length;\n        Arrays.sort(nums);\n        return kSum(nums, target, 4, 0);\n    }\n   private ArrayList<List<Integer>> kSum(int[] nums, int target, int k, int index) {\n        ArrayList<List<Integer>> res = new ArrayList<List<Integer>>();\n        if(index >= len) {\n            return res;\n        }\n        if(k == 2) {\n          int i = index, j = len - 1;\n          while(i < j) {\n                //find a pair\n              if(target - nums[i] == nums[j]) {\n                List<Integer> temp = new ArrayList<>();\n                  temp.add(nums[i]);\n                  temp.add(target-nums[i]);\n                    res.add(temp);\n                    //skip duplication\n                    while(i<j && nums[i]==nums[i+1]) i++;\n                    while(i<j && nums[j-1]==nums[j]) j--;\n                    i++;\n                    j--;\n                //move left bound\n              } else if (target - nums[i] > nums[j]) {\n                  i++;\n                //move right bound\n              } else {\n                  j--;\n              }\n          }\n        } else{\n            for (int i = index; i < len - k + 1; i++) {\n                //use current number to reduce ksum into k-1sum\n                ArrayList<List<Integer>> temp = kSum(nums, target - nums[i], k-1, i+1);\n                if(temp != null){\n                    //add previous results\n                    for (List<Integer> t : temp) {\n                        t.add(0, nums[i]);\n                    }\n                    res.addAll(temp);\n                }\n                while (i < len-1 && nums[i] == nums[i+1]) {\n                    //skip duplicated numbers\n                    i++;\n                }\n            }\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/FourSumII454.java",
    "content": "/**\n * Given four lists A, B, C, D of integer values, compute how many tuples\n * (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero.\n * \n * To make problem a bit easier, all A, B, C, D have same length of N where\n * 0 ≤ N ≤ 500. All integers are in the range of -228 to 228 - 1 and the result\n * is guaranteed to be at most 231 - 1.\n * \n * Example:\n * Input:\n * A = [ 1, 2]\n * B = [-2,-1]\n * C = [-1, 2]\n * D = [ 0, 2]\n *\n * Output: 2\n * \n * Explanation:\n * The two tuples are:\n * 1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0\n * 2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0\n */\n\npublic class FourSumII454 {\n    public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {\n        if (invalid(A) || invalid(B) || invalid(C) || invalid(D)) return 0;\n        int N = A.length;\n        HashMap<Integer, Integer> map = new HashMap<>();\n        for (int i=0; i<N; i++) {\n            int c = C[i];\n            for (int j=0; j<N; j++) {\n                int sum = c + D[j];\n                map.put(sum, map.getOrDefault(sum, 0) + 1);\n            }\n        }\n\n        int res = 0;\n        for (int i=0; i<N; i++) {\n            int a = A[i];\n            for (int j=0; j<N; j++) {\n                int counterPart = 0 - a - B[j];\n                res += map.getOrDefault(counterPart, 0);\n            }\n        }\n        return res;\n    }\n\n    private boolean invalid(int[] arr) {\n        return arr == null || arr.length == 0;\n    }\n\n\n    public int fourSumCount2(int[] A, int[] B, int[] C, int[] D) {\n        if (invalid(A) || invalid(B) || invalid(C) || invalid(D)) return 0;\n        Arrays.sort(A);\n        int N = A.length;\n        HashMap<Integer, Integer> map = new HashMap<>();\n        for (int i=0; i<N; i++) {\n            int c = C[i];\n            for (int j=0; j<N; j++) {\n                int sum = c + D[j];\n                map.put(sum, map.getOrDefault(sum, 0) + 1);\n            }\n        }\n\n        int res = 0;\n        int lastA = 0;\n        for (int i=0; i<N; i++) {\n            if (i != 0 && A[i] == A[i-1]) {\n                res += lastA;\n                continue;\n            }\n            int a = A[i];\n            int tmpRes = res;\n            for (int j=0; j<N; j++) {\n                int counterPart = 0 - a - B[j];\n                res += map.getOrDefault(counterPart, 0);\n            }\n            lastA = res - tmpRes;\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/FractionToRecurringDecimal166.java",
    "content": "/**\n * Given two integers representing the numerator and denominator of a fraction,\n * return the fraction in string format.\n *\n * If the fractional part is repeating, enclose the repeating part in parentheses.\n *\n * For example,\n *\n * Given numerator = 1, denominator = 2, return \"0.5\".\n * Given numerator = 2, denominator = 1, return \"2\".\n * Given numerator = 2, denominator = 3, return \"0.(6)\".\n *\n */\n\n\npublic class FractionToRecurringDecimal166 {\n    public String fractionToDecimal(int numerator, int denominator) {\n        boolean sameSign = (numerator >= 0 && denominator >= 0) || (numerator < 0 && denominator < 0);\n        long nume = Math.abs((long)numerator);\n        long deno = Math.abs((long)denominator);\n        Long ones = nume / deno;\n\n        List<Long> decimals = new ArrayList<>();\n        long left = nume % deno;\n        Map<Long, Integer> map = new HashMap<>();\n\n        left *= 10;\n        int pos = 0;\n        int repeat = -1;\n        while (true) {\n            if (left == 0) break;\n\n            if (map.containsKey(left)) {\n                repeat = map.get(left);\n                break;\n            }\n\n            long newOne = Math.abs(left / deno);\n            long newLeft = left % deno;\n            decimals.add(newOne);\n            map.put(left, pos);\n            left = newLeft*10;\n            pos++;\n        }\n\n        String pre = (sameSign || ones <= 0L) ? ones.toString() : (\"-\" + ones.toString());\n        if (decimals.size() == 0) return pre;\n\n\n        StringBuilder sb = new StringBuilder();\n        for (int i=0; i<decimals.size(); i++) {\n            String curr = decimals.get(i).toString();\n            String newD = (repeat != i) ? curr : (\"(\" + curr);\n            sb.append(newD);\n        }\n\n        if (repeat != -1) sb.append(\")\");\n\n        return String.format(\"%s.%s\", (sameSign) ? ones.toString() : (\"-\" + ones.toString()), sb);\n    }\n\n\n    public String fractionToDecimal2(int numerator, int denominator) {\n        if (numerator == 0) {\n            return \"0\";\n        }\n\n        StringBuilder fraction = new StringBuilder();\n        if (numerator < 0 ^ denominator < 0) {\n            fraction.append(\"-\");\n        }\n\n        long num = Math.abs(Long.valueOf(numerator));\n        long denom = Math.abs(Long.valueOf(denominator));\n\n        fraction.append(num / denom);\n        long remainder = num % denom;\n\n        if (remainder == 0) {\n            return fraction.toString();\n        }\n\n        fraction.append(\".\");\n        HashMap<Long, Integer> map = new HashMap<>();\n\n        while (remainder != 0) {\n            if (map.containsKey(remainder)) {\n                fraction.insert(map.get(remainder), \"(\");\n                fraction.append(\")\");\n                break;\n            }\n\n            map.put(remainder, fraction.length());\n            remainder *= 10;\n            fraction.append(remainder / denom);\n            remainder = remainder % denom;\n        }\n\n        return fraction.toString();\n    }\n\n\n}\n"
  },
  {
    "path": "src/FriendCircles547.java",
    "content": "/**\n * There are N students in a class. Some of them are friends, while some are not.\n * Their friendship is transitive in nature. For example, if A is a direct\n * friend of B, and B is a direct friend of C, then A is an indirect friend of C.\n * And we defined a friend circle is a group of students who are direct or\n * indirect friends.\n *\n * Given a N*N matrix M representing the friend relationship between students\n * in the class. If M[i][j] = 1, then the ith and jth students are direct friends\n * with each other, otherwise not. And you have to output the total number of\n * friend circles among all the students.\n *\n * Example 1:\n * Input:\n * [[1,1,0],\n *  [1,1,0],\n *  [0,0,1]]\n *\n * Output: 2\n * Explanation:The 0th and 1st students are direct friends, so they are in a\n * friend circle.\n * The 2nd student himself is in a friend circle. So return 2.\n * Example 2:\n * Input:\n * [[1,1,0],\n *  [1,1,1],\n *  [0,1,1]]\n *\n * Output: 1\n * Explanation:The 0th and 1st students are direct friends, the 1st and 2nd\n * students are direct friends, so the 0th and 2nd students are indirect\n * friends. All of them are in the same friend circle, so return 1.\n *\n * Note:\n *    N is in range [1,200].\n *    M[i][i] = 1 for all students.\n *    If M[i][j] = 1, then M[j][i] = 1.\n */\n\npublic class FriendCircles547 {\n    public int findCircleNum(int[][] M) {\n        boolean[] visited = new boolean[M.length];\n        int res = 0;\n        for (int i=0; i<M.length; i++) {\n            if (visited[i]) {\n                continue;\n            }\n            System.out.println(\"i: \" + i);\n            res++;\n            helper(M, visited, i);\n        }\n        return res;\n    }\n\n    private void helper(int[][] M, boolean[] visited, int i) {\n        if (i>=M.length) {\n            return;\n        }\n        visited[i] = true;\n        for (int j=0; j<M.length; j++) {\n            System.out.println(\"j: \" + j);\n            if (visited[j] || i == j || M[i][j] == 0) {\n                continue;\n            }\n            System.out.println(\"goto: \" + j);\n            helper(M, visited, j);\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/FrogJump403.java",
    "content": "/**\n * A frog is crossing a river. The river is divided into x units and at each\n * unit there may or may not exist a stone. The frog can jump on a stone, but\n * it must not jump into the water.\n * \n * Given a list of stones' positions (in units) in sorted ascending order,\n * determine if the frog is able to cross the river by landing on the last\n * stone. Initially, the frog is on the first stone and assume the first jump\n * must be 1 unit.\n * \n * If the frog's last jump was k units, then its next jump must be either\n * k - 1, k, or k + 1 units. Note that the frog can only jump in the forward\n * direction.\n * \n * Note:\n * The number of stones is ≥ 2 and is < 1,100.\n * Each stone's position will be a non-negative integer < 231.\n * The first stone's position is always 0.\n * \n * Example 1:\n * \n * [0,1,3,5,6,8,12,17]\n * \n * There are a total of 8 stones.\n * The first stone at the 0th unit, second stone at the 1st unit,\n * third stone at the 3rd unit, and so on...\n * The last stone at the 17th unit.\n * \n * Return true. The frog can jump to the last stone by jumping \n * 1 unit to the 2nd stone, then 2 units to the 3rd stone, then \n * 2 units to the 4th stone, then 3 units to the 6th stone, \n * 4 units to the 7th stone, and 5 units to the 8th stone.\n * \n * Example 2:\n * \n * [0,1,2,3,4,8,9,11]\n * \n * Return false. There is no way to jump to the last stone as \n * the gap between the 5th and 6th stone is too large.\n */\n\npublic class FrogJump403 {\n    public boolean canCross(int[] stones) {\n        Map<Integer, Set<Integer>> map = new HashMap<>();\n        for (int s: stones) {\n            map.put(s, new HashSet<>());\n        }\n        map.get(0).add(1);\n        int N = stones.length;\n        int last = stones[N-1];\n        for (int i=0; i<N; i++) {\n            int curr = stones[i];\n            Set<Integer> jumps = map.get(curr);\n            for (int j: jumps) {\n                int next = curr + j;\n                if (next == last) return true;\n                Set<Integer> after = map.get(next);\n                if (after != null) {\n                    if (j-1>0) after.add(j-1);\n                    after.add(j);\n                    after.add(j+1);\n                }\n            }\n        }\n        return !map.get(last).isEmpty();\n    }\n\n}\n"
  },
  {
    "path": "src/GameOfLife289.java",
    "content": "/**\n * According to the Wikipedia's article: \"The Game of Life, also known simply\n * as Life, is a cellular automaton devised by the British mathematician\n * John Horton Conway in 1970.\"\n * \n * Given a board with m by n cells, each cell has an initial state live (1) or\n * dead (0). Each cell interacts with its eight neighbors (horizontal, vertical,\n * diagonal) using the following four rules (taken from the above Wikipedia\n * article):\n * \n * Any live cell with fewer than two live neighbors dies, as if caused by under-population.\n * Any live cell with two or three live neighbors lives on to the next generation.\n * Any live cell with more than three live neighbors dies, as if by over-population..\n * Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.\n * \n * Write a function to compute the next state (after one update) of the board given its current state.\n * \n * Follow up: \n * Could you solve it in-place? Remember that the board needs to be updated at\n * the same time: You cannot update some cells first and then use their updated\n * values to update other cells.\n * \n * In this question, we represent the board using a 2D array. In principle, the\n * board is infinite, which would cause problems when the active area encroaches\n * the border of the array. How would you address these problems?\n */\n\n\npublic class GameOfLife289 {\n    public void gameOfLife(int[][] board) {\n        if (board == null || board.length == 0 || board[0].length == 0) return;\n        int n = board.length;\n        int m = board[0].length;\n        int[][] newBoard = new int[n][m];\n        \n        for (int i=0; i<n; i++) {\n            for (int j=0; j<m; j++) {\n                if (board[i][j] == 0) {\n                    newBoard[i][j] = countLive(board, i, j) == 3 ? 1 : 0;\n                } else {\n                    int lives = countLive(board, i, j);\n                    newBoard[i][j] = (lives == 2 || lives == 3) ? 1 : 0;\n                }\n            }\n        }\n        \n        for (int i=0; i<n; i++) {\n            for (int j=0; j<m; j++) {\n                board[i][j] = newBoard[i][j];\n            }\n        }\n    }\n\n    private int countLive(int[][] board, int x, int y) {\n        int n = board.length;\n        int m = board[0].length;\n        int res = 0;\n        for (int i=x-1; i<=x+1; i++) {\n            if (i < 0 || i >= n) continue;\n            for (int j=y-1; j<=y+1; j++) {\n                if (j < 0 || j >= m || (i == x && j == y)) continue;\n                if (board[i][j] == 1) res++;\n            }\n        }\n        return res;\n    }\n\n    /**\n     * https://leetcode.com/problems/game-of-life/discuss/73223/Easiest-JAVA-solution-with-explanation\n     */\n    public void gameOfLife2(int[][] board) {\n        if (board == null || board.length == 0) return;\n        int m = board.length, n = board[0].length;\n\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < n; j++) {\n                int lives = liveNeighbors(board, m, n, i, j);\n\n                // In the beginning, every 2nd bit is 0;\n                // So we only need to care about when will the 2nd bit become 1.\n                if (board[i][j] == 1 && lives >= 2 && lives <= 3) {  \n                    board[i][j] = 3; // Make the 2nd bit 1: 01 ---> 11\n                }\n                if (board[i][j] == 0 && lives == 3) {\n                    board[i][j] = 2; // Make the 2nd bit 1: 00 ---> 10\n                }\n            }\n        }\n\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < n; j++) {\n                board[i][j] >>= 1;  // Get the 2nd state.\n            }\n        }\n    }\n\n    public int liveNeighbors(int[][] board, int m, int n, int i, int j) {\n        int lives = 0;\n        for (int x = Math.max(i - 1, 0); x <= Math.min(i + 1, m - 1); x++) {\n            for (int y = Math.max(j - 1, 0); y <= Math.min(j + 1, n - 1); y++) {\n                lives += board[x][y] & 1;\n            }\n        }\n        lives -= board[i][j] & 1;\n        return lives;\n    }\n\n\n    public void gameOfLife3(int[][] board) {\n        int M = board.length;\n        int N = board[0].length;\n        for (int i=0; i<M; i++) {\n            for (int j=0; j<N; j++) {\n                update(board, i, j, M, N);\n            }\n        }\n        for (int i=0; i<M; i++) {\n            for (int j=0; j<N; j++) {\n                refresh(board, i, j);\n            }\n        }\n    }\n\n    private void update(int[][] board, int i, int j, int M, int N) {\n        int lives = 0;\n        for (int x=i-1; x<=i+1; x++) {\n            if (x < 0 || x >= M) continue;\n            for (int y=j-1; y<=j+1; y++) {\n                if (y < 0 || y >= N || (x == i && y == j)) continue;\n                if ((board[x][y] & 1) == 1) lives++;\n            }\n        }\n        boolean wasLive = (board[i][j] & 1) == 1;\n        if (wasLive) {\n            if (lives == 2 || lives == 3) {\n                board[i][j] |= 1 << 1;\n            }\n        } else {\n            if (lives == 3) {\n                board[i][j] |= 1 << 1;\n            }\n        }\n    }\n\n    private void refresh(int[][] board, int i, int j) {\n        board[i][j] = board[i][j] >> 1;\n    }\n\n}\n\n"
  },
  {
    "path": "src/GeneralizedAbbreviation320.java",
    "content": "/**\n * Write a function to generate the generalized abbreviations of a word. \n * \n * Note: The order of the output does not matter.\n * \n * Example:\n * Input: \"word\"\n * Output:\n * [\"word\", \"1ord\", \"w1rd\", \"wo1d\", \"wor1\", \"2rd\", \"w2d\", \"wo2\", \"1o1d\",\n * \"1or1\", \"w1r1\", \"1o2\", \"2r1\", \"3d\", \"w3\", \"4\"]\n */\n\npublic class GeneralizedAbbreviation320 {\n    public List<String> generateAbbreviations(String word) {\n        List<String> res = new ArrayList<>();\n        int N = word.length();\n        \n        backtrace(word.toCharArray(), res, true, 0, new StringBuilder());\n        \n        return res;\n    }\n\n    private void backtrace(char[] word, List<String> res, boolean prevIsWord, int i, StringBuilder sb) {\n        if (word.length == i) {\n            res.add(sb.toString());\n            return;\n        } \n\n        sb.append(word[i]);\n        backtrace(word, res, true, i+1, sb);\n        sb.deleteCharAt(sb.length() - 1);\n\n        if (prevIsWord) {\n            for (int j=i; j<word.length; j++) {\n                int num = j-i+1;\n                int len = sb.length();\n                sb.append(num);\n                backtrace(word, res, false, j+1, sb);\n                sb.setLength(len);\n            }\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/generalized-abbreviation/solution/\n     */\n    public List<String> generateAbbreviations2(String word) {\n        List<String> ans = new ArrayList<>();\n        for (int x = 0; x < (1 << word.length()); ++x) // loop through all possible x\n            ans.add(abbr(word, x));\n        return ans;\n    }\n\n    // build the abbreviation for word from number x\n    private String abbr(String word, int x) {\n        StringBuilder builder = new StringBuilder();\n        int k = 0, n = word.length(); // k is the count of consecutive ones in x\n        for (int i = 0; i < n; ++i, x >>= 1) {\n            if ((x & 1) == 0) { // bit is zero, we keep word.charAt(i)\n                if (k != 0) { // we have abbreviated k characters\n                    builder.append(k);\n                    k = 0; // reset the counter k\n                }\n                builder.append(word.charAt(i));\n            }\n            else // bit is one, increase k\n                ++k;\n        }\n        if (k != 0) builder.append(k); //don't forget to append the last k if non zero\n        return builder.toString();\n    }\n\n}\n"
  },
  {
    "path": "src/GenerateParentheses22.java",
    "content": "/**\n * Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.\n * For example, given n = 3, a solution set is:\n * [\n *   \"((()))\",\n *   \"(()())\",\n *   \"(())()\",\n *   \"()(())\",\n *   \"()()()\"\n * ]\n */\n\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n\npublic class GenerateParentheses22 {\n    public List<String> generateParenthesis(int n) {\n        if (n <= 0) {\n            return new ArrayList<String>();\n        } else if (n == 1) {\n            List<String> temp = new ArrayList<String>();\n            temp.add(\"()\");\n            return temp;\n        } else {\n            return addOnePair(generateParenthesis(n-1), n);\n        }\n\n    }\n\n    private List<String> addOnePair(List<String> source, Integer n) {\n        Set<String> returned = new HashSet<String>();\n        for (String prev: source) {\n            for (int i=0; i<n; i++) {\n                returned.add(prev.substring(0, n-1+i) + \"()\" + prev.substring(n-1+i, 2*n-2));\n            }\n        }\n        return new ArrayList(returned);\n    }\n\n\n    /** -------------------------------------------------------------------\n     * Top Solution:\n     * https://discuss.leetcode.com/topic/8724/easy-to-understand-java-backtracking-solution\n     * --------------------------------------------------------------------\n     */\n\n    public List<String> generateParenthesis2(int n) {\n        List<String> list = new ArrayList<String>();\n        backtrack(list, \"\", 0, 0, n);\n        return list;\n    }\n\n    private void backtrack(List<String> list, String str, int open, int close, int max){\n        if(str.length() == max*2){\n            list.add(str);\n            return;\n        }\n\n        if(open < max)\n            backtrack(list, str+\"(\", open+1, close, max);\n        if(close < open)\n            backtrack(list, str+\")\", open, close+1, max);\n    }\n\n    /** -------------------------------------------------------------------\n     * Top Solution (same idea above, but more efficient):\n     * https://discuss.leetcode.com/topic/8724/easy-to-understand-java-backtracking-solution\n     * --------------------------------------------------------------------\n     */\n\n    public List<String> generateParenthesis3(int n) {\n         List<String> res = new ArrayList<>();\n         helper(res, new StringBuilder(), 0, 0, n);\n         return res;\n    }\n\n    private void helper(List<String> res, StringBuilder sb, int open, int close, int n) {\n        if(open == n && close == n) {\n            res.add(sb.toString());\n            return;\n        }\n\n        if(open < n) {\n            sb.append(\"(\");\n            helper(res, sb, open+1, close, n);\n            sb.setLength(sb.length()-1);\n        }\n        if(close < open) {\n            sb.append(\")\");\n            helper(res, sb, open, close+1, n);\n            sb.setLength(sb.length()-1);\n        }\n    }\n\n\n    public static void main(String[] args) {\n        GenerateParentheses22 gp = new GenerateParentheses22();\n        System.out.println(gp.generateParenthesis(3));\n        System.out.println(gp.generateParenthesis2(3));\n        System.out.println(gp.generateParenthesis3(3));\n    }\n\n}\n"
  },
  {
    "path": "src/GraphValidTree261.java",
    "content": "/**\n * Given n nodes labeled from 0 to n-1 and a list of undirected edges (each\n * edge is a pair of nodes), write a function to check whether these edges make\n * up a valid tree.\n * \n * Example 1:\n * Input: n = 5, and edges = [[0,1], [0,2], [0,3], [1,4]]\n * Output: true\n * \n * Example 2:\n * Input: n = 5, and edges = [[0,1], [1,2], [2,3], [1,3], [1,4]]\n * Output: false\n * Note: you can assume that no duplicate edges will appear in edges. Since all\n * edges are undirected, [0,1] is the same as [1,0] and thus will not appear\n * together in edges.\n */\n\npublic class GraphValidTree261 {\n    // 1. construct Graph\n    // 2. detection cycle -- DFS\n    // 3. check not more than one tree\n    public boolean validTree(int n, int[][] edges) {\n        if (n == 0) return false;\n        if (n == 1) return true;\n        Map<Integer, Set<Integer>> graph = constructGraph(n, edges);\n        boolean[] visited = new boolean[n];\n        \n        // if cycle detected, return false\n        if (!isValid(graph, visited, 0, -1)) return false;\n        for (int i=0; i<n; i++) {\n            if (!visited[i]) return false;\n        }\n        return true;\n    }\n    \n    // return false if cycle detected\n    private boolean isValid(Map<Integer, Set<Integer>> graph, boolean[] visited, int curr, int parent) {\n        if (visited[curr]) {\n            return false;\n        }\n        \n        visited[curr] = true;\n        if (!graph.containsKey(curr)) return true;\n        for (int i: graph.get(curr)) {\n            if (i != parent && !isValid(graph, visited, i, curr)) return false;\n        }\n        return true;\n    }\n    \n    private Map<Integer, Set<Integer>> constructGraph(int n, int[][] edges) {\n        Map<Integer, Set<Integer>> graph = new HashMap<>();\n        for (int i=0; i<n; i++) {\n            graph.put(i, new HashSet<>());\n        }\n        for (int[] edge: edges) {\n            graph.get(edge[0]).add(edge[1]);\n            graph.get(edge[1]).add(edge[0]);\n        }\n        return graph;\n    }\n  \n    \n    public boolean validTree2(int n, int[][] edges) {\n        DisjointSet djs = new DisjointSet(n);\n        for (int[] edge: edges) {\n            int x = djs.find(edge[0]);\n            int y = djs.find(edge[1]);\n            if (x == y) return false;\n            djs.union(x, y);\n        }\n        int root = djs.find(0);\n        for (int i=1; i<n; i++) {\n            if (djs.find(i) != root) return false;\n        }\n        return true;\n    }\n\n    class DisjointSet {\n        int[] parent;\n        int[] rank;\n\n        public DisjointSet(int n) {\n            this.parent = new int[n];\n            for (int i=0; i<n; i++) this.parent[i] = i;\n            this.rank = new int[n];\n        }\n\n        public int find(int x) {\n            if (parent[x] != x) {\n                parent[x] = find(parent[x]);\n            }\n            return parent[x];\n        }\n\n        public void union(int x, int y) {\n            int xx = find(x);\n            int yy = find(y);\n            if (rank[xx] > rank[yy]) {\n                parent[yy] = xx;\n            } else if (rank[xx] < rank[yy]) {\n                parent[xx] = yy;\n            } else {\n                parent[xx] = yy;\n                rank[yy]++;\n            }\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/graph-valid-tree/discuss/69018/AC-Java-Union-Find-solution\n     */\n    public boolean validTree3(int n, int[][] edges) {\n        // initialize n isolated islands\n        int[] nums = new int[n];\n        Arrays.fill(nums, -1);\n        \n        // perform union find\n        for (int i = 0; i < edges.length; i++) {\n            int x = find(nums, edges[i][0]);\n            int y = find(nums, edges[i][1]);\n            \n            // if two vertices happen to be in the same set\n            // then there's a cycle\n            if (x == y) return false;\n            \n            // union\n            nums[x] = y;\n        }\n        \n        return edges.length == n - 1;\n    }\n    \n    int find(int nums[], int i) {\n        if (nums[i] == -1) return i;\n        return find(nums, nums[i]);\n    }\n\n}\n"
  },
  {
    "path": "src/GroupAnagrams49.java",
    "content": "/**\n * Given an array of strings, group anagrams together.\n *\n * For example, given: [\"eat\", \"tea\", \"tan\", \"ate\", \"nat\", \"bat\"],\n * Return:\n * [\n *   [\"ate\", \"eat\",\"tea\"],\n *   [\"nat\",\"tan\"],\n *   [\"bat\"]\n * ]\n *\n * Note: All inputs will be in lower-case.\n */\n\npublic class GroupAnagrams49 {\n    public List<List<String>> groupAnagrams(String[] strs) {\n        Map<String, List<String>> map = new HashMap<>();\n\n        for (String s: strs) {\n            String mapKey = getSortedString(s);\n            List<String> newList = (List<String>) map.getOrDefault(mapKey, new ArrayList<String>());\n            newList.add(s);\n            map.put(mapKey, newList);\n        }\n\n        return new ArrayList<List<String>>(map.values());\n    }\n\n    private String getSortedString(String s) {\n        char[] chars = s.toCharArray();\n        Arrays.sort(chars);\n        return String.valueOf(chars);\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/45639/java-beat-100-use-prime-number\n     */\n    public static List<List<String>> groupAnagrams2(String[] strs) {\n        int[] prime = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103}; //最多10609个z\n\n        List<List<String>> res = new ArrayList<>();\n        HashMap<Integer, Integer> map = new HashMap<>();\n        for (String s : strs) {\n            int key = 1;\n            for (char c : s.toCharArray()) {\n                key *= prime[c - 'a'];\n            }\n            List<String> t;\n            if (map.containsKey(key)) {\n                t = res.get(map.get(key));\n            } else {\n                t = new ArrayList<>();\n                res.add(t);\n                map.put(key, res.size() - 1);\n            }\n            t.add(s);\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/GroupShiftedStrings249.java",
    "content": "/**\n * Given a string, we can \"shift\" each of its letter to its successive letter,\n * for example: \"abc\" -> \"bcd\". We can keep \"shifting\" which forms the sequence:\n * \n * \"abc\" -> \"bcd\" -> ... -> \"xyz\"\n * Given a list of strings which contains only lowercase alphabets, group all\n * strings that belong to the same shifting sequence.\n * \n * Example:\n * \n * Input: [\"abc\", \"bcd\", \"acef\", \"xyz\", \"az\", \"ba\", \"a\", \"z\"],\n * Output: \n * [\n *   [\"abc\",\"bcd\",\"xyz\"],\n *   [\"az\",\"ba\"],\n *   [\"acef\"],\n *   [\"a\",\"z\"]\n * ]\n */\n\npublic class GroupShiftedStrings249 {\n    public List<List<String>> groupStrings(String[] strings) {\n        Map<String, List<String>> map = new HashMap<>();\n        for (String s: strings) {\n            boolean found = false;\n            for (String k: map.keySet()) {\n                if (s.length() != k.length()) continue;\n                boolean b = true;\n                int diff = getDiff(s.charAt(0), k.charAt(0));\n                for (int i=1; i<s.length(); i++) {\n                    b = getDiff(s.charAt(i), k.charAt(i)) == diff;\n                    if (!b) break;\n                }\n                if (b) {\n                    map.get(k).add(s);\n                    found = true;\n                    break;\n                }\n            }\n            if (!found) {\n                List<String> tmp = new ArrayList<>();\n                tmp.add(s);\n                map.put(s, tmp);\n            }\n        }\n\n        return new ArrayList<List<String>>(map.values());\n    }\n\n    private int getDiff(char c1, char c2) {\n        int init = c1 - c2;\n        while (init < 0) {\n            init += 26;\n        }\n        return init;\n    }\n\n    /**\n     * https://leetcode.com/problems/group-shifted-strings/discuss/127090/Short-Java-solution\n     */\n    public List<List<String>> groupStrings2(String[] strings) {\n        Map<String, List<String>> groups = new HashMap<String, List<String>>();\n        for (String s : strings) {\n            int shift = 'z' - s.charAt(0);\n            StringBuilder sb = new StringBuilder();\n            for (int i = 0; i < s.length(); i++) {\n                sb.append((s.charAt(i) + shift) % 26);\n            }\n            if (!groups.containsKey(sb.toString())) {\n                groups.put(sb.toString(), new ArrayList<String>());\n            }\n            groups.get(sb.toString()).add(s);\n        }\n        return new ArrayList<List<String>>(groups.values());\n    }\n\n}"
  },
  {
    "path": "src/GuessNumberHigherOrLowerII375.java",
    "content": "/**\n * We are playing the Guess Game. The game is as follows:\n * \n * I pick a number from 1 to n. You have to guess which number I picked.\n * \n * Every time you guess wrong, I'll tell you whether the number I picked is\n * higher or lower.\n * \n * However, when you guess a particular number x, and you guess wrong, you\n * pay $x. You win the game when you guess the number I picked.\n * \n * Example:\n * n = 10, I pick 8.\n * First round:  You guess 5, I tell you that it's higher. You pay $5.\n * Second round: You guess 7, I tell you that it's higher. You pay $7.\n * Third round:  You guess 9, I tell you that it's lower. You pay $9.\n * \n * Game over. 8 is the number I picked.\n * You end up paying $5 + $7 + $9 = $21.\n * \n * Given a particular n ≥ 1, find out how much money you need to have to\n * guarantee a win.\n */\n\npublic class GuessNumberHigherOrLowerII375 {\n    // // LTE\n    // public int getMoneyAmount(int n) {\n    //     return getMoneyAmount(1, n);\n    // }\n\n    // public int getMoneyAmount(int l, int r) {\n    //     if (l >= r) return 0;\n    //     if (l + 1 == r) return l;\n    //     if (l + 2 == r) return l + 1;\n\n    //     int res = Integer.MAX_VALUE;\n    //     for (int i=l; i<=r; i++) {\n    //         int left = getMoneyAmount(l, i-1);\n    //         int right = getMoneyAmount(i+1, r);\n    //         res = Math.min(res, Math.max(left, right) + i);\n    //     }\n    //     return res;\n    // }\n\n\n    public int getMoneyAmount(int n) {\n        return getMoneyAmount(1, n, new int[n][n]);\n    }\n\n    public int getMoneyAmount(int l, int r, int[][] memo) {\n        if (l >= r) return 0;\n        if (memo[l-1][r-1] != 0) return memo[l-1][r-1];\n        int res = Integer.MAX_VALUE;\n        for (int i=l; i<=r; i++) {\n            int left = getMoneyAmount(l, i-1, memo);\n            int right = getMoneyAmount(i+1, r, memo);\n            res = Math.min(res, Math.max(left, right) + i);\n        }\n        memo[l-1][r-1] = res;\n        return res;\n    }\n\n\n    public int getMoneyAmount2(int n) {\n        int[][] dp = new int[n+1][n+1];\n        for (int l=1; l<=n; l++) {\n            for (int i=1; i<=n-l; i++) {\n                int j = i+l;\n                int tmp = Integer.MAX_VALUE;\n                for (int k=i; k<=j; k++) {\n                    int left = i <= k-1 ? dp[i][k-1] : 0;\n                    int right = k+1 <= j ? dp[k+1][j] : 0;\n                    tmp = Math.min(tmp, Math.max(left, right) + k);\n                }\n                dp[i][j] = tmp;\n            }\n        }\n        return dp[1][n];\n    }\n\n\n    public int getMoneyAmount3(int n) {\n        int[][] dp = new int[n+1][n+1];\n        for (int l=1; l<=n; l++) {\n            for (int i=1; i<=n-l; i++) {\n                int j = i+l;\n                int tmp = Integer.MAX_VALUE;\n                for (int k=i+(l-1)/2; k<=j; k++) {\n                    int left = i <= k-1 ? dp[i][k-1] : 0;\n                    int right = k+1 <= j ? dp[k+1][j] : 0;\n                    tmp = Math.min(tmp, Math.max(left, right) + k);\n                }\n                dp[i][j] = tmp;\n            }\n        }\n        return dp[1][n];\n    }\n\n}\n"
  },
  {
    "path": "src/GuessTheWord843.java",
    "content": "/**\n * This problem is an interactive problem new to the LeetCode platform.\n * \n * We are given a word list of unique words, each word is 6 letters long, and\n * one word in this list is chosen as secret.\n * \n * You may call master.guess(word) to guess a word.  The guessed word should\n * have type string and must be from the original list with 6 lowercase letters.\n * \n * This function returns an integer type, representing the number of exact\n * matches (value and position) of your guess to the secret word.  Also, if\n * your guess is not in the given wordlist, it will return -1 instead.\n * \n * For each test case, you have 10 guesses to guess the word. At the end of\n * any number of calls, if you have made 10 or less calls to master.guess and\n * at least one of these guesses was the secret, you pass the testcase.\n * \n * Besides the example test case below, there will be 5 additional test cases,\n * each with 100 words in the word list.  The letters of each word in those\n * testcases were chosen independently at random from 'a' to 'z', such that\n * every word in the given word lists is unique.\n * \n * Example 1:\n * Input: secret = \"acckzz\", wordlist = [\"acckzz\",\"ccbazz\",\"eiowzz\",\"abcczz\"]\n * \n * Explanation:\n * master.guess(\"aaaaaa\") returns -1, because \"aaaaaa\" is not in wordlist.\n * master.guess(\"acckzz\") returns 6, because \"acckzz\" is secret and has all 6 matches.\n * master.guess(\"ccbazz\") returns 3, because \"ccbazz\" has 3 matches.\n * master.guess(\"eiowzz\") returns 2, because \"eiowzz\" has 2 matches.\n * master.guess(\"abcczz\") returns 4, because \"abcczz\" has 4 matches.\n * \n * We made 5 calls to master.guess and one of them was the secret, so we pass\n * the test case.\n * Note:  Any solutions that attempt to circumvent the judge will result in\n * disqualification.\n */\n\n/**\n * // This is the Master's API interface.\n * // You should not implement it, or speculate about its implementation\n * interface Master {\n *     public int guess(String word) {}\n * }\n */\n\npublic class GuessTheWord843 {\n    /**\n     * https://leetcode.com/problems/guess-the-word/discuss/133862/Random-Guess-and-Minimax-Guess-with-Comparison\n     */\n    public void findSecretWord(String[] wordlist, Master master) {\n        for (int i = 0, x = 0; i < 10 && x < 6; ++i) {\n            String guess = wordlist[new Random().nextInt(wordlist.length)];\n            x = master.guess(guess);\n            List<String> wordlist2 = new ArrayList<>();\n            for (String w : wordlist) if (match(guess, w) == x) wordlist2.add(w);\n            wordlist = wordlist2.toArray(new String[wordlist2.size()]);\n        }\n    }\n\n    public int match(String a, String b) {\n        int matches = 0;\n        for (int i = 0; i < a.length(); ++i) if (a.charAt(i) == b.charAt(i)) matches ++;\n        return matches;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/guess-the-word/discuss/133862/Random-Guess-and-Minimax-Guess-with-Comparison\n     */\n    public void findSecretWord2(String[] wordlist, Master master) {\n        for (int i = 0, x = 0; i < 10 && x < 6; ++i) {\n            HashMap<String, Integer> count = new HashMap<>();\n            for (String w1 : wordlist) for (String w2 : wordlist) if (match(w1, w2) == 0) count.put(w1, count.getOrDefault(w1 , 0) + 1);\n            Pair minimax = new Pair(\"\", 1000);\n            for (String w : wordlist) if (count.getOrDefault(w, 0) < minimax.i) minimax = new Pair(w, count.getOrDefault(w, 0));\n            x = master.guess(minimax.s);\n            List<String> wordlist2 = new ArrayList<String>();\n            for (String w : wordlist) if (match(minimax.s, w) == x) wordlist2.add(w);\n            wordlist = wordlist2.toArray(new String[0]);\n        }\n    }\n\n    class Pair {\n        String s;\n        Integer i;\n        Pair (String s, Integer i) {\n            this.s = s;\n            this.i = i;\n        } \n    }\n\n}\n"
  },
  {
    "path": "src/HIndex274.java",
    "content": "/**\n * Given an array of citations (each citation is a non-negative integer) of a\n * researcher, write a function to compute the researcher's h-index.\n *\n * According to the definition of h-index on Wikipedia: \"A scientist has\n * index h if h of his/her N papers have at least h citations each, and the\n * other N − h papers have no more than h citations each.\"\n *\n * For example, given citations = [3, 0, 6, 1, 5], which means the researcher\n * has 5 papers in total and each of them had received 3, 0, 6, 1, 5 citations\n * respectively. Since the researcher has 3 papers with at least 3 citations\n * each and the remaining two with no more than 3 citations each, his h-index is 3.\n *\n * Note: If there are several possible values for h, the maximum one is taken\n * as the h-index.\n */\n\n\npublic class HIndex274 {\n    public int hIndex(int[] citations) {\n        int hIndex = 0;\n        int L = citations.length;\n        for (int i=0; i<L; i++) {\n            int now = citations[i];\n            int high = 0;\n            int same = 0;\n            for (int j=0; j<L; j++) {\n                high += (citations[j] > now) ? 1:0;\n                same += (citations[j] == now) ? 1:0;\n            }\n            for (int h = high+same; h >= high; h--) {\n                if (now >= h) {\n                    hIndex = Math.max(hIndex, h);\n                    break;\n                }\n            }\n        }\n\n        return hIndex;\n    }\n\n    public int hIndex2(int[] citations) {\n        int L = citations.length;\n        for (int i=L; i>=0; i--) {\n            int high = 0;\n            int low = 0;\n            for (int j=0; j<L && low<=(L-i); j++) {\n                high += (citations[j] > i) ? 1:0;\n                low += (citations[j] < i) ? 1:0;\n            }\n\n            if (i >= high && i <= L-low) return i;\n        }\n\n        return 0;\n    }\n\n\n    public int hIndex3(int[] citations) {\n        final int L = citations.length;\n        List<Integer> less = new ArrayList<>();\n\n        int i = L;\n        int more = 0;\n        for (int j=0; j<L; j++) {\n            int now = citations[j];\n            if (now < i) {\n                less.add(now);\n            } else if (now > i) {\n                more++;\n            }\n        }\n        if (i >= more && i <= L-less.size()) return L;\n\n        for (i=L-1; i>=0; i--) {\n            int S = less.size();\n            more = L-S;\n            List<Integer> newLess = new ArrayList<>();\n            for (int j=0; j<S; j++) {\n                int now = less.get(j);\n                if (now < i) {\n                    newLess.add(now);\n                } else if (now > i) {\n                    more++;\n                }\n            }\n\n            less = newLess;\n            if (i >= more && i <= L-less.size()) return i;\n        }\n\n        return 0;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/23307/my-o-n-time-solution-use-java\n     */\n    public int hIndex4(int[] citations) {\n        int length = citations.length;\n        if (length == 0) {\n        \treturn 0;\n        }\n\n        int[] array2 = new int[length + 1];\n        for (int i = 0; i < length; i++) {\n        \tif (citations[i] > length) {\n        \t\tarray2[length] += 1;\n        \t} else {\n        \t\tarray2[citations[i]] += 1;\n        \t}\n        }\n        int t = 0;\n        int result = 0;\n\n        for (int i = length; i >= 0; i--) {\n        \tt = t + array2[i];\n        \tif (t >= i) {\n        \t\treturn i;\n        \t}\n        }\n        return 0;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/23310/my-easy-solution\n     */\n    public int hIndex5(int[] citations) {\n        Arrays.sort(citations);\n        int len=citations.length;\n        for(int i=0;i<len;i++){\n            if(citations[i]>=len-i) return len-i;\n        }\n        return 0;\n    }\n\n    /**\n     * https://leetcode.com/problems/h-index/solution/\n     */\n    public int hIndex6(int[] citations) {\n        int n = citations.length;\n        int[] papers = new int[n + 1];\n        // counting papers for each citation number\n        for (int c: citations)\n            papers[Math.min(n, c)]++;\n        // finding the h-index\n        int k = n;\n        for (int s = papers[n]; k > s; s += papers[k])\n            k--;\n        return k;\n    }\n\n    public int hIndex7(int[] citations) {\n        if (citations == null || citations.length == 0) return 0;\n        Arrays.sort(citations);\n        \n        if (citations[citations.length-1] == 0) return 0;\n        int i = 1;\n        while (i < citations.length) {\n            if (citations[citations.length-i] >= i && citations[citations.length-i-1] <= i) {\n                return i;\n            }\n            i++;\n        }\n        \n        return citations.length;\n    }\n\n}\n"
  },
  {
    "path": "src/HandOfStraights846.java",
    "content": "/**\n * Alice has a hand of cards, given as an array of integers.\n * \n * Now she wants to rearrange the cards into groups so that each group is\n * size W, and consists of W consecutive cards.\n * \n * Return true if and only if she can.\n * \n * Example 1:\n * Input: hand = [1,2,3,6,2,3,4,7,8], W = 3\n * Output: true\n * Explanation: Alice's hand can be rearranged as [1,2,3],[2,3,4],[6,7,8].\n * \n * Example 2:\n * Input: hand = [1,2,3,4,5], W = 4\n * Output: false\n * Explanation: Alice's hand can't be rearranged into groups of 4.\n * \n * Note:\n * 1 <= hand.length <= 10000\n * 0 <= hand[i] <= 10^9\n * 1 <= W <= hand.length\n */\n\npublic class HandOfStraights846 {\n    public boolean isNStraightHand(int[] hand, int W) {\n        if (hand == null) return false;\n        if (hand.length == 0 && W == 0) return true;\n        if (hand.length == 0 || W == 0 || hand.length % W != 0) return false; \n        \n        PriorityQueue<Integer> pq = new PriorityQueue<>();\n        for (int card: hand) {\n            pq.add(card);\n        }\n    \n        while (!pq.isEmpty()) {\n            int first = pq.peek();\n            for (int i = 0; i<W; i++) {\n                if (!pq.remove(first + i)) {\n                    return false;\n                }\n            }\n        }\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/hand-of-straights/solution/\n     */\n    public boolean isNStraightHand2(int[] hand, int W) {\n        TreeMap<Integer, Integer> count = new TreeMap();\n        for (int card: hand) {\n            if (!count.containsKey(card))\n                count.put(card, 1);\n            else\n                count.replace(card, count.get(card) + 1);\n        }\n\n        while (count.size() > 0) {\n            int first = count.firstKey();\n            for (int card = first; card < first + W; ++card) {\n                if (!count.containsKey(card)) return false;\n                int c = count.get(card);\n                if (c == 1) count.remove(card);\n                else count.replace(card, c - 1);\n            }\n        }\n\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/hand-of-straights/discuss/153519/copy-from-the-quickest-java-solutions-with-explanation(10-ms-Beats-100)\n     */\n    public boolean isNStraightHand3(int[] hands, int W) {\n        if (W == 1) return true;\n        if (hands.length % W != 0) return false;\n\n        int H = hands.length / W;\n        int[][] buckets = new int[W][H];\n        int[] bucketSize = new int[W];\n\n        for (int h : hands) {\n            int indexInBucket = h % W, bucketId = bucketSize[indexInBucket]++;\n            if (bucketId >= H) return false;\n            buckets[indexInBucket][bucketId] = h;\n        }\n        \n        for (int i = 0; i < W; i++) Arrays.sort(buckets[i]);\n        \n        for (int i = 0; i < H; i++)\n            for (int j = 1; j < W; j++)\n                //consider case 3,1,2 and 3,4,2\n                if (buckets[j][i] != buckets[j - 1][i] + 1 && buckets[j - 1][i] - buckets[j][i] != W - 1) return false;\n\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "src/HappyNumber202.java",
    "content": "/**\n * Write an algorithm to determine if a number is \"happy\".\n * \n * A happy number is a number defined by the following process: Starting with\n * any positive integer, replace the number by the sum of the squares of its\n * digits, and repeat the process until the number equals 1 (where it will\n * stay), or it loops endlessly in a cycle which does not include 1. Those\n * numbers for which this process ends in 1 are happy numbers.\n * \n * Example: \n * \n * Input: 19\n * Output: true\n * Explanation: \n * 12 + 92 = 82\n * 82 + 22 = 68\n * 62 + 82 = 100\n * 12 + 02 + 02 = 1\n */\n\npublic class HappyNumber202 {\n    public boolean isHappy(int n) {\n        if (n <= 0) return false;\n        Set<Integer> set = new HashSet<>();\n        set.add(n);\n        while (true) {\n            int next = next(n);\n            if (next == 1) return true;\n            if (set.contains(next)) return false;\n            set.add(n);\n            n = next;\n        }\n    }\n\n    private int next(int n) {\n        int res = 0;\n        while (n != 0) {\n            int t = n % 10;\n            res += t * t;\n            n /= 10;\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/happy-number/discuss/56917/My-solution-in-C(-O(1)-space-and-no-magic-math-property-involved-)\n     */\n    public boolean isHappy2(int n) {\n        int slow, fast;\n        slow = fast = n;\n        do {\n            slow = digitSquareSum(slow);\n            fast = digitSquareSum(fast);\n            fast = digitSquareSum(fast);\n        } while(slow != fast);\n        if (slow == 1) return true;\n        else return false;\n    }\n\n    private int digitSquareSum(int n) {\n        int sum = 0, tmp;\n        while (n != 0) {\n            tmp = n % 10;\n            sum += tmp * tmp;\n            n /= 10;\n        }\n        return sum;\n    }\n\n}\n"
  },
  {
    "path": "src/HighestPopulationYear.java",
    "content": "/**\n * Given a list of people with their birth and death years, find the year with the highest population.\n */\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class HighestPopulationYear {\n\n    // brute force\n    public static int find(int[][] people) {\n        int minB = Integer.MAX_VALUE;\n        int maxD = Integer.MIN_VALUE;\n        for (int[] bd: people) {\n            if (bd[0] < minB) minB = bd[0];\n            if (bd[1] > maxD) maxD = bd[1];\n        }\n\n        int highest = -1;\n        int year = -1;\n        for (int i = minB; i <= maxD; i++) {\n            int c = 0;\n            for (int[] bd: people) {\n                if (bd[0] <= i && bd[1] >= i) c++;\n            }\n            if (c > highest) {\n              highest = c;\n              year = i;\n            }\n        }\n\n        return year;\n    }\n\n\n    public static int find2(int[][] people) {\n        Map<Integer, Integer> map = new HashMap<>();\n\n        int max = Integer.MIN_VALUE;\n        int year = -1;\n        for (int[] p: people) {\n            if (map.containsKey(p[0])) {\n                continue;\n            } else {\n                int c = 0;\n                for (int[] q: people) {\n                    if (q[0] <= p[0] && q[1] >= p[0]) c++;\n                }\n                map.put(p[0], c);\n                if (c > max) {\n                    max = c;\n                    year = p[0];\n                }\n            }\n        }\n\n        return year;\n    }\n\n\n    public static int find3(int[][] people) {\n        int minB = Integer.MAX_VALUE;\n        int maxB = Integer.MIN_VALUE;\n        for (int[] p: people) {\n            if (p[0] < minB) minB = p[0];\n            if (p[0] > maxB) maxB = p[0];\n        }\n\n        int[] arr = new int[maxB - minB + 1];\n        for (int[] p: people) {\n            arr[p[0]-minB] += 1;\n            if (p[1] <= maxB) {\n                arr[p[1]-minB] -= 1;\n            }\n        }\n\n        int year = -1;\n        int max = Integer.MIN_VALUE;\n        for (int i = 0; i < maxB - minB; i++) {\n            if (arr[i] > max) {\n                max = arr[i];\n                year = i + minB;\n            }\n        }\n\n        return year;\n    }\n\n\n    public static void main(String[] args) {\n      // Arrays.sort(people, (p1, p2) -> Integer.compare(p1[0], p2[0]));\n        int[][] people = {\n            {2000, 2010},\n            {1975, 2005},\n            {1975, 2003},\n            {1803, 1809},\n            {1750, 1869},\n            {1890, 1935},\n            {1803, 1921},\n            {1894, 1921}\n        };\n\n        System.out.println(HighestPopulationYear.find(people));\n        System.out.println(HighestPopulationYear.find2(people));\n        System.out.println(HighestPopulationYear.find3(people));\n    }\n\n\n}"
  },
  {
    "path": "src/HouseRobber198.java",
    "content": "/**\n * You are a professional robber planning to rob houses along a street. Each\n * house has a certain amount of money stashed, the only constraint stopping\n * you from robbing each of them is that adjacent houses have security system\n * connected and it will automatically contact the police if two adjacent houses\n * were broken into on the same night.\n *\n * Given a list of non-negative integers representing the amount of money of\n * each house, determine the maximum amount of money you can rob tonight without\n * alerting the police.\n *\n */\n\npublic class HouseRobber198 {\n    public int rob(int[] nums) {\n        if (nums.length == 0) {\n            return 0;\n        }\n\n        if (nums.length == 1) {\n            return nums[0];\n        }\n\n        int[] dp = new int[nums.length+1];\n        dp[0] = 0;\n        dp[1] = nums[0];\n\n        for (int i=1; i<nums.length; i++) {\n            dp[i+1] = Math.max(dp[i], dp[i-1]+nums[i]);\n        }\n\n        return dp[nums.length];\n    }\n\n\n    public int rob2(int[] nums) {\n        int pre = 0;\n        int now = 0;\n        for (int i=0; i<nums.length; i++) {\n            int n = Math.max(now, pre+nums[i]);\n            pre = now;\n            now = n;\n        }\n\n        return now;\n    }\n\n}\n"
  },
  {
    "path": "src/HouseRobberII213.java",
    "content": "/**\n * Note: This is an extension of House Robber.\n *\n * After robbing those houses on that street, the thief has found himself a\n * new place for his thievery so that he will not get too much attention. This\n * time, all houses at this place are arranged in a circle. That means the\n * first house is the neighbor of the last one. Meanwhile, the security system\n * for these houses remain the same as for those in the previous street.\n *\n * Given a list of non-negative integers representing the amount of money of\n * each house, determine the maximum amount of money you can rob tonight\n * without alerting the police.\n */\n\n\npublic class HouseRobberII213 {\n    public int rob(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        if (nums.length == 1) return nums[0];\n        int pre0 = 0;\n        int now0 = 0;\n        int pre1 = 0;\n        int now1 = 0;\n        for (int i=1; i<nums.length; i++) {\n            int n0 = Math.max(now0, pre0+nums[i-1]);\n            pre0 = now0;\n            now0 = n0;\n            int n1 = Math.max(now1, pre1+nums[i]);\n            pre1 = now1;\n            now1 = n1;\n        }\n        return Math.max(now0, now1);\n    }\n\n    /**\n     * https://leetcode.com/problems/house-robber-ii/discuss/59934/Simple-AC-solution-in-Java-in-O(n)-with-explanation\n     */\n    public int rob2(int[] nums) {\n        if (nums.length == 1) return nums[0];\n        return Math.max(rob(nums, 0, nums.length - 2), rob(nums, 1, nums.length - 1));\n    }\n\n    private int rob(int[] num, int lo, int hi) {\n        int include = 0, exclude = 0;\n        for (int j = lo; j <= hi; j++) {\n            int i = include, e = exclude;\n            include = e + num[j];\n            exclude = Math.max(e, i);\n        }\n        return Math.max(include, exclude);\n    }\n\n\n    public int rob3(int[] nums) {\n        int N = nums.length;\n        if (N == 0) return 0;\n        if (N == 1) return nums[0];\n        return Math.max(rob3(nums, 0, N-2), rob3(nums, 1, N-1));\n    }\n\n    public int rob3(int[] nums, int i, int j) {\n        if (i == j) return nums[i];\n        int K = j - i + 1;\n        int pre0 = 0;\n        int pre1 = nums[i];\n        for (int k=2; k<=K; k++) {\n            int curr = Math.max(pre1, pre0 + nums[i+k-1]);\n            pre0 = pre1;\n            pre1 = curr;\n        }\n        return pre1;\n    }\n\n}\n"
  },
  {
    "path": "src/HouseRobberIII337.java",
    "content": "/**\n * The thief has found himself a new place for his thievery again. There is only\n * one entrance to this area, called the \"root.\" Besides the root, each house\n * has one and only one parent house. After a tour, the smart thief realized\n * that \"all houses in this place forms a binary tree\". It will automatically\n * contact the police if two directly-linked houses were broken into on the\n * same night.\n *\n * Determine the maximum amount of money the thief can rob tonight without alerting the police.\n *\n * Example 1:\n *\n *      3\n *     / \\\n *    2   3\n *     \\   \\\n *      3   1\n *\n * Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.\n *\n * Example 2:\n *\n *      3\n *     / \\\n *    4   5\n *   / \\   \\\n *  1   3   1\n *\n * Maximum amount of money the thief can rob = 4 + 5 = 9.\n *\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class HouseRobberIII337 {\n    public int rob(TreeNode root) {\n        return helper(root).last;\n    }\n\n    private DP helper(TreeNode root) {\n        if (root == null) {\n            return new DP(0, 0);\n        }\n        if (root.left == null && root.right == null) {\n            return new DP(root.val, 0);\n        }\n\n        DP leftDP = helper(root.left);\n        DP rightDP = helper(root.right);\n\n        return new DP(\n            Math.max(root.val+leftDP.prev+rightDP.prev, leftDP.last+rightDP.last),\n            leftDP.last+rightDP.last\n        );\n    }\n\n    class DP {\n        Integer last;\n        Integer prev;\n        DP(Integer last, Integer prev) {\n            this.last = last;\n            this.prev = prev;\n        }\n    }\n\n\n    public int rob2(TreeNode root) {\n        int[] res = helper2(root);\n        return res[1];\n    }\n\n    public int[] helper2(TreeNode root) {\n        if (root == null) return new int[]{0, 0};\n        int[] left = helper(root.left);\n        int[] right = helper(root.right);\n        return new int[]{left[1] + right[1], Math.max(left[0] + right[0] + root.val, left[1] + right[1])};\n    }\n\n}\n"
  },
  {
    "path": "src/ImageSmoother661.java",
    "content": "/**\n * Given a 2D integer matrix M representing the gray scale of an image, you\n * need to design a smoother to make the gray scale of each cell becomes the\n * average gray scale (rounding down) of all the 8 surrounding cells and itself.\n * If a cell has less than 8 surrounding cells, then use as many as you can.\n * \n * Example 1:\n * \n * Input:\n * [[1,1,1],\n *  [1,0,1],\n *  [1,1,1]]\n * \n * Output:\n * [[0, 0, 0],\n *  [0, 0, 0],\n *  [0, 0, 0]]\n * \n * Explanation:\n * For the point (0,0), (0,2), (2,0), (2,2): floor(3/4) = floor(0.75) = 0\n * For the point (0,1), (1,0), (1,2), (2,1): floor(5/6) = floor(0.83333333) = 0\n * For the point (1,1): floor(8/9) = floor(0.88888889) = 0\n * \n * Note:\n * The value in the given matrix is in the range of [0, 255].\n * The length and width of the given matrix are in the range of [1, 150].\n */\n\npublic class ImageSmoother661 {\n    private int[][] dirs = new int[][]{{0,0}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1}, {-1,0}, {-1,-1}, {-1,1}};\n    public int[][] imageSmoother(int[][] M) {\n        int lenI = M.length;\n        int lenJ = M[0].length;\n        int[][] newScale = new int[lenI][lenJ];\n        \n        for (int i=0; i<lenI; i++) {\n            for (int j=0; j<lenJ; j++) {\n                int sum = 0;\n                int count = 0;\n                for (int[] dir: dirs) {\n                    int ii = i+dir[0];\n                    int jj = j+dir[1];\n                    if (ii >= 0 && jj >= 0 && ii < lenI && jj < lenJ) {\n                        sum += M[ii][jj];\n                        count++;\n                    }\n                }\n                newScale[i][j] = sum / count;\n            }\n        }\n        return newScale;\n    }\n}\n"
  },
  {
    "path": "src/ImplementMagicDictionary676.java",
    "content": "/**\n * Implement a magic directory with buildDict, and search methods.\n * \n * For the method buildDict, you'll be given a list of non-repetitive words to\n * build a dictionary.\n * \n * For the method search, you'll be given a word, and judge whether if you\n * modify exactly one character into another character in this word, the\n * modified word is in the dictionary you just built.\n * \n * Example 1:\n * Input: buildDict([\"hello\", \"leetcode\"]), Output: Null\n * Input: search(\"hello\"), Output: False\n * Input: search(\"hhllo\"), Output: True\n * Input: search(\"hell\"), Output: False\n * Input: search(\"leetcoded\"), Output: False\n * \n * Note:\n * You may assume that all the inputs are consist of lowercase letters a-z.\n * For contest purpose, the test data is rather small by now. You could think\n * about highly efficient algorithm after the contest.\n * Please remember to RESET your class variables declared in class\n * MagicDictionary, as static/class variables are persisted across multiple\n * test cases. Please see here for more details.\n */\n\n\npublic class ImplementMagicDictionary676 {\n\n    class MagicDictionary {\n        private Trie trie = new Trie();\n\n        /** Initialize your data structure here. */\n        public MagicDictionary() {\n        }\n\n        /** Build a dictionary through a list of words */\n        public void buildDict(String[] dict) {\n            for (String word: dict) {\n                trie.add(word);\n            }\n        }\n\n        /** Returns if there is any word in the trie that equals to the given word after modifying exactly one character */\n        public boolean search(String word) {\n            return trie.search(word);\n        }\n\n        class Trie {\n            Trie[] children = new Trie[26];\n            boolean isWord;\n\n            void add(String word) {\n                if (word == null || word.length() == 0) return;\n                add(word.toCharArray(), 0);\n            }\n\n            void add(char[] word, int i) {\n                if (word.length == i) {\n                    isWord = true;\n                    return;\n                }\n                if (children[word[i]-'a'] == null) {\n                    children[word[i]-'a'] = new Trie();\n                }\n                children[word[i]-'a'].add(word, i+1);\n            }\n\n            boolean search(String word) {\n                if (word == null) return false;\n                return search(word.toCharArray(), 0, false);\n            }\n\n            boolean search(char[] word, int start, boolean modified) {\n                if (word.length == start) {\n                    return modified && isWord;\n                }\n                for (int i=0; i<26; i++) {\n                    if (children[i] == null) continue;\n                    if (word[start] == (i + 'a')) {\n                        if (children[i].search(word, start+1, modified)) return true;\n                    } else {\n                        if (modified) continue;\n                        if (children[i].search(word, start+1, true)) return true;\n                    }\n                }\n                return false;\n            }\n            \n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/implement-magic-dictionary/solution/\n     */\n    class MagicDictionary2 {\n        Map<Integer, ArrayList<String>> buckets;\n        public MagicDictionary() {\n            buckets = new HashMap();\n        }\n\n        public void buildDict(String[] words) {\n            for (String word: words) {\n                buckets.computeIfAbsent(word.length(), x -> new ArrayList()).add(word);\n            }\n        }\n\n        public boolean search(String word) {\n            if (!buckets.containsKey(word.length())) return false;\n            for (String candidate: buckets.get(word.length())) {\n                int mismatch = 0;\n                for (int i = 0; i < word.length(); ++i) {\n                    if (word.charAt(i) != candidate.charAt(i)) {\n                        if (++mismatch > 1) break;\n                    }\n                }\n                if (mismatch == 1) return true;\n            }\n            return false;\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/implement-magic-dictionary/solution/\n     */\n    public class MagicDictionary3 {\n        Set<String> words;\n        Map<String, Integer> count;\n\n        public MagicDictionary() {\n            words = new HashSet();\n            count = new HashMap();\n        }\n\n        private ArrayList<String> generalizedNeighbors(String word) {\n            ArrayList<String> ans = new ArrayList();\n            char[] ca = word.toCharArray();\n            for (int i = 0; i < word.length(); ++i) {\n                char letter = ca[i];\n                ca[i] = '*';\n                String magic = new String(ca);\n                ans.add(magic);\n                ca[i] = letter;\n            }\n            return ans;\n        }\n\n        public void buildDict(String[] words) {\n            for (String word: words) {\n                this.words.add(word);\n                for (String nei: generalizedNeighbors(word)) {\n                    count.put(nei, count.getOrDefault(nei, 0) + 1);\n                }\n            }\n        }\n\n        public boolean search(String word) {\n            for (String nei: generalizedNeighbors(word)) {\n                int c = count.getOrDefault(nei, 0);\n                if (c > 1 || c == 1 && !words.contains(word)) return true;\n            }\n            return false;\n        }\n    }\n\n/**\n * Your MagicDictionary object will be instantiated and called as such:\n * MagicDictionary obj = new MagicDictionary();\n * obj.buildDict(dict);\n * boolean param_2 = obj.search(word);\n */\n\n\n}\n"
  },
  {
    "path": "src/ImplementQueueUsingStacks232.java",
    "content": "/**\n * Implement the following operations of a queue using stacks.\n * \n * push(x) -- Push element x to the back of queue.\n * pop() -- Removes the element from in front of queue.\n * peek() -- Get the front element.\n * empty() -- Return whether the queue is empty.\n * \n * Example:\n * \n * MyQueue queue = new MyQueue();\n * \n * queue.push(1);\n * queue.push(2);  \n * queue.peek();  // returns 1\n * queue.pop();   // returns 1\n * queue.empty(); // returns false\n * \n * Notes:\n * \n * You must use only standard operations of a stack -- which means only push to\n * top, peek/pop from top, size, and is empty operations are valid.\n * Depending on your language, stack may not be supported natively. You may\n * simulate a stack by using a list or deque (double-ended queue), as long as\n * you use only standard operations of a stack.\n * You may assume that all operations are valid (for example, no pop or peek\n * operations will be called on an empty queue).\n */\n\n\npublic class ImplementQueueUsingStacks232 {\n\n    class MyQueue {\n        private Stack<Integer> st;\n        \n        /** Initialize your data structure here. */\n        public MyQueue() {\n            this.st = new Stack<Integer>();\n        }\n        \n        /** Push element x to the back of queue. */\n        public void push(int x) {\n            Stack<Integer> temp = new Stack<>();\n            int preSize = this.st.size();\n            for (int i=0; i<preSize; i++) {\n                temp.push(this.st.pop());\n            }\n            this.st.push(x);\n            for (int i=0; i<preSize; i++) {\n                this.st.push(temp.pop());\n            }\n        }\n        \n        /** Removes the element from in front of queue and returns that element. */\n        public int pop() {\n            return this.st.pop();\n        }\n        \n        /** Get the front element. */\n        public int peek() {\n            return this.st.peek();\n        }\n        \n        /** Returns whether the queue is empty. */\n        public boolean empty() {\n            return this.st.isEmpty();\n        }\n    }\n\n}\n\n\n\n/**\n* Your MyQueue object will be instantiated and called as such:\n* MyQueue obj = new MyQueue();\n* obj.push(x);\n* int param_2 = obj.pop();\n* int param_3 = obj.peek();\n* boolean param_4 = obj.empty();\n*/\n"
  },
  {
    "path": "src/ImplementStackusingQueues225.java",
    "content": "/**\n * Implement the following operations of a stack using queues.\n * \n * push(x) -- Push element x onto stack.\n * pop() -- Removes the element on top of the stack.\n * top() -- Get the top element.\n * empty() -- Return whether the stack is empty.\n * \n * Notes:\n * - You must use only standard operations of a queue -- which means only push\n *      to back, peek/pop from front, size, and is empty operations are valid.\n * - Depending on your language, queue may not be supported natively. You may\n *      simulate a queue by using a list or deque (double-ended queue), as long\n *      as you use only standard operations of a queue.\n * - You may assume that all operations are valid (for example, no pop or top\n *      operations will be called on an empty stack).\n */\n\n\npublic class ImplementStackUsingQueues225 {\n    \n    public class MyStack {\n        private Queue<Integer> q1 = new LinkedList<>();\n        private Queue<Integer> q2 = new LinkedList<>();\n        private int top = 0;\n        \n        /** Initialize your data structure here. */\n        public MyStack() {\n            \n        }\n        \n        /** Push element x onto stack. */\n        public void push(int x) {\n            if (empty()) {\n                q1.add(x);\n            } else {\n                if (q1.isEmpty()) {\n                    q2.add(x);\n                } else {\n                    q1.add(x);\n                }\n            }\n            top = x;\n        }\n        \n        /** Removes the element on top of the stack and returns that element. */\n        public int pop() {\n            if (q1.isEmpty()) {\n                int len = q2.size();\n                for (int i=1; i<len; i++) {\n                    top = q2.poll();\n                    q1.add(top);\n                }\n                return q2.poll();\n            } else {\n                int len = q1.size();\n                for (int i=1; i<len; i++) {\n                    top = q1.poll();\n                    q2.add(top);\n                }\n                return q1.poll();\n            }\n        }\n        \n        /** Get the top element. */\n        public int top() {\n            return top;\n        }\n        \n        /** Returns whether the stack is empty. */\n        public boolean empty() {\n            return q1.isEmpty() && q2.isEmpty();\n        }\n\n    }\n\n    public class MyStack2 {\n    \n        private Queue<Integer> q = new LinkedList<>();\n        \n        /** Initialize your data structure here. */\n        public MyStack() {\n            \n        }\n        \n        /** Push element x onto stack. */\n        public void push(int x) {\n            q.add(x);\n            int s = q.size();\n            while (s > 1) {\n                q.add(q.remove());\n                s--;\n            }\n        }\n        \n        /** Removes the element on top of the stack and returns that element. */\n        public int pop() {\n            return q.remove();\n        }\n        \n        /** Get the top element. */\n        public int top() {\n            return q.peek();\n        }\n        \n        /** Returns whether the stack is empty. */\n        public boolean empty() {\n            return q.isEmpty();\n        }\n    }\n\n}\n\n/**\n* Your MyStack object will be instantiated and called as such:\n* MyStack obj = new MyStack();\n* obj.push(x);\n* int param_2 = obj.pop();\n* int param_3 = obj.top();\n* boolean param_4 = obj.empty();\n*/\n"
  },
  {
    "path": "src/ImplementStrStr28.java",
    "content": "/**\n * Implement strStr(). http://www.cplusplus.com/reference/cstring/strstr/\n *\n * Return the index of the first occurrence of needle in haystack, or -1 if\n * needle is not part of haystack.\n *\n * Example 1:\n * Input: haystack = \"hello\", needle = \"ll\"\n * Output: 2\n *\n * Example 2:\n * Input: haystack = \"aaaaa\", needle = \"bba\"\n * Output: -1\n *\n */\n\n\npublic class ImplementStrStr28 {\n    public int strStr(String haystack, String needle) {\n        if (needle == null || needle.length() == 0) return 0;\n        if (haystack == null || haystack.length() == 0 || haystack.length() < needle.length()) return -1;\n\n        int i = 0;\n        while (i <= haystack.length() - needle.length()) {\n            int j = 0;\n            int t = i;\n            while (j < needle.length() && haystack.charAt(t) == needle.charAt(j)) {\n                j++;\n                t++;\n            }\n            if (j == needle.length()) return i;\n            i++;\n        }\n\n        return -1;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/implement-strstr/discuss/12811/Share-my-accepted-java-solution\n     */\n    public int strStr2(String haystack, String needle) {\n        int l1 = haystack.length(), l2 = needle.length();\n        if (l1 < l2) {\n            return -1;\n        } else if (l2 == 0) {\n            return 0;\n        }\n        int threshold = l1 - l2;\n        for (int i = 0; i <= threshold; ++i) {\n            if (haystack.substring(i,i+l2).equals(needle)) {\n                return i;\n            }\n        }\n        return -1;\n    }\n\n}\n"
  },
  {
    "path": "src/ImplementTriePrefixTree208.java",
    "content": "/**\n * Implement a trie with insert, search, and startsWith methods.\n * \n * Example:\n * \n * Trie trie = new Trie();\n * \n * trie.insert(\"apple\");\n * trie.search(\"apple\");   // returns true\n * trie.search(\"app\");     // returns false\n * trie.startsWith(\"app\"); // returns true\n * trie.insert(\"app\");   \n * trie.search(\"app\");     // returns true\n * \n * Note:\n * You may assume that all inputs are consist of lowercase letters a-z.\n * All inputs are guaranteed to be non-empty strings.\n */\n\n\npublic class ImplementTriePrefixTree208 {\n\n    class Trie {\n\n        private Trie[] children = new Trie[26];\n        private boolean isWord = false;\n        \n        /** Initialize your data structure here. */\n        public Trie() {\n            \n        }\n        \n        /** Inserts a word into the trie. */\n        public void insert(String word) {\n            insert(word.toCharArray(), 0);\n        }\n        \n        private void insert(char[] chars, int i) {\n            if (i == chars.length) {\n                this.isWord = true;\n                return;\n            }\n            if (this.children[chars[i]-'a'] == null) {\n                this.children[chars[i]-'a'] = new Trie();\n            }\n            this.children[chars[i]-'a'].insert(chars, i+1);\n        }\n        \n        /** Returns if the word is in the trie. */\n        public boolean search(String word) {\n            return search(word.toCharArray(), 0);\n        }\n        \n        private boolean search(char[] chars, int i) {\n            if (i == chars.length) return this.isWord;\n            if (this.children[chars[i]-'a'] == null) return false;\n            return this.children[chars[i]-'a'].search(chars, i+1);\n        }\n        \n        /** Returns if there is any word in the trie that starts with the given prefix. */\n        public boolean startsWith(String prefix) {\n            return startsWith(prefix.toCharArray(), 0);\n        }\n\n        private boolean startsWith(char[] chars, int i) {\n            if (i == chars.length) return true; \n            if (this.children[chars[i]-'a'] == null) return false;\n            return this.children[chars[i]-'a'].startsWith(chars, i+1);\n        }\n        \n    }\n\n\n    /**\n     * https://leetcode.com/problems/implement-trie-prefix-tree/solution/\n     */\n    class Trie2 {\n        private TrieNode root;\n    \n        /** Initialize your data structure here. */\n        public Trie() {\n            root = new TrieNode();\n        }\n    \n        /** Inserts a word into the trie. */\n        public void insert(String word) {\n            TrieNode node = root;\n            for (int i = 0; i < word.length(); i++) {\n                char c = word.charAt(i);\n                if (!node.containsKey(c)) {\n                    node.put(c, new TrieNode());\n                }\n                node = node.get(c);\n            }\n            node.setLeaf();\n        }\n    \n        /** Returns if the word is in the trie. */\n        public boolean search(String word) {\n            TrieNode node = root;\n            for (int i = 0; i < word.length(); i++) {\n                char c = word.charAt(i);\n                if (!node.containsKey(c)) {\n                    return false;\n                }\n                node = node.get(c);\n            }\n            return node.isLeaf();\n        }\n    \n        /** Returns if there is any word in the trie that starts with the given prefix. */\n        public boolean startsWith(String prefix) {\n            TrieNode node = root;\n            for (int i = 0; i < prefix.length(); i++) {\n                char c = prefix.charAt(i);\n                if (!node.containsKey(c)) {\n                    return false;\n                }\n                node = node.get(c);\n            }\n            return true;\n        }\n    }\n\n    class TrieNode {\n        // R links to node children\n        private TrieNode[] links;\n    \n        private final int R = 26;\n    \n        private boolean isLeaf;\n    \n        public TrieNode() {\n            links = new TrieNode[R];\n        }\n    \n        public boolean containsKey(char c) {\n            return links[c -'a'] != null;\n        }\n        public TrieNode get(char c) {\n            return links[c -'a'];\n        }\n        public void put(char c, TrieNode node) {\n            links[c -'a'] = node;\n        }\n        public void setLeaf() {\n            isLeaf = true;\n        }\n        public boolean isLeaf() {\n            return isLeaf;\n        }\n    }\n\n\n/**\n * Your Trie object will be instantiated and called as such:\n * Trie obj = new Trie();\n * obj.insert(word);\n * boolean param_2 = obj.search(word);\n * boolean param_3 = obj.startsWith(prefix);\n */\n\n  \n}\n"
  },
  {
    "path": "src/IncreasingSubsequences491.java",
    "content": "/**\n * Given an integer array, your task is to find all the different possible\n * increasing subsequences of the given array, and the length of an increasing\n * subsequence should be at least 2 .\n * \n * Example:\n * Input: [4, 6, 7, 7]\n * Output: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]]\n * \n * Note:\n * The length of the given array will not exceed 15.\n * The range of integer in the given array is [-100,100].\n * The given array may contain duplicates, and two equal integers should also\n * be considered as a special case of increasing sequence.\n */\n\npublic class IncreasingSubsequences491 {\n    public List<List<Integer>> findSubsequences(int[] nums) {\n        List<List<Integer>> res = new ArrayList<>();\n        helper(nums, Integer.MIN_VALUE, 0, new ArrayList<>(), res);\n        return res;\n    }\n    \n    private void helper(int[] nums, int pre, int start, List<Integer> path, List<List<Integer>> res) {\n        if (path.size() >= 2) res.add(new ArrayList<>(path));\n        if (start == nums.length) return;\n\n        boolean[] visited = new boolean[201];\n        for (int i=start; i<nums.length; i++) {\n            if (visited[nums[i]+100]) continue;\n            visited[nums[i]+100] = true;\n            if (nums[i] >= pre) {\n                path.add(nums[i]);\n                helper(nums, nums[i], i+1, path, res);\n                path.remove(path.size() - 1);\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/IncreasingTripletSubsequence334.java",
    "content": "/**\n * Given an unsorted array return whether an increasing subsequence of length\n * 3 exists or not in the array.\n *\n * Formally the function should:\n * Return true if there exists i, j, k\n * such that arr[i] < arr[j] < arr[k] given 0 ≤ i < j < k ≤ n-1 else return false.\n * Your algorithm should run in O(n) time complexity and O(1) space complexity.\n *\n * Examples:\n * Given [1, 2, 3, 4, 5],\n * return true.\n *\n * Given [5, 4, 3, 2, 1],\n * return false.\n */\n\n\npublic class IncreasingTripletSubsequence334 {\n    public boolean increasingTriplet(int[] nums) {\n        if (nums == null || nums.length < 3) return false;\n        int a = nums[0];\n        int b = Integer.MAX_VALUE;\n        for (int i=1; i<nums.length; i++) {\n            if (nums[i] > b) return true;\n            else if (nums[i] > a) b = nums[i];\n            else a = nums[i];\n        }\n        return false;\n    }\n\n    public boolean increasingTriplet2(int[] nums) {\n        if (nums == null || nums.length < 3) return false;\n        int N = nums.length;\n        int[] dp = new int[3];\n        \n        int size = 0;\n        for (int i=0; i<N; i++) {\n            int curr = nums[i];\n            int insertPoist = 0;\n            while (insertPoist < size && dp[insertPoist] < curr) {\n                insertPoist++;\n            }\n            dp[insertPoist] = curr;\n            if (insertPoist == size) size++;\n            if (size == 3) return true;\n        }\n        return false;\n    }\n\n\n    public boolean increasingTriplet3(int[] nums) {\n        if (nums == null || nums.length < 3) return false;\n        int N = nums.length;\n        int[] dp = new int[N + 1];\n        for (int i=1; i<=N; i++) {\n            int tmp = 1;\n            for (int j=1; j<i; j++) {\n                if (nums[i-1] > nums[j-1] && dp[j] + 1 > tmp) {\n                    tmp = dp[j] + 1;\n                }\n                if (tmp >= 3) return true;\n            }\n            dp[i] = tmp;\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "src/InorderSuccessorInBST285.java",
    "content": "/**\n * Given a binary search tree and a node in it, find the in-order successor of\n * that node in the BST.\n *\n * Note: If the given node has no in-order successor in the tree, return null.\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class InorderSuccessorInBST285 {\n    // Iteratively\n    public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {\n        if (p.right != null)\n            return findMin(p.right);\n\n        TreeNode succ = null;\n        while (root != null) {\n            if (root.val == p.val) break;\n            if (root.val > p.val) {\n                succ = root;\n                root = root.left;\n            } else {\n                root = root.right;\n            }\n        }\n        return succ;\n    }\n\n    private TreeNode findMin(TreeNode n) {\n        if (n == null) return null;\n        TreeNode t = n;\n        while (t.left != null) t = t.left;\n        return t;\n    }\n\n\n    // Recursively\n    public TreeNode inorderSuccessor2(TreeNode root, TreeNode x) {\n        if (x.right != null)\n            return findMin(x.right);\n        return inorderSuccessor2(root, x, null);\n    }\n\n    public TreeNode inorderSuccessor2(TreeNode root, TreeNode x, TreeNode succ) {\n        if (root == null || x == null || root.val == x.val) return succ;\n        if (root.val > x.val) {\n            return inorderSuccessor2(root.left, x, root);\n        } else {\n            return inorderSuccessor2(root.right, x, succ);\n        }\n    }\n\n\n    public TreeNode inorderSuccessor3(TreeNode root, TreeNode p) {\n        return inorderSuccessor3(root, p, null);\n    }\n\n    public TreeNode inorderSuccessor3(TreeNode root, TreeNode p, TreeNode pre) {\n        if (root.val == p.val) {\n            if (root.right == null) {\n                return pre;\n            } else {\n                return findMin(root.right);\n            }\n        } else if (root.val > p.val) {\n            return inorderSuccessor3(root.left, p, root);\n        } else {\n            return inorderSuccessor3(root.right, p, pre);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/inorder-successor-in-bst/discuss/72653/Share-my-Java-recursive-solution\n     */\n    public TreeNode inorderSuccessor4(TreeNode root, TreeNode p) {\n        if (root == null)\n            return null;\n        if (root.val <= p.val) {\n            return successor(root.right, p);\n        } else {\n            TreeNode left = successor(root.left, p);\n            return (left != null) ? left : root;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/InsertDeleteGetRandomOOne380.java",
    "content": "/**\n * Design a data structure that supports all following operations in average\n * O(1) time.\n *\n * insert(val): Inserts an item val to the set if not already present.\n * remove(val): Removes an item val from the set if present.\n * getRandom: Returns a random element from current set of elements.\n *     Each element must have the same probability of being returned.\n *\n * Example:\n *\n * // Init an empty set.\n * RandomizedSet randomSet = new RandomizedSet();\n *\n * // Inserts 1 to the set. Returns true as 1 was inserted successfully.\n * randomSet.insert(1);\n *\n * // Returns false as 2 does not exist in the set.\n * randomSet.remove(2);\n *\n * // Inserts 2 to the set, returns true. Set now contains [1,2].\n * randomSet.insert(2);\n *\n * // getRandom should return either 1 or 2 randomly.\n * randomSet.getRandom();\n *\n * // Removes 1 from the set, returns true. Set now contains [2].\n * randomSet.remove(1);\n *\n * // 2 was already in the set, so return false.\n * randomSet.insert(2);\n *\n * // Since 2 is the only number in the set, getRandom always return 2.\n * randomSet.getRandom();\n *\n */\n\n\npublic class InsertDeleteGetRandomOOne380 {\n    public class RandomizedSet {\n        private Set<Integer> set;\n        private Random rand;\n\n        /** Initialize your data structure here. */\n        public RandomizedSet() {\n            this.set = new HashSet<Integer>();\n            this.rand = new Random();\n        }\n\n        /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */\n        public boolean insert(int val) {\n            return this.set.add(val);\n        }\n\n        /** Removes a value from the set. Returns true if the set contained the specified element. */\n        public boolean remove(int val) {\n            return this.set.remove(val);\n        }\n\n        /** Get a random element from the set. */\n        public int getRandom() {\n            Object[] values = this.set.toArray();\n            return (Integer) values[rand.nextInt(values.length)];\n        }\n    }\n\n    public class RandomizedSet2 {\n\n        private Map<Integer, Integer> map;\n        private ArrayList<Integer> values;\n        private Random rand;\n\n        /** Initialize your data structure here. */\n        public RandomizedSet() {\n            this.map = new HashMap<Integer, Integer>();\n            this.values = new ArrayList<Integer>();\n            this.rand = new Random();\n        }\n\n        /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */\n        public boolean insert(int val) {\n            if (map.containsKey(val)) return false;\n            map.put(val, values.size());\n            values.add(val);\n            return true;\n        }\n\n        /** Removes a value from the set. Returns true if the set contained the specified element. */\n        public boolean remove(int val) {\n            if (!map.containsKey(val)) return false;\n\n            int pos = map.get(val);\n            int len = values.size();\n            if (pos != len-1) {\n                int temp = values.get(len-1);\n                values.set(pos, temp);\n                map.put(temp, pos);\n            }\n\n            map.remove(val);\n            values.remove(len-1);\n\n            return true;\n        }\n\n        /** Get a random element from the set. */\n        public int getRandom() {\n            return values.get(rand.nextInt(values.size()));\n        }\n    }\n\n\n    class RandomizedSet3 {\n        private Map<Integer, Integer> indexToValue = new HashMap<>();\n        private Map<Integer, Integer> valueToIndex = new HashMap<>();\n        private Queue<Integer> q = new LinkedList<>();\n        private int index = 0;\n        private Random rand = new Random();\n\n        /** Initialize your data structure here. */\n        public RandomizedSet() {\n            \n        }\n\n        /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */\n        public boolean insert(int val) {\n            if (valueToIndex.containsKey(val)) return false;\n            if (q.isEmpty()) {\n                indexToValue.put(index, val);\n                valueToIndex.put(val, index);\n                index++;\n            } else {\n                int currIdx = q.poll();\n                indexToValue.put(currIdx, val);\n                valueToIndex.put(val, currIdx);\n            }\n            return true;\n        }\n\n        /** Removes a value from the set. Returns true if the set contained the specified element. */\n        public boolean remove(int val) {\n            if (!valueToIndex.containsKey(val)) return false;\n            int idx = valueToIndex.remove(val);\n            indexToValue.remove(idx);\n            q.add(idx);\n            return true;\n        }\n\n        /** Get a random element from the set. */\n        public int getRandom() {\n            if (valueToIndex.isEmpty()) return -1;\n            while (true) {\n                int idx = rand.nextInt(index);\n                if (!indexToValue.containsKey(idx)) continue;\n                return indexToValue.get(idx);\n            }\n        }\n    }\n\n    /**\n     * Your RandomizedSet object will be instantiated and called as such:\n     * RandomizedSet obj = new RandomizedSet();\n     * boolean param_1 = obj.insert(val);\n     * boolean param_2 = obj.remove(val);\n     * int param_3 = obj.getRandom();\n     */\n\n}\n"
  },
  {
    "path": "src/InsertInterval57.java",
    "content": "/**\n * Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).\n *\n * You may assume that the intervals were initially sorted according to their start times.\n *\n * Example 1:\n * Given intervals [1,3],[6,9], insert and merge [2,5] in as [1,5],[6,9].\n *\n * Example 2:\n * Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as [1,2],[3,10],[12,16].\n *\n * This is because the new interval [4,9] overlaps with [3,5],[6,7],[8,10].\n */\n\n/**\n * Definition for an interval.\n * public class Interval {\n *     int start;\n *     int end;\n *     Interval() { start = 0; end = 0; }\n *     Interval(int s, int e) { start = s; end = e; }\n * }\n */\n\nimport java.util.Arrays;\nimport java.util.ArrayList;\nimport java.util.List;\n\n\npublic class InsertInterval57 {\n    public List<Interval> insert(List<Interval> intervals, Interval newInterval) {\n\n        int start = newInterval.start;\n        int end = newInterval.end;\n\n        List<Interval> result = new ArrayList<>();\n        boolean newAdded = false;\n\n        for (Interval in: intervals) {\n            if (in.end < start) {\n                result.add(in);\n            } else if (in.start > end) {\n                if (!newAdded) {\n                    result.add(new Interval(start, end));\n                    newAdded = true;\n                }\n                result.add(in);\n            } else {\n                start = Math.min(in.start, start);\n                end = Math.max(in.end, end);\n            }\n        }\n\n        if (!newAdded) {\n            result.add(new Interval(start, end));\n        }\n\n        return result;\n    }\n\n\n    public static void main(String[] args) {\n        InsertInterval57 ii = new InsertInterval57();\n        System.out.println(ii.insert(new ArrayList<Interval>(Arrays.asList(new Interval(1, 3), new Interval(6, 9))), new Interval(2, 5)));\n    }\n\n\n}\n"
  },
  {
    "path": "src/InsertIntoACyclicSortedList.java",
    "content": "/**\n * Given a node from a cyclic linked list which is sorted in ascending order,\n * write a function to insert a value into the list such that it remains a\n * cyclic sorted list. The given node can be a reference to any single node in\n * the list, and may not be necessarily the smallest value in the cyclic list.\n * \n * If there are multiple suitable places for insertion, you may choose any\n * place to insert the new value. After the insertion, the cyclic list should\n * remain sorted.\n * \n * If the list is empty (i.e., given node is null), you should create a new\n * single cyclic list and return the reference to that single node.\n * \n * Otherwise, you should return the original given node.\n * \n * The following example may help you understand the problem better:\n * https://leetcode.com/static/images/problemset/InsertCyclicBefore.png\n * \n * In the figure above, there is a cyclic sorted list of three elements. You\n * are given a reference to the node with value 3, and we need to insert 2\n * into the list.\n * https://leetcode.com/static/images/problemset/InsertCyclicAfter.png\n * \n * The new node should insert between node 1 and node 3. After the insertion,\n * the list should look like this, and we should still return node 3.\n */\n\n/*\n// Definition for a Node.\nclass Node {\n    public int val;\n    public Node next;\n\n    public Node() {}\n\n    public Node(int _val,Node _next) {\n        val = _val;\n        next = _next;\n    }\n};\n*/\n\npublic class InsertIntoACyclicSortedList {\n    public Node insert(Node head, int insertVal) {\n        Node newNode = new Node(insertVal, null);\n        if (head == null) {\n            newNode.next = newNode;\n            return newNode;\n        }\n        \n        Node p = head;\n        boolean inserted = false;\n        do {\n            if (p == p.next || p.val == insertVal || (p.val < insertVal && p.next.val > insertVal) ||\n                    (((p.val > insertVal && p.next.val > insertVal) || (p.val < insertVal && p.next.val < insertVal)) && p.next.val < p.val)) {\n                newNode.next = p.next;\n                p.next = newNode;\n                inserted = true;\n                break;\n            }\n            p = p.next;\n        } while (p != head);\n        if (!inserted) {\n            newNode.next = p.next;\n            p.next = newNode;\n        }\n        return head;\n    }\n\n\n    public Node insert2(Node head, int insertVal) {\n        Node newNode = new Node();\n        newNode.val = insertVal;\n        if (head == null) {\n            newNode.next = newNode;\n            return newNode;\n        }\n        Node p = head;\n        Node dec = null;\n        while (true) {\n            if (p.val <= insertVal && p.next.val >= insertVal) {\n                newNode.next = p.next;\n                p.next = newNode;\n                return head;\n            }\n            if (p.val > p.next.val) {\n                dec = p;\n            }\n            p = p.next;\n            if (p == head) break;\n        }\n        if (dec == null) dec = head;\n        newNode.next = dec.next;\n        dec.next = newNode;\n        return head;\n    }\n\n}\n"
  },
  {
    "path": "src/InsertionSortList147.java",
    "content": "/**\n * Sort a linked list using insertion sort.\n */\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\npublic class InsertionSortList147 {\n    public ListNode insertionSortList(ListNode head) {\n        if (head == null || head.next == null) return head;\n\n        ListNode dummy = new ListNode(0);\n        ListNode end = new ListNode(head.val);\n        dummy.next = end;\n\n        ListNode p = head.next;\n        while (p != null) {\n            ListNode n = new ListNode(p.val);\n            if (n.val >= end.val) {\n                end.next = n;\n                end = n;\n            } else {\n                insert(dummy, n);\n            }\n            p = p.next;\n        }\n\n        return dummy.next;\n    }\n\n    private void insert(ListNode dummy, ListNode newNode) {\n        ListNode pre = dummy;\n        ListNode now = dummy.next;\n        while (now != null) {\n            if (now.val >= newNode.val) {\n                pre.next = newNode;\n                newNode.next = now;\n                return;\n            }\n            now = now.next;\n            pre = pre.next;\n        }\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/8570/an-easy-and-clear-way-to-sort-o-1-space\n     */\n    public ListNode insertionSortList2(ListNode head) {\n  \t\tif( head == null ){\n  \t\t\treturn head;\n  \t\t}\n\n  \t\tListNode helper = new ListNode(0); //new starter of the sorted list\n  \t\tListNode cur = head; //the node will be inserted\n  \t\tListNode pre = helper; //insert node between pre and pre.next\n  \t\tListNode next = null; //the next node will be inserted\n  \t\t//not the end of input list\n  \t\twhile( cur != null ){\n  \t\t\tnext = cur.next;\n  \t\t\t//find the right place to insert\n  \t\t\twhile( pre.next != null && pre.next.val < cur.val ){\n  \t\t\t\tpre = pre.next;\n  \t\t\t}\n  \t\t\t//insert between pre and pre.next\n  \t\t\tcur.next = pre.next;\n  \t\t\tpre.next = cur;\n  \t\t\tpre = helper;\n  \t\t\tcur = next;\n  \t\t}\n\n  \t\treturn helper.next;\n  \t}\n\n}\n"
  },
  {
    "path": "src/IntegerBreak343.java",
    "content": "/**\n * Given a positive integer n, break it into the sum of at least two positive\n * integers and maximize the product of those integers. Return the maximum\n * product you can get.\n * \n * Example 1:\n * Input: 2\n * Output: 1\n * Explanation: 2 = 1 + 1, 1 × 1 = 1.\n * \n * Example 2:\n * Input: 10\n * Output: 36\n * Explanation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36.\n * Note: You may assume that n is not less than 2 and not larger than 58.\n */\n\npublic class IntegerBreak343 {\n    public int integerBreak(int n) {\n        int[] dp = new int[n+1];\n        dp[1] = 1;\n        for (int i=2; i<=n; i++) {\n            int tmp = 0;\n            for (int j=1; j<i; j++) {\n                int k = i - j;\n                tmp = Math.max(tmp, j * k);\n                tmp = Math.max(tmp, j * dp[k]);\n            }\n            dp[i] = tmp;\n        }\n        return dp[n];\n    }\n\n\n    /**\n     * https://leetcode.com/problems/integer-break/discuss/80689/A-simple-explanation-of-the-math-part-and-a-O(n)-solution\n     */\n    public int integerBreak2(int n) {\n        if(n==2) return 1;\n        if(n==3) return 2;\n        int product = 1;\n        while(n>4){\n            product*=3;\n            n-=3;\n        }\n        product*=n;\n        \n        return product;\n    }\n\n}\n"
  },
  {
    "path": "src/IntegerToEnglishWords273.java",
    "content": "/**\n * Convert a non-negative integer to its english words representation. Given\n * input is guaranteed to be less than 231 - 1.\n *\n * For example,\n * 123 -> \"One Hundred Twenty Three\"\n * 12345 -> \"Twelve Thousand Three Hundred Forty Five\"\n * 1234567 -> \"One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven\"\n */\n\n\npublic class IntegerToEnglishWords273 {\n\n    private static final String[] UNITS = {\n        \"Zero\", \"One\", \"Two\", \"Three\", \"Four\", \"Five\", \"Six\", \"Seven\", \"Eight\", \"Nine\", \"Ten\",\n        \"Eleven\", \"Twelve\", \"Thirteen\", \"Fourteen\", \"Fifteen\", \"Sixteen\", \"Seventeen\", \"Eighteen\", \"Nineteen\"};\n    private static final String[] TENS = {\"Twenty\", \"Thirty\", \"Forty\", \"Fifty\", \"Sixty\", \"Seventy\", \"Eighty\", \"Ninety\"};\n    private static final String[] THOUSANDS = {\"\", \"Thousand\", \"Million\", \"Billion\"};\n\n\n    public String numberToWords(int num) {\n        if (num == 0) return \"Zero\";\n\n        int i = 0;\n        String words = \"\";\n        while (num > 0) {\n            if (num % 1000 != 0) {\n        \t      words = threeDigits(num % 1000) + \" \" + THOUSANDS[i] + \" \" + words;\n            }\n          \tnum /= 1000;\n          \ti++;\n        }\n\n        return words.trim();\n    }\n\n\n    private String threeDigits(int num) {\n        if (num >= 100) {\n            int h = num/100;\n            String twoDigits = twoDigits(num%100);\n            return UNITS[h] + \" Hundred\" + ((twoDigits.length() == 0) ? \"\" : \" \" + twoDigits);\n        }\n        return twoDigits(num);\n    }\n\n    private String twoDigits(int num) {\n        if (num == 0) return \"\";\n\n        if (num > 0 && num < 20) {\n            return UNITS[num];\n        }\n\n        int t = num/10;\n        int n = num%10;\n\n        return TENS[t-2] + ((n == 0) ? \"\": (\" \" + UNITS[n]));\n    }\n\n\n}\n"
  },
  {
    "path": "src/IntegerToRoman12.java",
    "content": "/**\n * Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.\n * \n * Symbol       Value\n * I             1\n * V             5\n * X             10\n * L             50\n * C             100\n * D             500\n * M             1000\n * \n * For example, two is written as II in Roman numeral, just two one's added\n * together. Twelve is written as, XII, which is simply X + II. The number\n * twenty seven is written as XXVII, which is XX + V + II.\n * \n * Roman numerals are usually written largest to smallest from left to right.\n * However, the numeral for four is not IIII. Instead, the number four is\n * written as IV. Because the one is before the five we subtract it making\n * four. The same principle applies to the number nine, which is written as IX.\n * \n * There are six instances where subtraction is used:\n * \n * I can be placed before V (5) and X (10) to make 4 and 9. \n * X can be placed before L (50) and C (100) to make 40 and 90. \n * C can be placed before D (500) and M (1000) to make 400 and 900.\n * \n * Given an integer, convert it to a roman numeral. Input is guaranteed to be\n * within the range from 1 to 3999.\n * \n * Example 1:\n * Input: 3\n * Output: \"III\"\n * \n * Example 2:\n * Input: 4\n * Output: \"IV\"\n * \n * Example 3:\n * Input: 9\n * Output: \"IX\"\n * \n * Example 4:\n * Input: 58\n * Output: \"LVIII\"\n * Explanation: L = 50, V = 5, III = 3.\n * \n * Example 5:\n * Input: 1994\n * Output: \"MCMXCIV\"\n * Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.\n */\n\npublic class IntegerToRoman12 {\n    //                                    1,   5,  10,  50,  100, 500, 1000\n    private static char[] R = new char[]{'I', 'V', 'X', 'L', 'C', 'D', 'M'};\n    public String intToRoman(int num) {\n        StringBuilder sb = new StringBuilder();\n        int base = 0;\n        while (num > 0) {\n            int digit = num % 10;\n            if (digit > 0) {\n                char[] cur = curr(digit, base);\n                sb.insert(0, cur);\n            }\n            num /= 10;\n            base += 2;\n        }\n        return sb.toString();\n    }\n\n    private char[] curr(int digit, int base) {\n        if (digit >= 1 && digit <= 3) {\n            char[] res = new char[digit];\n            Arrays.fill(res, R[base]);\n            return res;\n        } else if (digit == 4) {\n            return new char[]{R[base], R[base+1]};\n        } else if (digit == 5) {\n            return new char[]{R[base+1]};\n        } else if (digit >= 6 && digit <= 8) {\n            char[] res = new char[digit-5+1];\n            Arrays.fill(res, R[base]);\n            res[0] = R[base+1];\n            return res;\n        } else { // 9\n            return new char[]{R[base], R[base+2]};\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/integer-to-roman/discuss/6274/Simple-Solution\n     */\n    public static String intToRoman2(int num) {\n        String M[] = {\"\", \"M\", \"MM\", \"MMM\"};\n        String C[] = {\"\", \"C\", \"CC\", \"CCC\", \"CD\", \"D\", \"DC\", \"DCC\", \"DCCC\", \"CM\"};\n        String X[] = {\"\", \"X\", \"XX\", \"XXX\", \"XL\", \"L\", \"LX\", \"LXX\", \"LXXX\", \"XC\"};\n        String I[] = {\"\", \"I\", \"II\", \"III\", \"IV\", \"V\", \"VI\", \"VII\", \"VIII\", \"IX\"};\n        return M[num/1000] + C[(num%1000)/100] + X[(num%100)/10] + I[num%10];\n    }\n\n}\n"
  },
  {
    "path": "src/InterleavingString97.java",
    "content": "/**\n * Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.\n *\n * For example,\n * Given:\n * s1 = \"aabcc\",\n * s2 = \"dbbca\",\n *\n * When s3 = \"aadbbcbcac\", return true.\n * When s3 = \"aadbbbaccc\", return false.\n *\n */\n\n\nimport java.util.Stack;\n\n\npublic class InterleavingString97 {\n    // cannot pass time limit\n    class Pair {\n        int i;\n        int j;\n        int k;\n        Pair(int i, int j, int k) {\n            this.i = i;\n        \tthis.j = j;\n            this.k = k;\n        }\n    }\n\n    public boolean isInterleave(String s1, String s2, String s3) {\n        int l1 = s1.length();\n        int l2 = s2.length();\n        int l3 = s3.length();\n        if ((l1 + l2) != l3) return false;\n\n        Stack<Pair> track = new Stack<>();\n\n        int i = 0;\n        int j = 0;\n        int k = 0;\n        boolean b = true;\n        while (k < l3) {\n            if (i<l1 && b && s3.charAt(k) == s1.charAt(i)) {\n                track.push(new Pair(i, j, k));\n                i++;\n                k++;\n                continue;\n            }\n            if (j<l2 && s3.charAt(k) == s2.charAt(j)) {\n                j++;\n                k++;\n                b = true;\n                continue;\n            }\n            if (k == 0 || track.size() == 0) {\n                return false;\n            }\n\n            Pair p = track.pop();\n            i = p.i;\n            j = p.j;\n            k = p.k;\n            b = false;\n        }\n\n        return true;\n    }\n\n    // DP\n    public boolean isInterleave2(String s1, String s2, String s3) {\n        int l1 = s1.length();\n        int l2 = s2.length();\n        int l3 = s3.length();\n        if ((l1 + l2) != l3) return false;\n\n\t\t    boolean[][] dp = new boolean[l2+1][l1+1];\n        dp[0][0] = true;\n\n        int i = 1;\n        int j = 1;\n        for (i = 1; i<=l2; i++) {\n            dp[i][0] = dp[i-1][0] && (s3.charAt(i-1) == s2.charAt(i-1));\n        }\n        for (j = 1; j<=l1; j++) {\n            dp[0][j] = dp[0][j-1] && (s3.charAt(j-1) == s1.charAt(j-1));\n        }\n\n        for (i=1; i<=l2; i++) {\n            for (j=1; j<=l1; j++) {\n                dp[i][j] = (dp[i-1][j] && s3.charAt(i+j-1) == s2.charAt(i-1)) || (dp[i][j-1] && s3.charAt(i+j-1) == s1.charAt(j-1));\n            }\n        }\n        for (i = 0; i<=l2; i++) {\n            System.out.println(Arrays.toString(dp[i]));\n        }\n\n        return dp[l2][l1];\n    }\n\n    // DP, stop early\n    public boolean isInterleave3(String s1, String s2, String s3) {\n        int l1 = s1.length();\n        int l2 = s2.length();\n        int l3 = s3.length();\n        if ((l1 + l2) != l3) return false;\n\n        boolean[][] dp = new boolean[l2+1][l1+1];\n        dp[0][0] = true;\n\n        int i = 1;\n        int j = 1;\n        for (i = 1; i<=l2; i++) {\n            dp[i][0] = dp[i-1][0] && (s3.charAt(i-1) == s2.charAt(i-1));\n        }\n\n        boolean l = false;\n        boolean one = false;\n        for (j = 1; j<=l1; j++) {\n            dp[0][j] = dp[0][j-1] && (s3.charAt(j-1) == s1.charAt(j-1));\n            one = dp[0][j] || one;\n        }\n        l = one;\n\n        for (i=1; i<=l2; i++) {\n            if (dp[i][0] == false && l == false) {\n                return false;\n            }\n            one = false;\n            for (j=1; j<=l1; j++) {\n                dp[i][j] = (dp[i-1][j] && s3.charAt(i+j-1) == s2.charAt(i-1)) || (dp[i][j-1] && s3.charAt(i+j-1) == s1.charAt(j-1));\n                one = dp[i][j] || one;\n            }\n            l = one;\n        }\n\n        return dp[l2][l1];\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/31991/1ms-tiny-dfs-beats-94-57\n     */\n    public boolean isInterleave4(String s1, String s2, String s3) {\n        char[] c1 = s1.toCharArray(), c2 = s2.toCharArray(), c3 = s3.toCharArray();\n    \tint m = s1.length(), n = s2.length();\n    \tif(m + n != s3.length()) return false;\n    \treturn dfs(c1, c2, c3, 0, 0, 0, new boolean[m + 1][n + 1]);\n    }\n\n    public boolean dfs(char[] c1, char[] c2, char[] c3, int i, int j, int k, boolean[][] invalid) {\n    \tif(invalid[i][j]) return false;\n    \tif(k == c3.length) return true;\n    \tboolean valid =\n    \t    i < c1.length && c1[i] == c3[k] && dfs(c1, c2, c3, i + 1, j, k + 1, invalid) ||\n            j < c2.length && c2[j] == c3[k] && dfs(c1, c2, c3, i, j + 1, k + 1, invalid);\n    \tif(!valid) invalid[i][j] = true;\n        return valid;\n    }\n\n}\n"
  },
  {
    "path": "src/IntersectionOfTwoArrays349.java",
    "content": "/**\n * Given two arrays, write a function to compute their intersection.\n * \n * Example:\n * Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2].\n * \n * Note:\n *      Each element in the result must be unique.\n *      The result can be in any order.\n */\n\nimport java.util.Set;\nimport java.util.HashSet;\n\npublic class IntersectionOfTwoArrays349 {\n\n    public static int[] intersection(int[] nums1, int[] nums2) {\n        if (nums1 == null || nums1.length == 0 ||\n            nums2 == null || nums2.length == 0) return new int[]{};\n\n        Set<Integer> setNums1 = new HashSet<>();\n        for (int i1: nums1) {\n            setNums1.add(i1);\n        }\n\n        Set<Integer> resSet = new HashSet<>();\n        for (int i2: nums2) {\n            if (setNums1.contains(i2)) {\n                resSet.add(i2);\n            }\n        }\n\n        int[] res = new int[resSet.size()];\n        int i = 0;\n        for (Integer resInt: resSet) {\n            res[i++] = (int) resInt;\n        }\n\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/intersection-of-two-arrays/discuss/81969/Three-Java-Solutions\n     */\n    public int[] intersection2(int[] nums1, int[] nums2) {\n        Set<Integer> set = new HashSet<>();\n        Arrays.sort(nums1);\n        Arrays.sort(nums2);\n        int i = 0;\n        int j = 0;\n        while (i < nums1.length && j < nums2.length) {\n            if (nums1[i] < nums2[j]) {\n                i++;\n            } else if (nums1[i] > nums2[j]) {\n                j++;\n            } else {\n                set.add(nums1[i]);\n                i++;\n                j++;\n            }\n        }\n        int[] result = new int[set.size()];\n        int k = 0;\n        for (Integer num : set) {\n            result[k++] = num;\n        }\n        return result;\n    }\n\n}\n"
  },
  {
    "path": "src/IntersectionOfTwoArraysII350.java",
    "content": "/**\n * Given two arrays, write a function to compute their intersection.\n *\n * Example:\n * Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2, 2].\n *\n * Note:\n * Each element in the result should appear as many times as it shows in both arrays.\n * The result can be in any order.\n *\n * Follow up:\n * What if the given array is already sorted? How would you optimize your algorithm?\n * What if nums1's size is small compared to nums2's size? Which algorithm is better?\n * What if elements of nums2 are stored on disk, and the memory is limited such\n * that you cannot load all elements into the memory at once?\n *\n */\n\n\npublic class IntersectionOfTwoArraysII350 {\n    public int[] intersect(int[] nums1, int[] nums2) {\n        if (nums1.length == 0 || nums2.length == 0) return new int[0];\n        Map<Integer, Integer> m1 = new HashMap<>();\n        for (int i=0; i<nums1.length; i++) {\n            m1.put(nums1[i], m1.getOrDefault(nums1[i], 0)+1);\n        }\n\n        Map<Integer, Integer> m2 = new HashMap<>();\n        for (int i=0; i<nums2.length; i++) {\n            m2.put(nums2[i], m2.getOrDefault(nums2[i], 0)+1);\n        }\n\n        List<Integer> res = new ArrayList<>();\n        if (m1.size() > m2.size()) {\n            Map<Integer, Integer> temp = m1;\n            m1 = m2;\n            m2 = temp;\n        }\n\n        for (Map.Entry<Integer, Integer> e: m1.entrySet()) {\n            if (m2.containsKey(e.getKey())) {\n                int minVal = Math.min(e.getValue(), m2.get(e.getKey()));\n                while (minVal > 0) {\n                    res.add(e.getKey());\n                    minVal--;\n                }\n            }\n        }\n\n        int[] arr = new int[res.size()];\n        for (int i=0; i<res.size(); i++) arr[i] = res.get(i);\n\n        return arr;\n    }\n\n\n    // solution to 3rd follow-up\n    public int[] intersect2(int[] nums1, int[] nums2) {\n        int len = Math.min(nums1.length, nums2.length);\n        int[] arr = new int[len];\n        if (len == 0) return arr;\n\n        Map<Integer, Integer> m1 = new HashMap<>();\n        for (int i=0; i<nums1.length; i++) {\n            m1.put(nums1[i], m1.getOrDefault(nums1[i], 0)+1);\n        }\n\n        int size = 0;\n        for (int i=0; i<nums2.length; i++) {\n            if (m1.containsKey(nums2[i]) && m1.get(nums2[i]) > 0) {\n                m1.put(nums2[i], m1.get(nums2[i])-1);\n                arr[size] = nums2[i];\n                size++;\n            }\n        }\n\n        return Arrays.copyOfRange(arr, 0, size);\n    }\n\n\n    public int[] intersect3(int[] nums1, int[] nums2) {\n        int len = Math.min(nums1.length, nums2.length);\n        int[] arr = new int[len];\n        if (len == 0) return arr;\n\n        Arrays.sort(nums1);\n        Arrays.sort(nums2);\n\n        int i = 0;\n        int j = 0;\n        int size = 0;\n        while (i < nums1.length && j < nums2.length) {\n            int n1 = nums1[i];\n            int n2 = nums2[j];\n            if (n1 == n2) {\n                arr[size] = n1;\n                i++;\n                j++;\n                size++;\n            } else if (n1 < n2) {\n                do {\n                    i++;\n                } while (i < nums1.length && nums1[i] == n1);\n            } else {\n                do {\n                    j++;\n                } while (j < nums2.length && nums2[j] == n2);\n            }\n\n        }\n\n        return Arrays.copyOfRange(arr, 0, size);\n    }\n\n}\n"
  },
  {
    "path": "src/IntersectionOfTwoLinkedLists160.java",
    "content": "/**\n * Write a program to find the node at which the intersection of two singly linked lists begins.\n *\n * For example, the following two linked lists:\n *\n * A:          a1 → a2\n *                    ↘\n *                      c1 → c2 → c3\n *                    ↗\n * B:     b1 → b2 → b3\n * begin to intersect at node c1.\n *\n *\n * Notes:\n *\n * If the two linked lists have no intersection at all, return null.\n * The linked lists must retain their original structure after the function returns.\n * You may assume there are no cycles anywhere in the entire linked structure.\n * Your code should preferably run in O(n) time and use only O(1) memory.\n *\n */\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) {\n *         val = x;\n *         next = null;\n *     }\n * }\n */\n\npublic class IntersectionOfTwoLinkedLists160 {\n    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {\n        int lA = 0;\n        ListNode tA = headA;\n        while (tA != null) {\n            lA++;\n            tA = tA.next;\n        }\n\n        int lB = 0;\n        ListNode tB = headB;\n        while (tB != null) {\n            lB++;\n            tB = tB.next;\n        }\n\n        if (lA < lB) {\n            for (int i=1; i<=(lB-lA); i++) headB = headB.next;\n        } else if (lB < lA) {\n            for (int i=1; i<=(lA-lB); i++) headA = headA.next;\n        }\n\n        while (headA != null && headB != null) {\n            if (headA == headB) {\n                return headA;\n            }\n            headA = headA.next;\n            headB = headB.next;\n        }\n\n        return null;\n    }\n\n\n    public ListNode getIntersectionNode2(ListNode headA, ListNode headB) {\n        if (headA == null || headB == null) return null;\n        ListNode a = headA;\n        ListNode b = headB;\n        while (a != null && b != null) {\n            if (a == b) return a;\n            a = a.next;\n            b = b.next;\n        }\n        if (a == null && b == null) return null;\n        if (a == null) {\n            a = headB;\n        } else {\n            b = headA;\n        }\n        while (a != null && b != null) {\n            a = a.next;\n            b = b.next;\n        }\n        if (a == null) {\n            a = headB;\n        } else {\n            b = headA;\n        }\n        while (a != null && b != null) {\n            if (a == b) return a;\n            a = a.next;\n            b = b.next;\n        }\n        \n        return null;\n    }\n\n    /**\n     * https://leetcode.com/problems/intersection-of-two-linked-lists/discuss/49785/Java-solution-without-knowing-the-difference-in-len!\n     *\n     * You can prove that: say A length = a + c, B length = b + c, after\n     * switching pointer, pointer A will move another b + c steps, pointer B\n     * will move a + c more steps, since a + c + b + c = b + c + a + c, it\n     * does not matter what value c is. Pointer A and B must meet after\n     * a + c + b (b + c + a) steps. If c == 0, they meet at NULL.\n     *\n     */\n    public ListNode getIntersectionNode3(ListNode headA, ListNode headB) {\n        //boundary check\n        if(headA == null || headB == null) return null;\n\n        ListNode a = headA;\n        ListNode b = headB;\n\n        //if a & b have different len, then we will stop the loop after second iteration\n        while( a != b){\n        \t//for the end of first iteration, we just reset the pointer to the head of another linkedlist\n            a = a == null? headB : a.next;\n            b = b == null? headA : b.next;\n        }\n\n        return a;\n    }\n\n\n    public ListNode getIntersectionNode4(ListNode headA, ListNode headB) {\n        if (headA == null || headB == null) return null;\n        ListNode pa = headA;\n        ListNode pb = headB;\n        while (pa != pb) {\n            pa = pa.next;\n            pb = pb.next;\n            if (pa == pb) return pa;\n            if (pa == null) pa = headB;\n            if (pb == null) pb = headA; \n        }\n        return pa;\n    }\n\n}\n"
  },
  {
    "path": "src/Interval.java",
    "content": "/**\n * Definition for an interval.\n */\n\npublic class Interval {\n    int start;\n    int end;\n    Interval() { start = 0; end = 0; }\n    Interval(int s, int e) { start = s; end = e; }\n}\n"
  },
  {
    "path": "src/InvertBinaryTree226.java",
    "content": "/**\n * Invert a binary tree.\n *\n *      4\n *    /   \\\n *   2     7\n *  / \\   / \\\n * 1   3 6   9\n *\n * to\n *\n *      4\n *    /   \\\n *   7     2\n *  / \\   / \\\n * 9   6 3   1\n *\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class InvertBinaryTree226 {\n    public TreeNode invertTree(TreeNode root) {\n        if (root == null || (root.left == null && root.right == null)) {\n            return root;\n        }\n        TreeNode left = invertTree(root.right);\n        TreeNode right = invertTree(root.left);\n        root.left = left;\n        root.right = right;\n        return root;\n    }\n}\n"
  },
  {
    "path": "src/IsGraphBipartite785.java",
    "content": "/**\n * Given an undirected graph, return true if and only if it is bipartite.\n * \n * Recall that a graph is bipartite if we can split it's set of nodes into two\n * independent subsets A and B such that every edge in the graph has one node\n * in A and another node in B.\n * \n * The graph is given in the following form: graph[i] is a list of indexes j\n * for which the edge between nodes i and j exists.  Each node is an integer\n * between 0 and graph.length - 1.  There are no self edges or parallel\n * edges: graph[i] does not contain i, and it doesn't contain any element twice.\n * \n * Example 1:\n * Input: [[1,3], [0,2], [1,3], [0,2]]\n * Output: true\n * Explanation: \n * The graph looks like this:\n * 0----1\n * |    |\n * |    |\n * 3----2\n * We can divide the vertices into two groups: {0, 2} and {1, 3}.\n * \n * Example 2:\n * Input: [[1,2,3], [0,2], [0,1,3], [0,2]]\n * Output: false\n * Explanation: \n * The graph looks like this:\n * 0----1\n * | \\  |\n * |  \\ |\n * 3----2\n * We cannot find a way to divide the set of nodes into two independent subsets.\n * \n * Note:\n * graph will have length in range [1, 100].\n * graph[i] will contain integers in range [0, graph.length - 1].\n * graph[i] will not contain i or duplicate values.\n * The graph is undirected: if any element j is in graph[i], then i will be\n * in graph[j].\n */\n\npublic class IsGraphBipartite785 {\n    public boolean isBipartite(int[][] graph) {\n        if (graph.length == 0) return true;\n        int N = graph.length;\n        int[] visited = new int[N];\n        for (int i=0; i<N; i++) {\n            if (visited[i] == 0 && !helper(graph, i, visited, 1)) return false;\n        }\n        return true;\n    }\n\n    private boolean helper(int[][] graph, int curr, int[] visited, int pre) {\n        if (visited[curr] != 0) return visited[curr] == pre;\n        visited[curr] = pre;\n        for (int next: graph[curr]) {\n            if (visited[next] == pre) return false;\n            if (visited[next] == 0) {\n                if (!helper(graph, next, visited, -pre)) return false;\n            }\n        }\n        return true;\n    }\n\n\n    public boolean isBipartite2(int[][] graph) {\n        if (graph.length == 0) return true;\n        int N = graph.length;\n        int[] visited = new int[N];\n        for (int i=0; i<N; i++) {\n            if (visited[i] == 0) {\n                Queue<Integer> q = new LinkedList<>();\n                visited[i] = 1;\n                q.add(i);\n                while (!q.isEmpty()) {\n                    int curr = q.poll();\n                    \n                    for (int next: graph[curr]) {\n                        if (visited[next] == 0) {\n                            visited[next] = - visited[curr];\n                            q.add(next);\n                        } else {\n                            if (visited[next] == visited[curr]) return false;\n                        }\n                    }\n                }\n            }\n        }\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/is-graph-bipartite/discuss/118959/JAVA-union-find-easy-solution\n     */\n    public boolean isBipartite3(int[][] graph) {\n        int n= graph.length;\n        int[] parent= new int[n];\n        for(int i=0; i<n; i++){\n            parent[i]=i;\n        }\n        for(int i=0; i<n; i++){\n            for(int j=1; j<graph[i].length; j++){\n                parent[findParent(parent,graph[i][j])]=findParent(parent,graph[i][0]);\n            }\n        }\n        for(int i=0; i<n; i++){\n            if(graph[i].length>0){\n                if(findParent(parent,i)==findParent(parent,graph[i][0])) return false;\n            }\n        }\n        \n        return true;\n        \n    }\n\n    private int findParent(int[]parent, int p){\n        if(parent[p]==p) return p;\n        parent[p]=findParent(parent, parent[p]);\n        return parent[p];\n    }\n\n}\n"
  },
  {
    "path": "src/IsSubsequence392.java",
    "content": "/**\n * Given a string s and a string t, check if s is subsequence of t.\n * \n * You may assume that there is only lower case English letters in both s and t.\n * t is potentially a very long (length ~= 500,000) string, and s is a short\n * string (<=100).\n * \n * A subsequence of a string is a new string which is formed from the original\n * string by deleting some (can be none) of the characters without disturbing\n * the relative positions of the remaining characters. (ie, \"ace\" is a\n * subsequence of \"abcde\" while \"aec\" is not).\n * \n * Example 1:\n * s = \"abc\", t = \"ahbgdc\"\n * Return true.\n * \n * Example 2:\n * s = \"axc\", t = \"ahbgdc\"\n * Return false.\n * \n * Follow up:\n * If there are lots of incoming S, say S1, S2, ... , Sk where k >= 1B, and you\n * want to check one by one to see if T has its subsequence. In this scenario,\n * how would you change your code?\n */\n\npublic class IsSubsequence392 {\n    public boolean isSubsequence(String s, String t) {\n        if (s == null && t == null) return true;\n        if (s == null || t == null) return true;\n        int lenS = s.length();\n        int lenT = t.length();\n        char[] charS = s.toCharArray();\n        char[] charT = t.toCharArray();\n        int i = 0;\n        int j = 0;\n        while (i < lenS && j < lenT) {\n            while (j < lenT && charT[j] != charS[i]) {\n                j++;\n            }\n            if (j == lenT) break;\n            j++;\n            i++;\n        }\n        return i == lenS;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/is-subsequence/discuss/87297/Java.-Only-2ms.-Much-faster-than-normal-2-pointers.\n     */\n    public boolean isSubsequence2(String s, String t) {\n        if(t.length() < s.length()) return false;\n        int prev = 0;\n        for(int i = 0; i < s.length();i++) {\n            char tempChar = s.charAt(i);\n            prev = t.indexOf(tempChar,prev);\n            if(prev == -1) return false;\n            prev++;\n        }\n        return true;\n    }\n\n    public boolean isSubsequence3(String s, String t) {\n        int i = 0;\n        int j = 0;\n        char[] chars = s.toCharArray();\n        char[] chart = t.toCharArray();\n        while (i < chars.length && j < chart.length) {\n            if (chars[i] == chart[j]) {\n                i++;\n                j++;\n            } else {\n                j++;\n            }\n        }\n        return i == chars.length;\n    }\n\n}\n"
  },
  {
    "path": "src/IslandPerimeter463.java",
    "content": "/**\n * You are given a map in form of a two-dimensional integer grid where 1\n * represents land and 0 represents water. Grid cells are connected\n * horizontally/vertically (not diagonally). The grid is completely surrounded\n * by water, and there is exactly one island (i.e., one or more connected land\n * cells). The island doesn't have \"lakes\" (water inside that isn't connected\n * to the water around the island). One cell is a square with side length 1.\n * The grid is rectangular, width and height don't exceed 100. Determine the\n * perimeter of the island.\n * \n * Example:\n * \n * [[0,1,0,0],\n *  [1,1,1,0],\n *  [0,1,0,0],\n *  [1,1,0,0]]\n * \n * Answer: 16\n * Explanation: The perimeter is the 16 yellow stripes in the image below:\n *    https://leetcode.com/static/images/problemset/island.png\n */\n\n\npublic class IslandPerimeter463 {\n    private static int[][] dir = new int[][]{{-1, 0}, {0, 1}, {1, 0}, {0, -1}};\n    public int islandPerimeter(int[][] grid) {\n        if (grid == null || grid.length == 0 || grid[0].length == 0) return 0;\n        int res = 0;\n        for (int i=0; i<grid.length; i++) {\n            for (int j=0; j<grid[0].length; j++) {\n                if (grid[i][j] == 1) {\n                    res += perimeter(grid, i, j, grid.length, grid[0].length);\n                }\n            }\n        }\n        return res;\n    }\n\n    private int perimeter(int[][] grid, int i, int j, int n, int m) {\n        int res = 0;\n        for (int[] d: dir) {\n            int x = i + d[0];\n            int y = j + d[1];\n            if (x < 0 || x >= n || y < 0 || y >= m || grid[x][y] == 0) {\n                res++;\n            }\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/island-perimeter/discuss/95001/clear-and-easy-java-solution\n     */\n    public int islandPerimeter2(int[][] grid) {\n        int islands = 0, neighbours = 0;\n\n        for (int i = 0; i < grid.length; i++) {\n            for (int j = 0; j < grid[i].length; j++) {\n                if (grid[i][j] == 1) {\n                    islands++; // count islands\n                    if (i < grid.length - 1 && grid[i + 1][j] == 1) neighbours++; // count down neighbours\n                    if (j < grid[i].length - 1 && grid[i][j + 1] == 1) neighbours++; // count right neighbours\n                }\n            }\n        }\n\n        return islands * 4 - neighbours * 2;\n    }\n\n}\n"
  },
  {
    "path": "src/IsomorphicStrings205.java",
    "content": "/**\n * Given two strings s and t, determine if they are isomorphic.\n * \n * Two strings are isomorphic if the characters in s can be replaced to get t.\n * \n * All occurrences of a character must be replaced with another character\n * while preserving the order of characters. No two characters may map to the\n * same character but a character may map to itself.\n * \n * Example 1:\n * Input: s = \"egg\", t = \"add\"\n * Output: true\n * \n * Example 2:\n * Input: s = \"foo\", t = \"bar\"\n * Output: false\n * \n * Example 3:\n * Input: s = \"paper\", t = \"title\"\n * Output: true\n * \n * Note:\n * You may assume both s and t have the same length.\n */\n\npublic class IsomorphicStrings205 {\n    public boolean isIsomorphic(String s, String t) {\n        if (s == null && t == null) return true;\n        if (s == null || t == null || s.length() != t.length()) return false;\n    \n        int N = s.length();\n        char[] charS = s.toCharArray();\n        char[] charT = t.toCharArray();\n        Map<Character, Character> map = new HashMap<>();\n        for (int i=0; i<N; i++) {\n            if (map.containsKey(charS[i])) {\n                if (map.get(charS[i]) != charT[i]) return false; \n            } else {\n                if (map.values().contains(charT[i])) {\n                    return false;\n                } else {\n                    map.put(charS[i], charT[i]);\n                }\n            }\n        }\n        return true;\n    }\n\n\n    public boolean isIsomorphic2(String s1, String s2) {\n        int[] m = new int[512];\n        for (int i = 0; i < s1.length(); i++) {\n            if (m[s1.charAt(i)] != m[s2.charAt(i)+256]) return false;\n            m[s1.charAt(i)] = m[s2.charAt(i)+256] = i+1;\n        }\n        return true;\n    }\n\n\n    public boolean isIsomorphic3(String sString, String tString) {\n        char[] s = sString.toCharArray();\n        char[] t = tString.toCharArray();\n\n        int length = s.length;\n        if(length != t.length) return false;\n\n        char[] sm = new char[256];\n        char[] tm = new char[256];\n\n        for(int i=0; i<length; i++){\n            char sc = s[i];\n            char tc = t[i];\n            if(sm[sc] == 0 && tm[tc] == 0){\n                sm[sc] = tc;\n                tm[tc] = sc;\n            }else{\n                if(sm[sc] != tc || tm[tc] != sc){\n                    return false;\n                }\n            }\n        }\n        return true;\n    }\n\n\n    public boolean isIsomorphic4(String sString, String tString) {\n        return encode(sString.toCharArray()) == encode(tString.toCharArray());\n    }\n\n    private int encode(char[] chars) {\n        int[] map = new int[256];\n        int res = 0;\n        int id = 1;\n        for (int i=1; i<=chars.length; i++) {\n            char ch = chars[i-1];\n            if (map[ch] == 0) {\n                map[ch] = id;\n                id++;\n            }\n            res += map[ch] * i;\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/JewelsAndStones771.java",
    "content": "/**\n * You're given strings J representing the types of stones that are jewels,\n * and S representing the stones you have.  Each character in S is a type of\n * stone you have.  You want to know how many of the stones you have are also\n * jewels.\n * \n * The letters in J are guaranteed distinct, and all characters in J and S\n * are letters. Letters are case sensitive, so \"a\" is considered a different\n * type of stone from \"A\".\n * \n * Example 1:\n * Input: J = \"aA\", S = \"aAAbbbb\"\n * Output: 3\n * \n * Example 2:\n * Input: J = \"z\", S = \"ZZ\"\n * Output: 0\n * \n * Note:\n * S and J will consist of letters and have length at most 50.\n * The characters in J are distinct.\n */\n\npublic class JewelsAndStones771 {\n    public int numJewelsInStones(String J, String S) {\n        boolean[] map = new boolean[256];\n        for (char c: J.toCharArray()) {\n            map[c] = true;\n        }\n        int res = 0;\n        for (char c: S.toCharArray()) {\n            if (map[c]) res++;\n        }\n        return res;\n    }\n}\n"
  },
  {
    "path": "src/JudgeRouteCircle657.java",
    "content": "/**\n * Initially, there is a Robot at position (0, 0). Given a sequence of its\n * moves, judge if this robot makes a circle, which means it moves back to\n * the original place.\n * \n * The move sequence is represented by a string. And each move is represent by\n * a character. The valid robot moves are R (Right), L (Left), U (Up) and\n * D (down). The output should be true or false representing whether the robot\n * makes a circle.\n * \n * Example 1:\n * Input: \"UD\"\n * Output: true\n * \n * Example 2:\n * Input: \"LL\"\n * Output: false\n */\n\n\npublic class JudgeRouteCircle657 {\n    public boolean judgeCircle(String s) {\n        if (s == null || s.length() == 0) return true;\n        char[] moves = s.toCharArray();\n        int x = 0;\n        int y = 0;\n        for (int i=0; i<s.length(); i++) {\n            switch (moves[i]) {\n                case 'U': y--; break;\n                case 'D': y++; break;\n                case 'L': x--; break;\n                case 'R': x++;\n            }\n        }\n        return x == 0 && y == 0;\n    }\n}\n"
  },
  {
    "path": "src/JumpGame55.java",
    "content": "/**\n * Given an array of non-negative integers, you are initially positioned at the\n * first index of the array.\n *\n * Each element in the array represents your maximum jump length at that position.\n *\n * Determine if you are able to reach the last index.\n *\n * For example:\n * A = [2,3,1,1,4], return true.\n *\n * A = [3,2,1,0,4], return false.\n */\n\n\n\npublic class JumpGame55 {\n    public boolean canJump(int[] nums) {\n        int length = nums.length;\n        if (length == 0 || length == 1 ) {\n            return true;\n        }\n\n        boolean[] dp = new boolean[length];\n        dp[0] = true;\n\n        for (int i = 1; i <= length - 1; i++) {\n            for (int j = i - 1; j >= 0; j--) {\n                dp[i] = dp[j] && (nums[j] >= i - j);\n                if (dp[i]) {\n                    break;\n                }\n            }\n        }\n\n        return dp[length - 1];\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/3443/simplest-o-n-solution-with-constant-space\n     */\n    public boolean canJump2(int[] nums) {\n        return canJumpHelper(nums, nums.length);\n    }\n\n    boolean canJumpHelper(int A[], int n) {\n        int last=n-1,i,j;\n        for(i=n-2;i>=0;i--){\n            if(i+A[i]>=last)last=i;\n        }\n        return last<=0;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/7661/java-solution-easy-to-understand\n     */\n    public boolean canJump3(int[] A) {\n        int max = 0;\n        for(int i=0;i<A.length;i++){\n            if(i>max) {return false;}\n            max = Math.max(A[i]+i,max);\n        }\n        return true;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/36578/java-98-percentile-solution/7\n     */\n    public boolean canJump4(int[] nums) {\n       if(nums.length < 2) return true;\n\n       for(int curr = nums.length-2; curr>=0;curr--){\n           if(nums[curr] == 0){\n               int neededJumps = 1;\n               while(neededJumps > nums[curr]){\n                   neededJumps++;\n                   curr--;\n                   if(curr < 0) return false;\n               }\n           }\n       }\n       return true;\n    }\n}\n"
  },
  {
    "path": "src/JumpGameII45.java",
    "content": "/**\n * Given an array of non-negative integers, you are initially positioned at\n * the first index of the array.\n * \n * Each element in the array represents your maximum jump length at that position.\n * \n * Your goal is to reach the last index in the minimum number of jumps.\n * \n * Example:\n * Input: [2,3,1,1,4]\n * Output: 2\n * Explanation: The minimum number of jumps to reach the last index is 2.\n * Jump 1 step from index 0 to 1, then 3 steps to the last index.\n * \n * Note:\n * You can assume that you can always reach the last index.\n */\n\npublic class JumpGameII45 {\n    public int jump(int[] nums) {\n        int N = nums.length;\n        int[] dp = new int[N];\n        Arrays.fill(dp, Integer.MAX_VALUE);\n        dp[0] = 0;\n        for (int i=0; i<N-1; i++) {\n            int farest = Math.min(i+nums[i], N-1);\n            for (int j=i+1; j<=farest; j++) {\n                dp[j] = Math.min(dp[j], dp[i] + 1);\n            }\n        }\n        return dp[N-1];\n    }\n\n\n    /**\n     * https://leetcode.com/problems/jump-game-ii/discuss/18014/Concise-O(n)-one-loop-JAVA-solution-based-on-Greedy\n     */\n    public int jump2(int[] A) {\n      int jumps = 0, curEnd = 0, curFarthest = 0;\n      for (int i = 0; i < A.length - 1; i++) {\n        curFarthest = Math.max(curFarthest, i + A[i]);\n        if (i == curEnd) {\n          jumps++;\n          curEnd = curFarthest;\n        }\n      }\n      return jumps;\n    }\n\n}\n"
  },
  {
    "path": "src/KEmptySlots683.java",
    "content": "/**\n * There is a garden with N slots. In each slot, there is a flower. The N\n * flowers will bloom one by one in N days. In each day, there will be exactly\n * one flower blooming and it will be in the status of blooming since then.\n * \n * Given an array flowers consists of number from 1 to N. Each number in the\n * array represents the place where the flower will open in that day.\n * \n * For example, flowers[i] = x means that the unique flower that blooms at day\n * i will be at position x, where i and x will be in the range from 1 to N.\n * \n * Also given an integer k, you need to output in which day there exists two\n * flowers in the status of blooming, and also the number of flowers between\n * them is k and these flowers are not blooming.\n * \n * If there isn't such day, output -1.\n * \n * Example 1:\n * Input: \n * flowers: [1,3,2]\n * k: 1\n * Output: 2\n * Explanation: In the second day, the first and the third flower have become blooming.\n * \n * Example 2:\n * Input: \n * flowers: [1,2,3]\n * k: 1\n * Output: -1\n * \n * Note:\n * The given array will be in the range [1, 20000].\n */\n\n\npublic class KEmptySlots683 {\n    public int kEmptySlots(int[] flowers, int k) {\n        int n = flowers.length;\n        if (n <= 1) return -1;\n        int[] slot2days = new int[n+1];\n        for (int i=0; i<n; i++) {\n            slot2days[flowers[i]] = i+1;\n        }\n\n        int i = n-1;\n        int j = n;\n        int min = Integer.MAX_VALUE;\n        int ans = Integer.MAX_VALUE;\n        while (i > 0) {\n            if (slot2days[i] < slot2days[j]) {\n                if ((j - i - 1) == k) ans = Math.min(ans, Math.max(slot2days[i], slot2days[j]));\n                j--;\n                i = j-1;\n                min = Integer.MAX_VALUE;\n            } else if (slot2days[i] < min && slot2days[i] > slot2days[j]) {\n                if ((j - i - 1) == k) ans = Math.min(ans, Math.max(slot2days[i], slot2days[j]));\n                min = slot2days[i];\n                i--;\n            } else {\n                i--;\n            }\n            if ((j - i - 1) > k) {\n                j--;\n                i = j-1;\n                min = Integer.MAX_VALUE;\n            }\n        }\n        \n        return ans < Integer.MAX_VALUE ? ans : -1;\n    }\n\n    /**\n     * https://leetcode.com/problems/k-empty-slots/solution/\n     */\n    public int kEmptySlots2(int[] flowers, int k) {\n        int[] days = new int[flowers.length];\n        for (int i = 0; i < flowers.length; i++) {\n            days[flowers[i] - 1] = i + 1;\n        }\n\n        int ans = Integer.MAX_VALUE;\n        int left = 0, right = k+1;\n\n        search: while (right < days.length) {\n            for (int i = left+1; i < right; ++i) {\n                if (days[i] < days[left] || days[i] < days[right]) {\n                    left = i;\n                    right = i + k + 1;\n                    continue search;\n                }\n            }\n            ans = Math.min(ans, Math.max(days[left], days[right]));\n            left = right;\n            right = left + k + 1;\n        }\n\n        return ans < Integer.MAX_VALUE ? ans : -1;\n    }\n\n}\n"
  },
  {
    "path": "src/KMP.java",
    "content": "/**\n * \n */\n\npublic class KMP {\n\n    /**\n     * https://www.jianshu.com/p/e2bd1ee482c3\n     */\n    public static int find(String txt, String pat, int[] next) {\n        int M = txt.length();\n        int N = pat.length();\n        int i = 0;\n        int j = 0;\n        while (i < M && j < N) {\n            if (j == -1 || txt.charAt(i) == pat.charAt(j)) {\n                i++;\n                j++;\n            } else {\n                j = next[j];\n            }\n            if (j == N) return i - j;\n        }\n        return -1;\n    }\n\n    public static int[] getNext(String pat) {\n        int N = pat.length();\n        int[] next = new int[N];\n        next[0] = -1;\n        int k = -1;\n        int j = 0;\n        while (j < N - 1) {\n            if (k == -1 || pat.charAt(j) == pat.charAt(k)) {\n                k++;\n                j++;\n                next[j] = k;\n            } else {\n                k = next[k];\n            } \n        }\n        return next;\n    }\n\n\n    public static void main(String[] args) {\n        String txt = \"BBC ABCDAB CDABABCDABCDABDE\";\n        String pat = \"ABCDABD\";\n        int[] next = getNext(pat);\n        System.out.println(find(txt, pat, next));\n    }\n\n}\n"
  },
  {
    "path": "src/KeysAndRooms841.java",
    "content": "/**\n * There are N rooms and you start in room 0.  Each room has a distinct number\n * in 0, 1, 2, ..., N-1, and each room may have some keys to access the next\n * room. \n * \n * Formally, each room i has a list of keys rooms[i], and each key rooms[i][j]\n * is an integer in [0, 1, ..., N-1] where N = rooms.length.  A key\n * rooms[i][j] = v opens the room with number v.\n * \n * Initially, all the rooms start locked (except for room 0). \n * \n * You can walk back and forth between rooms freely.\n * \n * Return true if and only if you can enter every room.\n * \n * Example 1:\n * Input: [[1],[2],[3],[]]\n * Output: true\n * Explanation:  \n * We start in room 0, and pick up key 1.\n * We then go to room 1, and pick up key 2.\n * We then go to room 2, and pick up key 3.\n * We then go to room 3.  Since we were able to go to every room, we return true.\n * \n * Example 2:\n * Input: [[1,3],[3,0,1],[2],[0]]\n * Output: false\n * Explanation: We can't enter the room with number 2.\n * \n * Note:\n * 1 <= rooms.length <= 1000\n * 0 <= rooms[i].length <= 1000\n * The number of keys in all rooms combined is at most 3000.\n */\n\npublic class KeysAndRooms841 {\n    public boolean canVisitAllRooms(List<List<Integer>> rooms) {\n        int N  = rooms.size();\n        Set<Integer> visited = new HashSet<>();\n\n        Queue<Integer> q = new LinkedList<>();\n        q.add(0);\n        while (!q.isEmpty()) {\n            int curr = q.poll();\n            if (visited.contains(curr)) continue;\n            visited.add(curr);\n            for (Integer next: rooms.get(curr)) {\n                if (!visited.contains(next)) {\n                    q.add(next);\n                }\n            }\n        }\n\n        return visited.size() == N;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/keys-and-rooms/discuss/133895/Clean-Code\n     */\n    HashSet<Integer> enteredRooms = new HashSet<>();\n\n    public boolean canVisitAllRooms2(List<List<Integer>> rooms) {\n        enterRoom(0, rooms);\n        return enteredRooms.size() == rooms.size();\n    }\n    \n    private void enterRoom(int roomId, List<List<Integer>> rooms) {\n        enteredRooms.add(roomId);\n        List<Integer> keysInRoom = rooms.get(roomId);\n        for (int key: keysInRoom)\n            if (!enteredRooms.contains(key))\n                enterRoom(key, rooms);\n    }\n\n}\n"
  },
  {
    "path": "src/KillProcess582.java",
    "content": "/**\n * Given n processes, each process has a unique PID (process id) and its PPID\n * (parent process id).\n * \n * Each process only has one parent process, but may have one or more children\n * processes. This is just like a tree structure. Only one process has PPID\n * that is 0, which means this process has no parent process. All the PIDs will\n * be distinct positive integers.\n * \n * We use two list of integers to represent a list of processes, where the\n * first list contains PID for each process and the second list contains the\n * corresponding PPID.\n * \n * Now given the two lists, and a PID representing a process you want to kill,\n * return a list of PIDs of processes that will be killed in the end. You\n * should assume that when a process is killed, all its children processes will\n * be killed. No order is required for the final answer.\n * \n * Example 1:\n * Input: \n * pid =  [1, 3, 10, 5]\n * ppid = [3, 0, 5, 3]\n * kill = 5\n * Output: [5,10]\n * Explanation: \n *            3\n *          /   \\\n *         1     5\n *              /\n *             10\n * Kill 5 will also kill 10.\n * \n * Note:\n * The given kill id is guaranteed to be one of the given PIDs.\n * n >= 1.\n */\n\npublic class KillProcess582 {\n    public List<Integer> killProcess(List<Integer> pid, List<Integer> ppid, int kill) {\n        TreeNode root = constructTree(pid, ppid);\n        List<Integer> res = new ArrayList<>();\n        findNode(root, kill, res);\n        return res;\n    }\n\n    private TreeNode constructTree(List<Integer> pid, List<Integer> ppid) {\n        Map<Integer, TreeNode> map = new HashMap<>();\n        int size = pid.size();\n        TreeNode root = null;\n        for (int i=0; i<size; i++) {\n            int curr = pid.get(i);\n            TreeNode currNode = null;\n            if (!map.containsKey(curr)) {\n                currNode = new TreeNode(curr);\n                map.put(curr, currNode);\n            } else {\n                currNode = map.get(curr);\n            }\n            int parent = ppid.get(i);\n            if (parent == 0) {\n                root = currNode;\n            } else {\n                TreeNode parentNode = null;\n                if (!map.containsKey(parent)) {\n                    parentNode = new TreeNode(parent);\n                    map.put(parent, parentNode);\n                } else {\n                    parentNode = map.get(parent);\n                }\n                if (!parentNode.children.containsKey(curr)) {\n                    parentNode.children.put(curr, currNode);\n                }\n            }\n        }\n        return root;\n    }\n\n    // BFS\n    private void findNode(TreeNode root, int kill, List<Integer> res) {\n        Queue<TreeNode> q = new LinkedList<>();\n        q.add(root);\n        while (!q.isEmpty()) {\n            TreeNode currNode = q.poll();\n            if (currNode.value == kill) {\n                gatherResults(currNode, res);\n                return;\n            }\n            for (TreeNode child: currNode.children.values()) {\n                q.add(child);\n            }\n        }\n    }\n\n    private void gatherResults(TreeNode found, List<Integer> res) {\n        if (found == null) return;\n        res.add(found.value);\n        for (TreeNode child: found.children.values()) {\n            gatherResults(child, res);\n        }\n    }\n\n    class TreeNode {\n        int value;\n        Map<Integer, TreeNode> children = new HashMap<>();\n        TreeNode(int x) {\n            this.value = x;\n        }\n    }\n\n\n    public List<Integer> killProcess2(List<Integer> pid, List<Integer> ppid, int kill) {\n        TreeNode found = findKill(pid, ppid, kill);\n        List<Integer> res = new ArrayList<>();\n        gatherResults(found, res);\n        return res;\n    }\n\n    private TreeNode findKill(List<Integer> pid, List<Integer> ppid, int kill) {\n        Map<Integer, TreeNode> map = new HashMap<>();\n        int size = pid.size();\n        TreeNode found = null;\n        for (int i=0; i<size; i++) {\n            int curr = pid.get(i);\n            TreeNode currNode = null;\n            if (!map.containsKey(curr)) {\n                currNode = new TreeNode(curr);\n                map.put(curr, currNode);\n            } else {\n                currNode = map.get(curr);\n            }\n            if (curr == kill) {\n                found = currNode;\n            }\n            int parent = ppid.get(i);\n            if (parent != 0) {\n                TreeNode parentNode = null;\n                if (!map.containsKey(parent)) {\n                    parentNode = new TreeNode(parent);\n                    map.put(parent, parentNode);\n                } else {\n                    parentNode = map.get(parent);\n                }\n                if (!parentNode.children.containsKey(curr)) {\n                    parentNode.children.put(curr, currNode);\n                }\n            }\n        }\n        return found;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/kill-process/solution/\n     */\n    class Node {\n        int val;\n        List < Node > children = new ArrayList < > ();\n    }\n    public List < Integer > killProcess3(List < Integer > pid, List < Integer > ppid, int kill) {\n        HashMap < Integer, Node > map = new HashMap < > ();\n        for (int id: pid) {\n            Node node = new Node();\n            node.val = id;\n            map.put(id, node);\n        }\n        for (int i = 0; i < ppid.size(); i++) {\n            if (ppid.get(i) > 0) {\n                Node par = map.get(ppid.get(i));\n                par.children.add(map.get(pid.get(i)));\n            }\n        }\n        List < Integer > l = new ArrayList < > ();\n        l.add(kill);\n        getAllChildren(map.get(kill), l);\n        return l;\n    }\n    public void getAllChildren(Node pn, List < Integer > l) {\n        for (Node n: pn.children) {\n            l.add(n.val);\n            getAllChildren(n, l);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/kill-process/discuss/103176/Java-Solution-HashMap\n     */\n    public List<Integer> killProcess4(List<Integer> pid, List<Integer> ppid, int kill) {\n        // Kill root, return all nodes\n        if (kill == 0) return pid;\n        \n        int n = pid.size();\n        Map<Integer, Set<Integer>> tree = new HashMap<>();\n        for (int i = 0; i < n; i++) {\n            if (!tree.containsKey(ppid.get(i))) {\n                tree.put(ppid.get(i), new HashSet<>());\n            }\n            tree.get(ppid.get(i)).add(pid.get(i));\n        }\n        \n        List<Integer> result = new ArrayList<>();\n        traverse(tree, result, kill);\n        \n        return result;\n    }\n    \n    private void traverse(Map<Integer, Set<Integer>> tree, List<Integer> result, int pid) {\n        result.add(pid);\n        if (!tree.containsKey(pid)) {\n            return;\n        }\n        \n        for (Integer child : tree.get(pid)) {\n            traverse(tree, result, child);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/kill-process/solution/\n     */\n    public List < Integer > killProcess5(List < Integer > pid, List < Integer > ppid, int kill) {\n        HashMap < Integer, List < Integer >> map = new HashMap < > ();\n        for (int i = 0; i < ppid.size(); i++) {\n            if (ppid.get(i) > 0) {\n                List < Integer > l = map.getOrDefault(ppid.get(i), new ArrayList < Integer > ());\n                l.add(pid.get(i));\n                map.put(ppid.get(i), l);\n            }\n        }\n        Queue < Integer > queue = new LinkedList < > ();\n        List < Integer > l = new ArrayList < > ();\n        queue.add(kill);\n        while (!queue.isEmpty()) {\n            int r = queue.remove();\n            l.add(r);\n            if (map.containsKey(r))\n                for (int id: map.get(r))\n                    queue.add(id);\n        }\n        return l;\n    }\n\n}\n"
  },
  {
    "path": "src/KokoEatingBananas875.java",
    "content": "/**\n * Koko loves to eat bananas.  There are N piles of bananas, the i-th pile has\n * piles[i] bananas.  The guards have gone and will come back in H hours.\n * \n * Koko can decide her bananas-per-hour eating speed of K.  Each hour, she\n * chooses some pile of bananas, and eats K bananas from that pile. If the\n * pile has less than K bananas, she eats all of them instead, and won't eat\n * any more bananas during this hour.\n * \n * Koko likes to eat slowly, but still wants to finish eating all the bananas\n * before the guards come back.\n * \n * Return the minimum integer K such that she can eat all the bananas within H hours.\n * \n * Example 1:\n * Input: piles = [3,6,7,11], H = 8\n * Output: 4\n * \n * Example 2:\n * Input: piles = [30,11,23,4,20], H = 5\n * Output: 30\n * \n * Example 3:\n * Input: piles = [30,11,23,4,20], H = 6\n * Output: 23 \n * \n * Note:\n * 1 <= piles.length <= 10^4\n * piles.length <= H <= 10^9\n * 1 <= piles[i] <= 10^9\n */\n\npublic class KokoEatingBananas875 {\n    public int minEatingSpeed(int[] piles, int H) {\n        int lo = 1;\n        int hi = Integer.MAX_VALUE - 1;\n        while (lo < hi) {\n            int mid = (lo + hi) / 2;\n            int h = countHours(piles, mid);\n            if (h <= H) hi = mid;\n            else lo = mid + 1;\n        }\n        return lo;\n    }\n\n    private int countHours(int[] piles, int K) {\n        int h = 0;\n        for (int i=0; i<piles.length; i++) {\n            h += piles[i] / K + (piles[i] % K == 0 ? 0 : 1);\n        }\n        return h;\n    }\n\n}\n"
  },
  {
    "path": "src/KthLargestElementInAnArray215.java",
    "content": "/**\n * Find the kth largest element in an unsorted array. Note that it is the kth\n * largest element in the sorted order, not the kth distinct element.\n *\n * For example,\n * Given [3,2,1,5,6,4] and k = 2, return 5.\n *\n * Note:\n * You may assume k is always valid, 1 ≤ k ≤ array's length.\n */\n\n\npublic class KthLargestElementInAnArray215 {\n    public int findKthLargest(int[] nums, int k) {\n        Arrays.sort(nums);\n        return nums[nums.length - k];\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/14597/solution-explained\n     */\n    public int findKthLargest2(int[] nums, int k) {\n\n        final PriorityQueue<Integer> pq = new PriorityQueue<>();\n        for(int val : nums) {\n            pq.offer(val);\n\n            if(pq.size() > k) {\n                pq.poll();\n            }\n        }\n        return pq.peek();\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/14597/solution-explained\n     */\n    public int findKthLargest3(int[] nums, int k) {\n\n        k = nums.length - k;\n        int lo = 0;\n        int hi = nums.length - 1;\n        while (lo < hi) {\n            final int j = partition(nums, lo, hi);\n            if(j < k) {\n                lo = j + 1;\n            } else if (j > k) {\n                hi = j - 1;\n            } else {\n                break;\n            }\n        }\n        return nums[k];\n    }\n\n    private int partition(int[] a, int lo, int hi) {\n\n        int i = lo;\n        int j = hi + 1;\n        while(true) {\n            while(i < hi && less(a[++i], a[lo]));\n            while(j > lo && less(a[lo], a[--j]));\n            if(i >= j) {\n                break;\n            }\n            exch(a, i, j);\n        }\n        exch(a, lo, j);\n        return j;\n    }\n\n    private void exch(int[] a, int i, int j) {\n        final int tmp = a[i];\n        a[i] = a[j];\n        a[j] = tmp;\n    }\n\n    private boolean less(int v, int w) {\n        return v < w;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/14597/solution-explained\n     */\n    public int findKthLargest4(int[] nums, int k) {\n\n        shuffle(nums);\n        k = nums.length - k;\n        int lo = 0;\n        int hi = nums.length - 1;\n        while (lo < hi) {\n            final int j = partition(nums, lo, hi);\n            if(j < k) {\n                lo = j + 1;\n            } else if (j > k) {\n                hi = j - 1;\n            } else {\n                break;\n            }\n        }\n        return nums[k];\n    }\n\n    private void shuffle(int a[]) {\n        final Random random = new Random();\n        for(int ind = 1; ind < a.length; ind++) {\n            final int r = random.nextInt(ind + 1);\n            exch(a, ind, r);\n        }\n    }\n    \n\n    public int findKthLargest5(int[] nums, int k) {\n        int min = Integer.MAX_VALUE;\n        int max = Integer.MIN_VALUE;\n        for (int n: nums) {\n            min = Math.min(min, n);\n            max = Math.max(max, n);\n        }\n        if (min == max) return min;\n\n        while (min < max) {\n            int mid = min + (max - min) / 2;\n            int c = count(nums, mid);\n            if (c >= k) {\n                min = mid + 1;\n            } else {\n                max = mid;\n            }\n        }\n        return min;\n    }\n\n    private int count(int[] nums, int mid) {\n        int res = 0;\n        for (int n: nums) {\n            if (n > mid) res++;\n        }\n        return res;\n    }\n\n    public int findKthLargest6(int[] nums, int k) {\n        int len = nums.length;\n        \n        int lo = 0;\n        int hi = len - 1;\n        while (lo < hi) {\n            int p = partition2(nums, lo, hi);\n            if (p == (len - k)) return nums[p];\n            if (p > (len - k)) {\n                hi = p - 1;\n            } else {\n                lo = p + 1;\n            }\n        }\n        \n        return nums[lo];\n    }\n\n    private int partition2(int[] nums, int lo, int hi) {\n        if (lo == hi) return lo;\n        \n        int slow = lo+1;\n        int fast = lo+1;\n        while (fast <= hi) {\n            if (nums[fast] < nums[lo]) {\n                swap(nums, slow, fast);\n                slow++;\n            }\n            fast++;\n        }\n        swap(nums, lo, slow-1);\n        return slow-1;\n    }\n    \n    private void swap(int[] nums, int i, int j) {\n        if (i == j) return ;\n        int temp = nums[i];\n        nums[i] = nums[j];\n        nums[j] = temp;\n    }\n\n}\n"
  },
  {
    "path": "src/KthSmallestElementInABST230.java",
    "content": "/**\n * Given a binary search tree, write a function kthSmallest to find the kth\n * smallest element in it.\n *\n * Note:\n * You may assume k is always valid, 1 ≤ k ≤ BST's total elements.\n *\n * Follow up:\n * What if the BST is modified (insert/delete operations) often and you need to\n * find the kth smallest frequently? How would you optimize the kthSmallest\n * routine?\n *\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\n\npublic class KthSmallestElementInABST230 {\n    public int kthSmallest(TreeNode root, int k) {\n        Stack<Integer> st = new Stack<>();\n        kthSmallest(root, k, st);\n        return st.pop();\n    }\n\n    public void kthSmallest(TreeNode root, int k, Stack<Integer> st) {\n        if (root == null) return;\n\n        kthSmallest(root.left, k, st);\n        if (st.size() == k) return;\n\n        st.push(root.val);\n        if (st.size() == k) return;\n\n        kthSmallest(root.right, k, st);\n    }\n\n\n    public int kthSmallest2(TreeNode root, int k) {\n        int[] i = new int[]{0, 0};\n        kthSmallest(root, k, i);\n        return i[1];\n    }\n\n    public void kthSmallest(TreeNode root, int k, int[] i) {\n        if (root.left != null) kthSmallest(root.left, k, i);\n        if (i[0] == k) return ;\n\n        i[0] = i[0] + 1;\n        i[1] = root.val;\n        if (i[0] == k) return;\n\n        if (root.right != null) kthSmallest(root.right, k, i);\n    }\n\n\n    public int kthSmallest3(TreeNode root, int k) {\n        int l = kth(root.left);\n        if (l >= k) {\n            return kthSmallest3(root.left, k);\n        } else if (l + 1 == k) {\n            return root.val;\n        } else {\n            return kthSmallest3(root.right, k-l-1);\n        }\n    }\n\n    public int kth(TreeNode root) {\n        if (root == null) return 0; \n        return kth(root.left) + kth(root.right) + 1;\n    }\n\n\n}\n"
  },
  {
    "path": "src/KthSmallestElementInASortedMatrix378.java",
    "content": "/**\n * Given a n x n matrix where each of the rows and columns are sorted in\n * ascending order, find the kth smallest element in the matrix.\n *\n * Note that it is the kth smallest element in the sorted order, not the\n * kth distinct element.\n *\n * Example:\n *\n * matrix = [\n *    [ 1,  5,  9],\n *    [10, 11, 13],\n *    [12, 13, 15]\n * ],\n * k = 8,\n *\n * return 13.\n *\n * Note:\n * You may assume k is always valid, 1 ≤ k ≤ n2.\n *\n */\n\n\npublic class KthSmallestElementInASortedMatrix378 {\n    /**\n     * https://discuss.leetcode.com/topic/52948/share-my-thoughts-and-clean-java-code\n     *\n     * Binary Search: The key point for any binary search is to figure out the\n     * \"Search Space\". For me, I think there are two kind of \"Search Space\" --\n     * index and range(the range from the smallest number to the biggest number).\n     * Most usually, when the array is sorted in one direction, we can use index\n     * as \"search space\", when the array is unsorted and we are going to find a\n     * specific number, we can use \"range\".\n     *\n     * The reason why we did not use index as \"search space\" for this problem\n     * is the matrix is sorted in two directions, we can not find a linear way\n     * to map the number and its index.\n     *\n     */\n    public int kthSmallest(int[][] matrix, int k) {\n        int lo = matrix[0][0], hi = matrix[matrix.length - 1][matrix[0].length - 1];\n        while(lo < hi) {\n            int mid = lo + (hi - lo) / 2;\n            int count = 0,  j = matrix[0].length - 1;\n            for(int i = 0; i < matrix.length; i++) {\n                while(j >= 0 && matrix[i][j] > mid) j--;\n                count += (j + 1);\n            }\n            if(count < k) lo = mid + 1;\n            else hi = mid;\n        }\n        return lo;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/52948/share-my-thoughts-and-clean-java-code\n     *\n     * Heap:\n     *   1. Build a minHeap of elements from the first row.\n     *   2. Do the following operations k-1 times :\n     *      Every time when you poll out the root(Top Element in Heap), you need\n     *      to know the row number and column number of that element(so we can\n     *      create a tuple class here), replace that root with the next element\n     *      from the same column.\n     *\n     */\n    public int kthSmallest2(int[][] matrix, int k) {\n        int n = matrix.length;\n        PriorityQueue<Tuple> pq = new PriorityQueue<Tuple>();\n        for(int j = 0; j <= n-1; j++) pq.offer(new Tuple(0, j, matrix[0][j]));\n        for(int i = 0; i < k-1; i++) {\n            Tuple t = pq.poll();\n            if(t.x == n-1) continue;\n            pq.offer(new Tuple(t.x+1, t.y, matrix[t.x+1][t.y]));\n        }\n        return pq.poll().val;\n    }\n\n    class Tuple implements Comparable<Tuple> {\n        int x, y, val;\n        public Tuple (int x, int y, int val) {\n            this.x = x;\n            this.y = y;\n            this.val = val;\n        }\n\n        @Override\n        public int compareTo (Tuple that) {\n            return this.val - that.val;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/KthSmallestPrimeFraction786.java",
    "content": "/**\n * A sorted list A contains 1, plus some number of primes. Then, for every p < q\n * in the list, we consider the fraction p/q.\n * \n * What is the K-th smallest fraction considered?  Return your answer as an\n * array of ints, where answer[0] = p and answer[1] = q.\n * \n * Examples:\n * Input: A = [1, 2, 3, 5], K = 3\n * Output: [2, 5]\n * Explanation:\n * The fractions to be considered in sorted order are:\n * 1/5, 1/3, 2/5, 1/2, 3/5, 2/3.\n * The third fraction is 2/5.\n * \n * Input: A = [1, 7], K = 1\n * Output: [1, 7]\n * \n * Note:\n * A will have length between 2 and 2000.\n * Each A[i] will be between 1 and 30000.\n * K will be between 1 and A.length * (A.length - 1) / 2.\n */\n\n/**\n * https://leetcode.com/problems/k-th-smallest-prime-fraction/discuss/115819/Summary-of-solutions-for-problems-%22reducible%22-to-LeetCode-378\n */\npublic class KthSmallestPrimeFraction786 {\n    public int[] kthSmallestPrimeFraction(int[] A, int K) {\n        Comparator<int[]> comp = (int[] a, int[] b) -> {\n            return Double.compare(A[a[0]] * 1.0 / A[a[1]], A[b[0]] * 1.0 / A[b[1]]);\n        };\n        PriorityQueue<int[]> q = new PriorityQueue<>(comp);\n        int len = A.length;\n        q.add(new int[]{0, len-1});\n        boolean[][] mark = new boolean[len][len];\n        mark[0][len-1] = true;\n        int c = 0;\n        while (c + 1 < K) {\n            int[] tmp = q.remove();\n            c++;\n            int i = tmp[0];\n            int j = tmp[1];\n            if (i+1 < len && i+1 < j && !mark[i+1][j]) {\n                q.add(new int[]{i+1, j});\n                mark[i+1][j] = true;\n            }\n            if (j-1 >= 0 && i < j-1 && !mark[i][j-1]) {\n                q.add(new int[]{i, j-1});\n                mark[i][j-1] = true;\n            }\n            if (i+1 < len && j-1 >= 0 && i+1 < j-1 && !mark[i+1][j-1]) {\n                q.add(new int[]{i+1, j-1});\n                mark[i+1][j-1] = true;\n            }\n        }\n        int[] tmp = q.peek();\n        return new int[]{A[tmp[0]], A[tmp[1]]};\n    }\n\n\n    /**\n     * https://leetcode.com/problems/k-th-smallest-prime-fraction/discuss/115486/Java-AC-O(max(nk)-*-logn)-Short-Easy-PriorityQueue\n     */\n    public int[] kthSmallestPrimeFraction2(int[] a, int k) {\n        int n = a.length;\n        // 0: numerator idx, 1: denominator idx\n        PriorityQueue<int[]> pq = new PriorityQueue<>(new Comparator<int[]>() {\n            @Override\n            public int compare(int[] o1, int[] o2) {\n                int s1 = a[o1[0]] * a[o2[1]];\n                int s2 = a[o2[0]] * a[o1[1]];\n                return s1 - s2;\n            }\n        });\n        for (int i = 0; i < n-1; i++) {\n            pq.add(new int[]{i, n-1});\n        }\n        for (int i = 0; i < k-1; i++) {\n            int[] pop = pq.remove();\n            int ni = pop[0];\n            int di = pop[1];\n            if (pop[1] - 1 > pop[0]) {\n                pop[1]--;\n                pq.add(pop);\n            }\n        }\n\n        int[] peek = pq.peek();\n        return new int[]{a[peek[0]], a[peek[1]]};\n    }\n\n    /**\n     * https://leetcode.com/problems/k-th-smallest-prime-fraction/discuss/116107/Java-Better-than-O(NlogN)-it-can-be-O(KlogK)\n     */\n    public int[] kthSmallestPrimeFraction3(int[] A, int K) {\n        PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> A[a[0]] * A[b[1]] - A[a[1]] * A[b[0]]);\n        pq.offer(new int[]{0, A.length - 1});\n        while (K > 1 && !pq.isEmpty()) {\n            int[] cur = pq.poll();\n            if (cur[1] == A.length - 1 && cur[0] + 1 < cur[1]) {\n                pq.offer(new int[]{cur[0] + 1, cur[1]});\n            }\n            if (cur[0] < cur[1] - 1) {\n                pq.offer(new int[]{cur[0], cur[1] - 1});\n            }\n            K--;\n        }\n        if (pq.isEmpty()) {\n            throw new RuntimeException(\"invalid input.\");\n        }\n        return new int[]{A[pq.peek()[0]], A[pq.peek()[1]]};\n    }\n}\n"
  },
  {
    "path": "src/KthSymbolInGrammar779.java",
    "content": "/**\n * On the first row, we write a 0. Now in every subsequent row, we look at the\n * previous row and replace each occurrence of 0 with 01, and each occurrence\n * of 1 with 10.\n * \n * Given row N and index K, return the K-th indexed symbol in row N.\n * (The values of K are 1-indexed.) (1 indexed).\n * \n * Examples:\n * Input: N = 1, K = 1\n * Output: 0\n * \n * Input: N = 2, K = 1\n * Output: 0\n * \n * Input: N = 2, K = 2\n * Output: 1\n * \n * Input: N = 4, K = 5\n * Output: 1\n * \n * Explanation:\n * row 1: 0\n * row 2: 01\n * row 3: 0110\n * row 4: 01101001\n * \n * Note:\n * N will be an integer in the range [1, 30].\n * K will be an integer in the range [1, 2^(N-1)].\n */\n\npublic class KthSymbolInGrammar779 {\n    public int kthGrammar(int N, int K) {\n        if (N == 1 && K == 1) return 0;\n        return (kthGrammar(N-1, (K+1) / 2) == 0) ^ (K % 2 == 0) ? 0 : 1;\n    }\n\n}\n"
  },
  {
    "path": "src/LFUCache460.java",
    "content": "/**\n * Design and implement a data structure for Least Frequently Used (LFU) cache.\n * It should support the following operations: get and put.\n * \n * get(key) - Get the value (will always be positive) of the key if the key\n * exists in the cache, otherwise return -1.\n * put(key, value) - Set or insert the value if the key is not already present.\n * When the cache reaches its capacity, it should invalidate the least\n * frequently used item before inserting a new item. For the purpose of this\n * problem, when there is a tie (i.e., two or more keys that have the same\n * frequency), the least recently used key would be evicted.\n * \n * Follow up:\n * Could you do both operations in O(1) time complexity?\n * \n * Example:\n * LFUCache cache = new LFUCache( 2 ); // capacity\n * \n * cache.put(1, 1);\n * cache.put(2, 2);\n * cache.get(1);       // returns 1\n * cache.put(3, 3);    // evicts key 2\n * cache.get(2);       // returns -1 (not found)\n * cache.get(3);       // returns 3.\n * cache.put(4, 4);    // evicts key 1.\n * cache.get(1);       // returns -1 (not found)\n * cache.get(3);       // returns 3\n * cache.get(4);       // returns 4\n */\n\npublic class LFUCache460 {\n    class LFUCache {\n        // freq -> Linked List\n        private TreeMap<Integer, Node> treeMap = new TreeMap<>();\n        // key -> Node\n        private Map<Integer, Node> map = new HashMap<>();\n        private int capacity;\n        \n        public LFUCache(int capacity) {\n            this.capacity = capacity;\n        }\n        \n        public int get(int key) {\n            if (!this.map.containsKey(key)) return -1;\n            Node node = map.get(key);\n            deleteFromTreeMap(node);\n            node.freq++;\n            addOnTreeMap(node);\n            return node.val;\n        }\n        \n        private void deleteFromList(Node node) {\n            node.prev.next = node.next;\n            node.next.prev = node.prev;\n        }\n        \n        private void addToListEnd(Node head, Node node) {\n            node.prev = head.prev;\n            node.next = head;\n            head.prev.next = node;\n            head.prev = node;\n        }\n        \n        private void addOnTreeMap(Node node) {\n            Node head = treeMap.get(node.freq);\n            if (head == null) {\n                head = newHead();\n            }\n            addToListEnd(head, node);\n            this.treeMap.put(node.freq, head);\n        }\n        \n        private void deleteFromTreeMap(Node node) {\n            deleteFromList(node);\n            Node head = treeMap.get(node.freq);\n            if (head.next.freq == -1) {\n                this.treeMap.remove(node.freq);\n            }\n        }\n        \n        public void put(int key, int value) {\n            if (this.capacity == 0) return; \n            Node node = this.map.get(key);\n            if (node == null) {\n                node = new Node(key, value, 1);\n                if (this.map.size() == this.capacity) {\n                    Map.Entry<Integer, Node> first = this.treeMap.firstEntry();\n                    Integer firstKey = first.getKey();\n                    Node firstHead = first.getValue();\n                    Node toBeRemoved = firstHead.next;\n                    deleteFromTreeMap(toBeRemoved);\n                    this.map.remove(toBeRemoved.key);\n                }\n                this.map.put(key, node);\n            } else {\n                node.val = value;\n                deleteFromTreeMap(node);\n                node.freq++;\n            }\n            addOnTreeMap(node);\n        }\n        \n        private Node newHead() {\n            Node head = new Node(0, 0, -1);\n            head.prev = head;\n            head.next = head;\n            return head;\n        }\n        \n        class Node {\n            Node next;\n            Node prev;\n            int key;\n            int val;\n            int freq;\n            Node(int key, int val, int freq) {\n                this.key = key;\n                this.val = val;\n                this.freq = freq;\n            }\n        }\n    }\n\n\n    class LFUCache2 {\n        private FreqNode head;\n        private Map<Integer, FreqNode> freqMap = new HashMap<>();\n        private Map<Integer, ItemNode> itemMap = new HashMap<>();\n        private int capacity;\n    \n        public LFUCache(int capacity) {\n            this.capacity = capacity;\n            this.head = new FreqNode();\n            this.head.next = this.head;\n            this.head.prev = this.head;\n        }\n        \n        public int get(int key) {\n            if (!this.itemMap.containsKey(key)) return -1;\n            ItemNode item = this.itemMap.get(key);\n            updateNodeFreq(item);\n            return item.val;\n        }\n        \n        private void updateNodeFreq(ItemNode item) {\n            dislinkNode(item);\n            Integer freq = item.freq;\n            item.freq++;\n            FreqNode currFreqNode = freqMap.get(freq);\n            FreqNode newFreqNode = freqMap.get(freq+1);\n            if (newFreqNode == null) {\n                newFreqNode = new FreqNode(freq+1);\n                freqMap.put(freq+1, newFreqNode);\n                addAfter(currFreqNode, newFreqNode);\n            }\n            addBefore(newFreqNode.itemHead, item);\n    \n            if (itemNodeIsEmpty(currFreqNode.itemHead)) {\n                removeNode(currFreqNode);\n            }\n        }\n        \n        private boolean itemNodeIsEmpty(ItemNode node) {\n            return node.next == node;\n        }\n        \n        private void removeNode(FreqNode node) {\n            dislinkNode(node);\n            this.freqMap.remove(node.freq);\n        }\n        \n        private void removeNode(ItemNode node) {\n            dislinkNode(node);\n            this.itemMap.remove(node.key);\n        }\n        \n        private void dislinkNode(FreqNode node) {\n            node.prev.next = node.next;\n            node.next.prev = node.prev;\n        }\n        \n        private void dislinkNode(ItemNode node) {\n            node.prev.next = node.next;\n            node.next.prev = node.prev;\n        }\n        \n        private void addAfter(FreqNode currNode, FreqNode newNode) {\n            newNode.next = currNode.next;\n            newNode.prev = currNode;\n            currNode.next.prev = newNode;\n            currNode.next = newNode;\n        }\n        \n        private void addAfter(ItemNode currNode, ItemNode newNode) {\n            newNode.next = currNode.next;\n            newNode.prev = currNode;\n            currNode.next.prev = newNode;\n            currNode.next = newNode;\n        }\n        \n        private void addBefore(ItemNode currNode, ItemNode newNode) {\n            newNode.next = currNode;\n            newNode.prev = currNode.prev;\n            currNode.prev.next = newNode;\n            currNode.prev = newNode;\n        }\n        \n        public void put(int key, int value) {\n            if (this.capacity == 0) return;\n            if (this.itemMap.containsKey(key)) {\n                ItemNode item = this.itemMap.get(key);\n                item.val = value;\n                updateNodeFreq(item);\n                return;\n            }\n    \n            if (this.itemMap.size() == this.capacity) {\n                FreqNode first = this.head.next;\n                ItemNode toBeRemoved = first.itemHead.next;\n                removeNode(toBeRemoved);\n                if (itemNodeIsEmpty(first.itemHead)) {\n                    removeNode(first);\n                }\n            }\n            \n            FreqNode newFreqNode = freqMap.get(1);\n            if (newFreqNode == null) {\n                newFreqNode = new FreqNode(1);\n                freqMap.put(1, newFreqNode);\n                addAfter(this.head, newFreqNode);\n            }\n            ItemNode newItem = new ItemNode(key, value, 1);\n            addBefore(newFreqNode.itemHead, newItem);\n            this.itemMap.put(key, newItem);\n        }\n        \n        private ItemNode newItemHead() {\n            ItemNode head = new ItemNode();\n            head.prev = head;\n            head.next = head;\n            return head;\n        }\n    \n        class ItemNode {\n            ItemNode next;\n            ItemNode prev;\n            int key;\n            int val;\n            int freq;\n            ItemNode(int key, int val, int freq) {\n                this.key = key;\n                this.val = val;\n                this.freq = freq;\n            }\n            ItemNode() {\n                this.key = -1;\n                this.val = -1;\n                this.freq = -1;\n            }\n        }\n        \n        class FreqNode {\n            FreqNode next;\n            FreqNode prev;\n            int freq;\n            ItemNode itemHead;\n            FreqNode(int freq) {\n                this.freq = freq;\n                this.itemHead = newItemHead();\n            }\n            FreqNode() {\n                this.freq = -1;\n            }\n        }\n    }\n\n\n/**\n * Your LFUCache object will be instantiated and called as such:\n * LFUCache obj = new LFUCache(capacity);\n * int param_1 = obj.get(key);\n * obj.put(key,value);\n */\n\n}\n"
  },
  {
    "path": "src/LRUCache146.java",
    "content": "/**\n * 146. LRU Cache\n *\n * Design and implement a data structure for Least Recently Used (LRU) cache.\n * https://en.wikipedia.org/wiki/Cache_replacement_policies#LRU\n *\n * It should support the following operations: get and put.\n *\n * get(key) - Get the value (will always be positive) of the key if the key\n *            exists in the cache, otherwise return -1.\n * put(key, value) - Set or insert the value if the key is not already present.\n *                   When the cache reached its capacity, it should invalidate\n *                   the least recently used item before inserting a new item.\n *\n * Follow up:\n * Could you do both operations in O(1) time complexity?\n *\n * Example:\n *\n * LRUCache cache = new LRUCache( 2 ); // capacity\n *\n * cache.put(1, 1);\n * cache.put(2, 2);\n * cache.get(1);       // returns 1\n * cache.put(3, 3);    // evicts key 2\n * cache.get(2);       // returns -1 (not found)\n * cache.put(4, 4);    // evicts key 1\n * cache.get(1);       // returns -1 (not found)\n * cache.get(3);       // returns 3\n * cache.get(4);       // returns 4\n */\n\n/**\n * Your LRUCache object will be instantiated and called as such:\n * LRUCache obj = new LRUCache(capacity);\n * int param_1 = obj.get(key);\n * obj.put(key,value);\n */\n\n\npublic class LRUCache {\n    private class Node{\n        int key, value;\n        Node prev, next;\n        Node(int k, int v){\n            this.key = k;\n            this.value = v;\n        }\n        Node(){\n            this(0, 0);\n        }\n    }\n    private int capacity;\n    private Map<Integer, Node> map;\n    private Node head, tail;\n\n    public LRUCache(int capacity) {\n        this.capacity = capacity;\n        map = new HashMap<>();\n        head = new Node();\n        tail = new Node();\n        head.next = tail;\n        tail.prev = head;\n    }\n\n    public int get(int key) {\n        Node n = map.get(key);\n        if(null==n){\n            return -1;\n        }\n        update(n);\n        return n.value;\n    }\n\n    public void put(int key, int value) {\n        Node n = map.get(key);\n        if(null==n){\n            n = new Node(key, value);\n            map.put(key, n);\n            add(n);\n        }\n        else{\n            n.value = value;\n            update(n);\n        }\n        if(map.size()>capacity){\n            Node toDel = tail.prev;\n            remove(toDel);\n            map.remove(toDel.key);\n        }\n    }\n\n    private void update(Node node){\n        remove(node);\n        add(node);\n    }\n    private void add(Node node){\n        Node after = head.next;\n        head.next = node;\n        node.prev = head;\n        node.next = after;\n        after.prev = node;\n    }\n\n    private void remove(Node node){\n        Node before = node.prev, after = node.next;\n        before.next = after;\n        after.prev = before;\n    }\n}\n\n\n\n\n/**\n * Easy LinkedHashMap Implementation\n */\n\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\npublic class LRUCache {\n    private Map<Integer, Integer> map;\n    private Integer capacity;\n\n    public LRUCache(int capacity) {\n        map = new LinkedHashMap<Integer, Integer>(capacity) {\n            @Override\n            protected boolean removeEldestEntry(Map.Entry eldest) {\n                return size() > capacity;\n            }\n        };\n        this.capacity = capacity;\n    }\n\n    public int get(int key) {\n        if (map.containsKey(key)) {\n            Integer i = map.get(key);\n            map.remove(key);\n            map.put(key, i);\n            return i;\n        }\n        return -1;\n    }\n\n    public void put(int key, int value) {\n        if (value < 0) return;\n\n        if (map.containsKey(key)) {\n            map.remove(key);\n        }\n\n        map.put(key, value);\n    }\n}\n\n\n// class LRUCache {\n//\n//     private Map<Integer, Node> map = new HashMap<>();\n//     private Node head = new Node(-1, -1);\n//     private Node tail = new Node(-1, -1);\n//     private int capacity;\n//\n//     public LRUCache(int capacity) {\n//         this.capacity = capacity;\n//         head.next = tail;\n//         tail.pre = head;\n//     }\n//\n//     public int get(int key) {\n//         Node n = map.get(key);\n//         if (n == null) return -1;\n//         detach(n);\n//         toEnd(n);\n//         return n.val;\n//     }\n//\n//     public void put(int key, int value) {\n//         Node n = map.get(key);\n//         if (n == null) {\n//             n = new Node(key, value);\n//             if (map.size() >= capacity) {\n//                 Node first = head.next;\n//                 if (first.val != -1) {\n//                     detach(first);\n//                     map.remove(first.key);\n//                 }\n//             }\n//             toEnd(n);\n//             map.put(key, n);\n//         } else {\n//             n.key = key;\n//             n.val = value;\n//             detach(n);\n//             toEnd(n);\n//         }\n//     }\n//\n//     private void detach(Node n) {\n//         n.pre.next = n.next;\n//         n.next.pre = n.pre;\n//     }\n//\n//     private void toEnd(Node n) {\n//         n.pre = tail.pre;\n//         tail.pre.next = n;\n//         tail.pre = n;\n//         n.next = tail;\n//     }\n//\n//     class Node {\n//         int val;\n//         int key;\n//         Node pre;\n//         Node next;\n//         public Node(int key, int val) {\n//             this.key = key;\n//             this.val = val;\n//         }\n//     }\n//\n// }\n"
  },
  {
    "path": "src/LargestBSTSubtree333.java",
    "content": "/**\n * Given a binary tree, find the largest subtree which is a Binary Search Tree\n * (BST), where largest means subtree with largest number of nodes in it.\n * \n * Note:\n * A subtree must include all of its descendants.\n * \n * Example:\n * Input: [10,5,15,1,8,null,7]\n * \n *    10 \n *    / \\ \n *   5  15 \n *  / \\   \\ \n * 1   8   7\n * Output: 3\n * Explanation: The Largest BST Subtree in this case is the highlighted one.\n *              The return value is the subtree's size, which is 3.\n * \n * Follow up:\n * Can you figure out ways to solve it with O(n) time complexity?\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class LargestBSTSubtree333 {\n    public int largestBSTSubtree(TreeNode root) {\n        if (root == null) return 0;\n        return helper(root)[0];\n    }\n\n    public int[] helper(TreeNode root) {\n        //   0       1         2      3\n        // {res, isBST(0/1), lower, upper}\n        if (root == null) return null;\n\n        int[] left = helper(root.left);\n        int[] right = helper(root.right);\n\n        if (left == null && right == null) {\n            return new int[]{1, 1, root.val, root.val};\n        } else if (left == null) {\n            boolean isBST = right[1] == 1 && root.val < right[2];\n            int res = right[0] + (isBST ? 1 : 0);\n            int lower = isBST ? root.val : 0;\n            int upper = isBST ? right[3] : 0;\n            return new int[]{res, isBST ? 1 : 0, lower, upper};\n        } else if (right == null) {\n            boolean isBST = left[1] == 1 && root.val > left[3];\n            int res = left[0] + (isBST ? 1 : 0);\n            int lower = isBST ? left[2] : 0;\n            int upper = isBST ? root.val : 0;\n            return new int[]{res, isBST ? 1 : 0, lower, upper};\n        } else {\n            boolean isBST = left[1] == 1 && right[1] == 1 && root.val > left[3] && root.val < right[2];\n            int res = isBST ? (left[0] + right[0] + 1) : Math.max(left[0], right[0]);\n            int lower = isBST ? left[2] : 0;\n            int upper = isBST ? right[3] : 0;\n            return new int[]{res, isBST ? 1 : 0, lower, upper}; \n        }\n    }\n\n}\n"
  },
  {
    "path": "src/LargestDivisibleSubset368.java",
    "content": "/**\n * Given a set of distinct positive integers, find the largest subset such that\n * every pair (Si, Sj) of elements in this subset satisfies:\n * Si % Sj = 0 or Sj % Si = 0.\n * \n * If there are multiple solutions, return any subset is fine.\n * \n * Example 1:\n * nums: [1,2,3]\n * Result: [1,2] (of course, [1,3] will also be ok)\n * \n * Example 2:\n * nums: [1,2,4,8]\n * Result: [1,2,4,8]\n */\n\npublic class LargestDivisibleSubset368 {\n    public List<Integer> largestDivisibleSubset(int[] nums) {\n        if (nums == null || nums.length == 0) return new ArrayList<>();\n        Arrays.sort(nums);\n        int N = nums.length;\n        int[] dp = new int[N + 1];\n        int[] track = new int[N + 1];\n        int maxIdx = 1;\n        int maxSize = 0;\n        for (int i=1; i<=N; i++) {\n            dp[i] = 1;\n            for (int j=1; j<i; j++) {\n                if (nums[i-1] % nums[j-1] == 0) {\n                    if (dp[j] + 1 > dp[i]) {\n                        dp[i] = dp[j] + 1;\n                        track[i] = j;\n\n                    }\n                }\n            }\n            if (dp[i] > maxSize) {\n                maxSize = dp[i];\n                maxIdx = i;\n            }\n        }\n\n        List<Integer> res = new ArrayList<>();\n        int i = maxIdx;\n        while (i != 0) {\n            res.add(nums[i-1]);\n            i = track[i];\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/LargestNumber179.java",
    "content": "/**\n * Given a list of non negative integers, arrange them such that they form the\n * largest number.\n *\n * For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330.\n *\n * Note: The result may be very large, so you need to return a string instead\n * of an integer.\n *\n */\n\n\npublic class LargestNumber179 {\n    public String largestNumber(int[] nums) {\n        String[] newNums = new String[nums.length];\n        boolean allZeros = true;\n        for (int i=0; i<nums.length; i++) {\n            if (nums[i] != 0) allZeros = false;\n            newNums[i] = Integer.toString(nums[i]);\n        }\n        if (allZeros) return \"0\";\n\n        Arrays.sort(newNums, new Comparator<String>() {\n            @Override\n            public int compare(String s1, String s2) {\n                String sum1 = s1 + s2;\n                String sum2 = s2 + s1;\n                return sum2.compareTo(sum1);\n            }\n        });\n\n        return String.join(\"\", newNums);\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/7235/my-3-lines-code-in-java-and-python\n     */\n    public String largestNumber2(int[] num) {\n        String[] array = Arrays.stream(num).mapToObj(String::valueOf).toArray(String[]::new);\n        Arrays.sort(array, (String s1, String s2) -> (s2 + s1).compareTo(s1 + s2));\n        return Arrays.stream(array).reduce((x, y) -> x.equals(\"0\") ? y : x + y).get();\n    }\n\n}\n"
  },
  {
    "path": "src/LargestRectangleInHistogram84.java",
    "content": "/**\n * Given n non-negative integers representing the histogram's bar height where\n * the width of each bar is 1, find the area of largest rectangle in the histogram.\n *\n * https://leetcode.com/static/images/problemset/histogram.png\n * Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].\n *\n * https://leetcode.com/static/images/problemset/histogram_area.png\n * The largest rectangle is shown in the shaded area, which has area = 10 unit.\n *\n * For example,\n * Given heights = [2,1,5,6,2,3],\n * return 10.\n *\n */\n\n\npublic class LargestRectangleInHistogram84 {\n    /**\n     * https://discuss.leetcode.com/topic/7599/o-n-stack-based-java-solution\n     */\n    public int largestRectangleArea(int[] height) {\n      int len = height.length;\n      Stack<Integer> s = new Stack<Integer>();\n      int maxArea = 0;\n      for(int i = 0; i <= len; i++){\n          int h = (i == len ? 0 : height[i]);\n          if(s.isEmpty() || h >= height[s.peek()]){\n              s.push(i);\n          }else{\n              int tp = s.pop();\n              maxArea = Math.max(maxArea, height[tp] * (s.isEmpty() ? i : i - 1 - s.peek()));\n              i--;\n          }\n      }\n      return maxArea;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/39151/5ms-o-n-java-solution-explained-beats-96\n     */\n    public int largestRectangleArea2(int[] height) {\n        if (height == null || height.length == 0) {\n            return 0;\n        }\n        int[] lessFromLeft = new int[height.length]; // idx of the first bar the left that is lower than current\n        int[] lessFromRight = new int[height.length]; // idx of the first bar the right that is lower than current\n        lessFromRight[height.length - 1] = height.length;\n        lessFromLeft[0] = -1;\n\n        for (int i = 1; i < height.length; i++) {\n            int p = i - 1;\n\n            while (p >= 0 && height[p] >= height[i]) {\n                p = lessFromLeft[p];\n            }\n            lessFromLeft[i] = p;\n        }\n\n        for (int i = height.length - 2; i >= 0; i--) {\n            int p = i + 1;\n\n            while (p < height.length && height[p] >= height[i]) {\n                p = lessFromRight[p];\n            }\n            lessFromRight[i] = p;\n        }\n\n        int maxArea = 0;\n        for (int i = 0; i < height.length; i++) {\n            maxArea = Math.max(maxArea, height[i] * (lessFromRight[i] - lessFromLeft[i] - 1));\n        }\n\n        return maxArea;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/2424/my-modified-answer-from-geeksforgeeks-in-java\n     */\n    public int largestRectangleArea3(int[] height) {\n        if (height==null) return 0;//Should throw exception\n        if (height.length==0) return 0;\n\n        Stack<Integer> index= new Stack<Integer>();\n        index.push(-1);\n        int max=0;\n\n        for  (int i=0;i<height.length;i++){\n                //Start calculate the max value\n            while (index.peek()>-1)\n                if (height[index.peek()]>height[i]){\n                    int top=index.pop();\n                    max=Math.max(max,height[top]*(i-1-index.peek()));\n                }else break;\n\n            index.push(i);\n        }\n        while(index.peek()!=-1){\n        \tint top=index.pop();\n            max=Math.max(max,height[top]*(height.length-1-index.peek()));\n        }\n        return max;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/39836/share-my-2ms-java-solution-beats-100-java-submissions\n     */\n    public int largestRectangleArea4(int[] heights) {\n        if (heights == null || heights.length == 0) return 0;\n        return getMax(heights, 0, heights.length);\n    }\n    private int getMax(int[] heights, int s, int e) {\n        if (s + 1 >= e) return heights[s];\n        int min = s;\n        boolean sorted = true;\n        for (int i = s; i < e; i++) {\n            if (i > s && heights[i] < heights[i - 1]) sorted = false;\n            if (heights[min] > heights[i]) min = i;\n        }\n        if (sorted) {\n            int max = 0;\n            for (int i = s; i < e; i++) {\n                max = Math.max(max, heights[i] * (e - i));\n            }\n            return max;\n        }\n        int left = (min > s) ? getMax(heights, s, min) : 0;\n        int right = (min < e - 1) ? getMax(heights, min + 1, e) : 0;\n        return Math.max(Math.max(left, right), (e - s) * heights[min]);\n    }\n}\n"
  },
  {
    "path": "src/LemonadeChange860.java",
    "content": "/**\n * At a lemonade stand, each lemonade costs $5. \n * \n * Customers are standing in a queue to buy from you, and order one at a time\n * (in the order specified by bills).\n * \n * Each customer will only buy one lemonade and pay with either a $5, $10, or\n * $20 bill.  You must provide the correct change to each customer, so that\n * the net transaction is that the customer pays $5.\n * \n * Note that you don't have any change in hand at first.\n * \n * Return true if and only if you can provide every customer with correct change.\n * \n * Example 1:\n * Input: [5,5,5,10,20]\n * Output: true\n * Explanation: \n * From the first 3 customers, we collect three $5 bills in order.\n * From the fourth customer, we collect a $10 bill and give back a $5.\n * From the fifth customer, we give a $10 bill and a $5 bill.\n * Since all customers got correct change, we output true.\n * \n * Example 2:\n * Input: [5,5,10]\n * Output: true\n * \n * Example 3:\n * Input: [10,10]\n * Output: false\n * \n * Example 4:\n * Input: [5,5,10,10,20]\n * Output: false\n * Explanation: \n * From the first two customers in order, we collect two $5 bills.\n * For the next two customers in order, we collect a $10 bill and give back a $5 bill.\n * For the last customer, we can't give change of $15 back because we only have two $10 bills.\n * Since not every customer received correct change, the answer is false.\n * \n * Note:\n * 0 <= bills.length <= 10000\n * bills[i] will be either 5, 10, or 20.\n */\n\npublic class LemonadeChange860 {\n    public boolean lemonadeChange(int[] bills) {\n        int five = 0, ten = 0;\n        for (int bill: bills) {\n            if (bill == 5) {\n                five++;\n            } else if (bill == 10) {\n                if (five == 0) return false;\n                five--;\n                ten++;\n            } else {\n                if (five > 0 && ten > 0) {\n                    five--;\n                    ten--;\n                } else if (five >= 3) {\n                    five -= 3;\n                } else {\n                    return false;\n                }\n            }\n        }\n\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/LengthOfLongestFibonacciSubsequence873.java",
    "content": "/**\n * A sequence X_1, X_2, ..., X_n is fibonacci-like if:\n * n >= 3\n * X_i + X_{i+1} = X_{i+2} for all i + 2 <= n\n * \n * Given a strictly increasing array A of positive integers forming a sequence,\n * find the length of the longest fibonacci-like subsequence of A.\n * If one does not exist, return 0.\n * \n * (Recall that a subsequence is derived from another sequence A by deleting\n * any number of elements (including none) from A, without changing the order\n * of the remaining elements.  For example, [3, 5, 8] is a subsequence of\n * [3, 4, 5, 6, 7, 8].)\n * \n * Example 1:\n * Input: [1,2,3,4,5,6,7,8]\n * Output: 5\n * Explanation:\n * The longest subsequence that is fibonacci-like: [1,2,3,5,8].\n * \n * Example 2:\n * Input: [1,3,7,11,12,14,18]\n * Output: 3\n * Explanation:\n * The longest subsequence that is fibonacci-like:\n * [1,11,12], [3,11,14] or [7,11,18].\n * \n * Note:\n * \n * 3 <= A.length <= 1000\n * 1 <= A[0] < A[1] < ... < A[A.length - 1] <= 10^9\n * (The time limit has been reduced by 50% for submissions in Java, C, and C++.)\n */\n\n\npublic class LengthOfLongestFibonacciSubsequence873 {\n    public int lenLongestFibSubseq(int[] A) {\n        int len = A.length;\n        int longest = Integer.MIN_VALUE;\n        for (int i=0; i<len-3; i++) {\n            for (int j=i+1; j<len-2; j++) {\n                int a = A[i];\n                int b = A[j];\n                int idx = Arrays.binarySearch(A, j+1, len, a + b);\n                if (idx < 0) continue;\n                int l = 2;\n                while (idx >= 0 && idx < len) {\n                    l++;\n                    a = b;\n                    b = A[idx];\n                    if (idx >= len) break;\n                    idx = Arrays.binarySearch(A, idx + 1, len, a + b);\n                }\n                if (l > longest) {\n                    longest = l;\n                }\n            }\n        }\n        return longest == Integer.MIN_VALUE ? 0 : longest;\n    }\n\n\n    public int lenLongestFibSubseq2(int[] A) {\n        int N = A.length;\n        int[][] dp = new int[N + 1][N + 1];\n        int res = 0;\n        for (int i=2; i<N; i++) {\n            for (int j=i+1; j<=N; j++) {\n                int toBeFound = A[j-1] - A[i-1];\n                if (toBeFound > A[i-2]) break;\n                int idx = Arrays.binarySearch(A, 0, i-1, toBeFound);\n                if (idx >= 0) {\n                    if (dp[idx+1][i] == 0) {\n                        dp[i][j] = 3;\n                    } else {\n                        dp[i][j] += dp[idx+1][i] + 1;\n                    }\n                }\n                if (dp[i][j] > res) res = dp[i][j];\n            }\n        }\n        return res;\n    }\n\n\n    public int lenLongestFibSubseq3(int[] A) {\n        int N = A.length;\n        Map<Integer, Integer> index = new HashMap();\n        for (int i = 0; i < N; ++i) index.put(A[i], i);\n        int[][] dp = new int[N + 1][N + 1];\n        int res = 0;\n        for (int i=2; i<N; i++) {\n            for (int j=i+1; j<=N; j++) {\n                int toBeFound = A[j-1] - A[i-1];\n                if (toBeFound > A[i-2]) break;\n                if (index.containsKey(toBeFound)) {\n                    int idx = index.get(toBeFound);\n                    if (dp[idx+1][i] == 0) {\n                        dp[i][j] = 3;\n                    } else {\n                        dp[i][j] += dp[idx+1][i] + 1;\n                    }\n                }\n                if (dp[i][j] > res) res = dp[i][j];\n            }\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/length-of-longest-fibonacci-subsequence/solution/\n     */\n    public int lenLongestFibSubseq4(int[] A) {\n        int N = A.length;\n        Map<Integer, Integer> index = new HashMap();\n        for (int i = 0; i < N; ++i)\n            index.put(A[i], i);\n\n        Map<Integer, Integer> longest = new HashMap();\n        int ans = 0;\n\n        for (int k = 0; k < N; ++k) {\n            for (int j = 0; j < k; ++j) {\n                int i = index.getOrDefault(A[k] - A[j], -1);\n                if (i >= 0 && i < j) {\n                    // Encoding tuple (i, j) as integer (i * N + j)\n                    int cand = longest.getOrDefault(i * N + j, 2) + 1;\n                    longest.put(j * N + k, cand);\n                    ans = Math.max(ans, cand);\n                }\n            }\n        }\n        return ans >= 3 ? ans : 0;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/length-of-longest-fibonacci-subsequence/discuss/152343/C++JavaPython-Check-Pair\n     */\n    public int lenLongestFibSubseq5(int[] A) {\n        Set<Integer> s = new HashSet<Integer>();\n        for (int x : A) s.add(x);\n        int res = 2;\n        for (int i = 0; i < A.length; ++i) {\n            for (int j = i + 1; j < A.length; ++j) {\n                int a = A[i], b = A[j], l = 2;\n                while (s.contains(a + b)) {\n                    b = a + b;\n                    a = b - a;\n                    l++;\n                }\n                res = Math.max(res, l);\n            }\n        }\n        return res > 2 ? res : 0;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/length-of-longest-fibonacci-subsequence/discuss/152343/C++JavaPython-Check-Pair\n     */\n    public int lenLongestFibSubseq6(int[] A) {\n        int res = 0;\n        int[][] dp = new int[A.length][A.length];\n        Map<Integer, Integer> index = new HashMap<>();\n        for (int j = 0; j < A.length; j++) {\n            index.put(A[j], j);\n            for (int i = 0; i < j; i++) {\n                int k = index.getOrDefault(A[j] - A[i], -1);\n                dp[i][j] = (A[j] - A[i] < A[i] && k >= 0) ? dp[k][i] + 1 : 2;\n                res = Math.max(res, dp[i][j]);\n            }\n        }\n        return res > 2 ? res : 0;\n    }\n\n}\n"
  },
  {
    "path": "src/LetterCombinationsOfAPhoneNumber17.java",
    "content": "/**\n * Given a digit string, return all possible letter combinations that the number\n * could represent.\n *\n * A mapping of digit to letters (just like on the telephone buttons) is given below.\n *\n * Image: http://upload.wikimedia.org/wikipedia/commons/thumb/7/73/Telephone-keypad2.svg/200px-Telephone-keypad2.svg.png\n *\n * Input:Digit string \"23\"\n * Output: [\"ad\", \"ae\", \"af\", \"bd\", \"be\", \"bf\", \"cd\", \"ce\", \"cf\"].\n *\n *\n * Note:\n * Although the above answer is in lexicographical order, your answer could be\n * in any order you want.\n *\n */\n\n\npublic class LetterCombinationsOfAPhoneNumber17 {\n    /**\n     * https://discuss.leetcode.com/topic/8465/my-java-solution-with-fifo-queue\n     */\n    public List<String> letterCombinations(String digits) {\n        LinkedList<String> ans = new LinkedList<String>();\n        int L = digits.length();\n        if (L == 0) return ans;\n\n        String[] mapping = new String[] {\"0\", \"1\", \"abc\", \"def\", \"ghi\", \"jkl\", \"mno\", \"pqrs\", \"tuv\", \"wxyz\"};\n        ans.add(\"\");\n        for(int i =0; i<digits.length();i++){\n            int x = Character.getNumericValue(digits.charAt(i));\n            while(ans.peek().length()==i){\n                String t = ans.remove();\n                for(char s : mapping[x].toCharArray())\n                    ans.add(t+s);\n            }\n        }\n        return ans;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/6380/my-recursive-solution-using-java\n     */\n    private static final String[] KEYS = { \"\", \"\", \"abc\", \"def\", \"ghi\", \"jkl\", \"mno\", \"pqrs\", \"tuv\", \"wxyz\" };\n\n    public List<String> letterCombinations2(String digits) {\n      List<String> ret = new LinkedList<String>();\n          if (digits.length() == 0) return ret;\n\n      combination(\"\", digits, 0, ret);\n      return ret;\n    }\n\n    private void combination(String prefix, String digits, int offset, List<String> ret) {\n      if (offset >= digits.length()) {\n        ret.add(prefix);\n        return;\n      }\n      String letters = KEYS[(digits.charAt(offset) - '0')];\n      for (int i = 0; i < letters.length(); i++) {\n        combination(prefix + letters.charAt(i), digits, offset + 1, ret);\n      }\n    }\n\n\n\n    private String[] alphas = new String[]{\"\", \"\", \"abc\", \"def\", \"ghi\", \"jkl\", \"mno\", \"pqrs\", \"tuv\", \"wxyz\"};\n\n    public List<String> letterCombinations4(String digits) {\n        List<String> res = new ArrayList<>();\n        if (digits == null || digits.length() == 0) return res;\n\n        String[] letters = new String[digits.length()];\n        for (int i=0; i<digits.length(); i++) letters[i] = alphas[Character.getNumericValue(digits.charAt(i))];\n\n        helper(res, letters, 0, new StringBuilder());\n\n        return res;\n    }\n\n    private void helper(List<String> res, String[] letters, int i, StringBuilder sb) {\n        if (i >= letters.length) {\n            res.add(sb.toString());\n            return;\n        }\n\n        char[] chars = letters[i].toCharArray();\n        for (char c: chars) {\n            sb.append(c);\n            helper(res, letters, i+1, sb);\n            sb.deleteCharAt(sb.length()-1);\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/LexicographicalNumbers386.java",
    "content": "/**\n * Given an integer n, return 1 - n in lexicographical order.\n * \n * For example, given 13, return: [1,10,11,12,13,2,3,4,5,6,7,8,9].\n * \n * Please optimize your algorithm to use less time and space.\n * The input size may be as large as 5,000,000.\n */\n\npublic class LexicographicalNumbers386 {\n    public List<Integer> lexicalOrder(int n) {\n        List<Integer> res = new ArrayList<>();\n        for (int i=1; i<=9; i++) {\n            helper(i, res, n);\n        }\n        return res;\n    }\n\n    private void helper(int curr, List<Integer> res, int n) {\n        if (curr > n) return;\n        res.add(curr);\n        for (int i=0; i<=9; i++) {\n            helper(10*curr+i, res, n);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/lexicographical-numbers/discuss/86269/Simple-Java-DFS-Solution-(beats-85-12-lines)\n     */\n    public List<Integer> lexicalOrder2(int n) {\n        List<Integer> res = new ArrayList<>(n);\n        //  from  1 to 9.\n        //  0 is can't be a soution.\n        dfs(1, 9, n, res);\n        return res;\n    }\n\n    private void dfs(int start, int end, int n, List<Integer> res){\n        // <= n make the solution can't bigger than n\n        for (int i = start; i <= end && i <= n; i++){\n            res.add(i);\n            // 10 -> next recursion: 100(->next recursion 1000), 101,102....\n            // next loop: 11 -> next recursion: 110,  111,112....\n            // next loop: 12 -> next recursion: 120,  121,122....\n            // from 0 to 9 different from the dfs call in method lexicalOrder\n            dfs(i * 10, i * 10 + 9, n, res);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/lexicographical-numbers/discuss/86242/Java-O(n)-time-O(1)-space-iterative-solution-130ms\n     */\n    public List<Integer> lexicalOrder3(int n) {\n        List<Integer> res = new ArrayList<>();\n        int curr = 1;\n        for (int i=1; i<=n; i++) {\n            res.add(curr);\n            if (curr * 10 <= n) {\n                curr *= 10;\n            } else if (curr % 10 != 9 && curr + 1 <= n) {\n                curr++;\n            } else {\n                while ((curr / 10) % 10 == 9) {\n                    curr /= 10;\n                }\n                curr = curr / 10 + 1;\n            }\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/LicenseKeyFormatting482.java",
    "content": "/**\n * You are given a license key represented as a string S which consists only\n * alphanumeric character and dashes. The string is separated into N+1 groups\n * by N dashes.\n * \n * Given a number K, we would want to reformat the strings such that each group\n * contains exactly K characters, except for the first group which could be\n * shorter than K, but still must contain at least one character. Furthermore,\n * there must be a dash inserted between two groups and all lowercase letters\n * should be converted to uppercase.\n * \n * Given a non-empty string S and a number K, format the string according to\n * the rules described above.\n * \n * Example 1:\n * Input: S = \"5F3Z-2e-9-w\", K = 4\n * Output: \"5F3Z-2E9W\"\n * Explanation: The string S has been split into two parts, each part has 4\n * characters. Note that the two extra dashes are not needed and can be removed.\n * \n * Example 2:\n * Input: S = \"2-5g-3-J\", K = 2\n * Output: \"2-5G-3J\"\n * Explanation: The string S has been split into three parts, each part has 2\n * characters except the first part as it could be shorter as mentioned above.\n * \n * Note:\n * The length of string S will not exceed 12,000, and K is a positive integer.\n * String S consists only of alphanumerical characters (a-z and/or A-Z and/or 0-9)\n * and dashes(-).\n * String S is non-empty.\n */\n\n\npublic class LicenseKeyFormatting482 {\n    public String licenseKeyFormatting(String S, int K) {\n        char[] chars = S.toCharArray();\n        \n        int i = chars.length - 1;\n        int loop = -1;\n        StringBuilder sb = new StringBuilder();\n        while (i >= 0) {\n            if (chars[i] == '-') {\n                i--;\n                continue;\n            }\n            sb.append(Character.toUpperCase(chars[i]));\n            i--;\n            loop = (loop + 1) % K;\n            if (loop == K-1) {\n                sb.append(\"-\");\n            }\n        }\n        sb = sb.reverse();\n        if (sb.length() > 0 && sb.charAt(0) == '-') sb.deleteCharAt(0);\n        return sb.toString();\n    }\n\n}\n"
  },
  {
    "path": "src/LinkedListCycle141.java",
    "content": "/**\n * Given a linked list, determine if it has a cycle in it.\n *\n * Follow up:\n * Can you solve it without using extra space?\n *\n */\n\n\n/**\n * Definition for singly-linked list.\n * class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) {\n *         val = x;\n *         next = null;\n *     }\n * }\n */\n\npublic class LinkedListCycle141 {\n    public boolean hasCycle(ListNode head) {\n        ListNode slow = head;\n        ListNode fast = head;\n\n        while(slow != null && fast != null && fast.next != null) {\n            slow = slow.next;\n            fast = fast.next.next;\n\n            if (slow == fast) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/LinkedListCycleII142.java",
    "content": "/**\n * Given a linked list, return the node where the cycle begins.\n * If there is no cycle, return null.\n *\n * Note: Do not modify the linked list.\n *\n * Follow up:\n * Can you solve it without using extra space?\n */\n\n/**\n * Definition for singly-linked list.\n * class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) {\n *         val = x;\n *         next = null;\n *     }\n * }\n */\n\npublic class LinkedListCycleII142 {\n    public ListNode detectCycle(ListNode head) {\n        ListNode slow = head;\n        ListNode fast = head;\n\n        while(slow != null && fast != null && fast.next != null) {\n            slow = slow.next;\n            fast = fast.next.next;\n\n            if (slow == fast) {\n                fast = head;\n                while (slow != fast) {\n                    slow = slow.next;\n                    fast = fast.next;\n                }\n                return fast;\n            }\n        }\n\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/LinkedListRandomNode382.java",
    "content": "/**\n * Given a singly linked list, return a random node's value from the linked\n * list. Each node must have the same probability of being chosen.\n * \n * Follow up:\n * What if the linked list is extremely large and its length is unknown to\n * you? Could you solve this efficiently without using extra space?\n * \n * Example:\n * \n * // Init a singly linked list [1,2,3].\n * ListNode head = new ListNode(1);\n * head.next = new ListNode(2);\n * head.next.next = new ListNode(3);\n * Solution solution = new Solution(head);\n * \n * // getRandom() should return either 1, 2, or 3 randomly. Each element should\n * have equal probability of returning.\n * solution.getRandom();\n */\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\npublic class LinkedListRandomNode382 {\n    class Solution {\n        private ListNode head;\n        private Random rand = new Random();\n        /** @param head The linked list's head.\n            Note that the head is guaranteed to be not null, so it contains at least one node. */\n        public Solution(ListNode head) {\n            this.head = head;\n        }\n\n        /** Returns a random node's value. */\n        public int getRandom() {\n            int count = 0;\n            int res = -1;\n            ListNode p = head;\n            while (p != null) {\n                count++;\n                if (count == 1) {\n                    res = p.val;\n                } else {\n                  int idx = rand.nextInt(count);\n                    if (idx == count - 1) res = p.val;\n                }\n                p = p.next;\n            }\n            return res;\n        }\n    }\n\n/**\n* Your Solution object will be instantiated and called as such:\n* Solution obj = new Solution(head);\n* int param_1 = obj.getRandom();\n*/\n\n}\n"
  },
  {
    "path": "src/ListNode.java",
    "content": "/**\n * Definition for singly-linked list.\n */\n\npublic class ListNode {\n    int val;\n    ListNode next;\n    ListNode(int x) { val = x; }\n}\n"
  },
  {
    "path": "src/LoggerRateLimiter359.java",
    "content": "/**\n * Design a logger system that receive stream of messages along with its\n * timestamps, each message should be printed if and only if it is not printed\n * in the last 10 seconds.\n * \n * Given a message and a timestamp (in seconds granularity), return true if\n * the message should be printed in the given timestamp, otherwise returns\n * false.\n * \n * It is possible that several messages arrive roughly at the same time.\n * \n * Example:\n * \n * Logger logger = new Logger();\n * \n * // logging string \"foo\" at timestamp 1\n * logger.shouldPrintMessage(1, \"foo\"); returns true; \n * \n * // logging string \"bar\" at timestamp 2\n * logger.shouldPrintMessage(2,\"bar\"); returns true;\n * \n * // logging string \"foo\" at timestamp 3\n * logger.shouldPrintMessage(3,\"foo\"); returns false;\n * \n * // logging string \"bar\" at timestamp 8\n * logger.shouldPrintMessage(8,\"bar\"); returns false;\n * \n * // logging string \"foo\" at timestamp 10\n * logger.shouldPrintMessage(10,\"foo\"); returns false;\n * \n * // logging string \"foo\" at timestamp 11\n * logger.shouldPrintMessage(11,\"foo\"); returns true;\n */\n\npublic class LoggerRateLimiter359 {\n    class Logger {\n        Map<String, Integer> map = new HashMap<>();\n        \n        /** Initialize your data structure here. */\n        public Logger() {\n            \n        }\n        \n        /** Returns true if the message should be printed in the given timestamp, otherwise returns false.\n            If this method returns false, the message will not be printed.\n            The timestamp is in seconds granularity. */\n        public boolean shouldPrintMessage(int timestamp, String message) {\n            if (!map.containsKey(message) || map.get(message) + 10 <= timestamp) {\n                map.put(message, timestamp);\n                return true;\n            }\n            return false;\n        }\n    }\n\n    /**\n     * https://leetcode.com/problems/logger-rate-limiter/discuss/83254/Java-with-a-LinkedHashMap-and-using-removeEldestEntry\n     */\n    class Logger2 {\n        public Map<String, Integer> map;\n        int lastSecond = 0;\n\n        /** Initialize your data structure here. */\n        public Logger() {\n            map = new LinkedHashMap<String, Integer>(100, 0.6f, true) {\n                protected boolean removeEldestEntry(Map.Entry<String, Integer> eldest) {\n                    return lastSecond - eldest.getValue() > 10;\n                }\n            };\n        }\n\n        /** Returns true if the message should be printed in the given timestamp, otherwise returns false.\n            If this method returns false, the message will not be printed.\n            The timestamp is in seconds granularity. */\n        public boolean shouldPrintMessage(int timestamp, String message) {\n            lastSecond = timestamp;\n            if(!map.containsKey(message)||timestamp - map.get(message) >= 10){\n                map.put(message,timestamp);\n                return true;\n            }\n            return false;\n        }\n    }\n\n\n/**\n * Your Logger object will be instantiated and called as such:\n * Logger obj = new Logger();\n * boolean param_1 = obj.shouldPrintMessage(timestamp,message);\n */\n\n}\n"
  },
  {
    "path": "src/LonelyPixelI531.java",
    "content": "/**\n * Given a picture consisting of black and white pixels, find the number of\n * black lonely pixels.\n * \n * The picture is represented by a 2D char array consisting of 'B' and 'W',\n * which means black and white pixels respectively.\n * \n * A black lonely pixel is character 'B' that located at a specific position\n * where the same row and same column don't have any other black pixels.\n * \n * Example:\n * Input: \n * [['W', 'W', 'B'],\n *  ['W', 'B', 'W'],\n *  ['B', 'W', 'W']]\n * Output: 3\n * Explanation: All the three 'B's are black lonely pixels.\n * \n * Note:\n * The range of width and height of the input 2D array is [1,500].\n */\n\npublic class LonelyPixelI531 {\n    public int findLonelyPixel(char[][] picture) {\n        if (picture == null || picture.length == 0 || picture[0].length == 0) return 0;\n        int M = picture.length;\n        int N = picture[0].length;\n        int[] hori = new int[M];\n        int[] vert = new int[N];\n        for (int i=0; i<M; i++) {\n            for (int j=0; j<N; j++) {\n                hori[i] = hori[i] + (picture[i][j] == 'B' ? 1 : 0);\n                vert[j] = vert[j] + (picture[i][j] == 'B' ? 1 : 0);\n            }\n        }\n        \n        int res = 0;\n        for (int i=0; i<M; i++) {\n            for (int j=0; j<N; j++) {\n                if (picture[i][j] == 'B' && hori[i] == 1 && vert[j] == 1) {\n                    res++;\n                    continue;\n                }\n            }\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/LongestAbsoluteFilePath388.java",
    "content": "/**\n * Suppose we abstract our file system by a string in the following manner:\n * \n * The string \"dir\\n\\tsubdir1\\n\\tsubdir2\\n\\t\\tfile.ext\" represents:\n * \n * dir\n *     subdir1\n *     subdir2\n *         file.ext\n *\n * The directory dir contains an empty sub-directory subdir1 and a sub-directory\n * subdir2 containing a file file.ext.\n * \n * The string \"dir\\n\\tsubdir1\\n\\t\\tfile1.ext\\n\\t\\tsubsubdir1\\n\\tsubdir2\\n\\t\\tsubsubdir2\\n\\t\\t\\tfile2.ext\" represents:\n * \n * dir\n *     subdir1\n *         file1.ext\n *         subsubdir1\n *     subdir2\n *         subsubdir2\n *             file2.ext\n * \n * The directory dir contains two sub-directories subdir1 and subdir2. subdir1\n * contains a file file1.ext and an empty second-level sub-directory subsubdir1.\n * subdir2 contains a second-level sub-directory subsubdir2 containing a file\n * file2.ext.\n * \n * We are interested in finding the longest (number of characters) absolute\n * path to a file within our file system. For example, in the second example\n * above, the longest absolute path is \"dir/subdir2/subsubdir2/file2.ext\", and\n * its length is 32 (not including the double quotes).\n * \n * Given a string representing the file system in the above format, return the\n * length of the longest absolute path to file in the abstracted file system.\n * If there is no file in the system, return 0.\n * \n * Note:\n * The name of a file contains at least a . and an extension.\n * The name of a directory or sub-directory will not contain a ..\n * Time complexity required: O(n) where n is the size of the input string.\n * \n * Notice that a/aa/aaa/file1.txt is not the longest file path, if there is\n * another path aaaaaaaaaaaaaaaaaaaaa/sth.png.\n */\n\n\npublic class LongestAbsoluteFilePath388 {\n    public int lengthLongestPath(String input) {\n        String[] paths = input.split(\"\\\\n\");\n        int len = paths.length;\n        int i = 0;\n        Stack<String> stack = new Stack<>();\n        int currentLength = 0;\n        int longest = 0;\n        while (i < len) {\n            int currentLevel = stack.size();\n            String path = paths[i];\n            int level = levelOf(path);\n            int diff = currentLevel - level;\n            for (int k=0; k<diff; k++) {\n                String last = stack.pop();\n                currentLength -= last.length() - stack.size() + 1;\n            }\n            stack.push(path);\n            currentLength += path.length() - level + 1;\n            if (path.indexOf('.') != -1) longest = Math.max(longest, currentLength);\n            i++;\n        }\n        return longest == 0 ? 0 : longest-1;\n    }\n    \n    private int levelOf(String path) {\n        char[] chars = path.toCharArray();\n        int res = 0;\n        while (chars[res] == '\\t') {\n            res++;\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/longest-absolute-file-path/discuss/86615/9-lines-4ms-Java-solution\n     */\n    public int lengthLongestPath2(String input) {\n        Deque<Integer> stack = new ArrayDeque<>();\n        stack.push(0); // \"dummy\" length\n        int maxLen = 0;\n        for(String s:input.split(\"\\n\")){\n            int lev = s.lastIndexOf(\"\\t\")+1; // number of \"\\t\"\n            while(lev+1<stack.size()) stack.pop(); // find parent\n            int len = stack.peek()+s.length()-lev+1; // remove \"/t\", add\"/\"\n            stack.push(len);\n            // check if it is file\n            if(s.contains(\".\")) maxLen = Math.max(maxLen, len-1); \n        }\n        return maxLen;\n    }\n\n    public int lengthLongestPath3(String input) {\n        String[] paths = input.split(\"\\n\");\n        int[] stack = new int[paths.length+1];\n        int maxLen = 0;\n        for(String s:paths){\n            int lev = s.lastIndexOf(\"\\t\")+1, curLen = stack[lev+1] = stack[lev]+s.length()-lev+1;\n            if(s.contains(\".\")) maxLen = Math.max(maxLen, curLen-1);\n        }\n        return maxLen;\n    }\n\n}\n"
  },
  {
    "path": "src/LongestCommonPrefix14.java",
    "content": "/**\n * Write a function to find the longest common prefix string amongst an array of strings.\n */\n\n\npublic class LongestCommonPrefix14 {\n    public String longestCommonPrefix(String[] strs) {\n        String lcp = \"\";\n        int S = strs.length;\n        if (S == 0) return lcp;\n\n        int L = strs[0].length();\n        int idx = 0;\n        for (int i = 1; i < S; i++) {\n            if (strs[i].length() < L) {\n                L = strs[i].length();\n                idx = i;\n            }\n        }\n        if (L == 0) return lcp;\n\n        int p = 1;\n        String possible = strs[idx];\n        while (p <= L) {\n            String sub = possible.substring(0, p);\n            boolean b = true;\n            for (int k = 0; k < S; k++) {\n                if (!strs[k].startsWith(sub)) {\n                    b = false;\n                    break;\n                }\n            }\n            if (!b) break;\n            lcp = sub;\n            p++;\n        }\n\n        return lcp;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/6987/java-code-with-13-lines\n     */\n    public String longestCommonPrefix2(String[] strs) {\n        if(strs == null || strs.length == 0)    return \"\";\n        String pre = strs[0];\n        int i = 1;\n        while(i < strs.length){\n            while(strs[i].indexOf(pre) != 0)\n                pre = pre.substring(0,pre.length()-1);\n            i++;\n        }\n        return pre;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/27913/sorted-the-array-java-solution-2-ms\n     */\n    public String longestCommonPrefix3(String[] strs) {\n        StringBuilder result = new StringBuilder();\n\n        if (strs!= null && strs.length > 0){\n\n            Arrays.sort(strs);\n\n            char [] a = strs[0].toCharArray();\n            char [] b = strs[strs.length-1].toCharArray();\n\n            for (int i = 0; i < a.length; i ++){\n                if (b.length > i && b[i] == a[i]){\n                    result.append(b[i]);\n                }\n                else {\n                    return result.toString();\n                }\n            }\n        }\n        return result.toString();\n    }\n\n}\n"
  },
  {
    "path": "src/LongestConsecutiveSequence128.java",
    "content": "/**\n * Given an unsorted array of integers, find the length of the longest\n * consecutive elements sequence.\n *\n * For example,\n * Given [100, 4, 200, 1, 3, 2],\n * The longest consecutive elements sequence is [1, 2, 3, 4].\n * Return its length: 4.\n *\n * Your algorithm should run in O(n) complexity.\n *\n */\n\n\npublic class LongestConsecutiveSequence128 {\n    public int longestConsecutive(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        Map<Integer, Range> ranges = new HashMap<>();\n        Set<Integer> found = new HashSet<>();\n\n        int res = 1;\n        for (int i=0; i<nums.length; i++) {\n            int val = nums[i];\n            if (found.contains(val)) continue;\n            found.add(val);\n            Range left = ranges.get(val-1);\n            Range right = ranges.get(val+1);\n\n            Range newRange = new Range(val, val);\n            if (left == null && right == null) {\n                ranges.put(val, newRange);\n                continue;\n            }\n            if (left == null) {\n                newRange.r = right.r;\n                ranges.remove(right.l);\n            } else if (right == null) {\n                newRange.l = left.l;\n                ranges.remove(left.r);\n            } else {\n                newRange.l = left.l;\n                newRange.r = right.r;\n                ranges.remove(left.r);\n                ranges.remove(right.l);\n            }\n            ranges.put(newRange.l, newRange);\n            ranges.put(newRange.r, newRange);\n            res = Math.max(res, newRange.r-newRange.l+1);\n        }\n        return res;\n    }\n\n    class Range {\n        int l;\n        int r;\n        Range (int l0,int r0) { l=l0; r=r0; }\n    }\n\n    public int longestConsecutive2(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        Arrays.sort(nums);\n\n        int res = 1;\n        int temp = 1;\n        for (int i = 1; i < nums.length; i++) {\n            if (nums[i] == nums[i-1]) continue;\n            if (nums[i] == nums[i-1]+1) {\n                temp += 1;\n            } else {\n                res = Math.max(res, temp);\n                temp = 1;\n            }\n        }\n\n        return Math.max(res, temp);\n    }\n\n\n    public int longestConsecutive3(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        Set<Integer> set = new HashSet<>();\n        for (int n : nums) set.add(n);\n\n        int res = 1;\n        for (int n : set) {\n            if (set.contains(n-1)) continue;\n            int curr = n;\n            int temp = 1;\n            while (set.contains(curr+1)) {\n                curr += 1;\n                temp += 1;\n            }\n            res = Math.max(res, temp);\n        }\n\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/LongestContinuousIncreasingSubsequence674.java",
    "content": "/**\n * Given an unsorted array of integers, find the length of longest continuous\n * increasing subsequence (subarray).\n * \n * Example 1:\n * Input: [1,3,5,4,7]\n * Output: 3\n * Explanation: The longest continuous increasing subsequence is [1,3,5], its\n * length is 3. \n * Even though [1,3,5,7] is also an increasing subsequence, it's not a\n * continuous one where 5 and 7 are separated by 4. \n * \n * Example 2:\n * Input: [2,2,2,2,2]\n * Output: 1\n * Explanation: The longest continuous increasing subsequence is [2], its\n * length is 1. \n * \n * Note: Length of the array will not exceed 10,000.\n */\n\npublic class LongestContinuousIncreasingSubsequence674 {\n    public int findLengthOfLCIS(int[] nums) {\n        int len = 0;\n        int res = 0;\n        if (nums == null || nums.length == 0) return res; \n        int pre = nums[0]-1;\n        for (int n: nums) {\n            if (n > pre) {\n                len++;\n            } else {\n                res = Math.max(res, len);\n                len = 1;\n            }\n            pre = n;\n        }\n        return Math.max(res, len);\n    }\n\n\n    public int findLengthOfLCIS2(int[] nums) {\n        int count = 0;\n        int res = 0;\n        for (int i=0; i<nums.length; i++) {\n            if (i == 0) {\n                count++;\n            } else {\n                if (nums[i] > nums[i-1]) {\n                    count++;\n                } else {\n                    count = 1;\n                }\n            }\n            res = Math.max(res, count);\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/LongestHarmoniousSubsequence594.java",
    "content": "/**\n * We define a harmonious array is an array where the difference between its\n * maximum value and its minimum value is exactly 1.\n * \n * Now, given an integer array, you need to find the length of its longest\n * harmonious subsequence among all its possible subsequences.\n * \n * Subsequences: https://en.wikipedia.org/wiki/Subsequence\n * \n * Example 1:\n * Input: [1,3,2,2,5,2,3,7]\n * Output: 5\n * Explanation: The longest harmonious subsequence is [3,2,2,2,3].\n * \n * Note: The length of the input array will not exceed 20,000.\n */\n\npublic class LongestHarmoniousSubsequence594 {\n    public int findLHS(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        int res = 0;\n        Map<Integer, Integer> map = new HashMap<>();\n        for (int n: nums) {\n            map.put(n, map.getOrDefault(n, 0)+1);\n            int b = map.get(n);\n            if (map.containsKey(n-1)) {\n                int a = map.get(n-1);\n                if (a + b > res) res = a + b;\n            }\n            if (map.containsKey(n+1)) {\n                int a = map.get(n+1);\n                if (a + b > res) res = a + b;\n            }\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/longest-harmonious-subsequence/solution/\n     */\n    public int findLHS2(int[] nums) {\n        HashMap < Integer, Integer > map = new HashMap < > ();\n        int res = 0;\n        for (int num: nums) {\n            map.put(num, map.getOrDefault(num, 0) + 1);\n        }\n        for (int key: map.keySet()) {\n            if (map.containsKey(key + 1))\n                res = Math.max(res, map.get(key) + map.get(key + 1));\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/longest-harmonious-subsequence/solution/\n     */\n    public int findLHS3(int[] nums) {\n        Arrays.sort(nums);\n        int prev_count = 1, res = 0;\n        for (int i = 0; i < nums.length; i++) {\n            int count = 1;\n            if (i > 0 && nums[i] - nums[i - 1] == 1) {\n                while (i < nums.length - 1 && nums[i] == nums[i + 1]) {\n                    count++;\n                    i++;\n                }\n                res = Math.max(res, count + prev_count);\n                prev_count = count;\n            } else {\n                while (i < nums.length - 1 && nums[i] == nums[i + 1]) {\n                    count++;\n                    i++;\n                }\n                prev_count = count;\n            }\n        }\n        return res;\n    }\n\n\n    public int findLHS4(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        Arrays.sort(nums);\n        int N = nums.length;\n        int res = 0;\n        int preCount = -1;\n        int pre = 0;\n        int count = 1;\n        int curr = nums[0];\n        int i = 1;\n        while (i < N && nums[i] == curr) {\n            count++;\n            i++;\n        }\n        while (i < N) {\n            if (nums[i] == curr) {\n                count++;\n            } else {\n                if (preCount != -1 && curr == pre + 1 && (count + preCount) > res) {\n                    res = count + preCount;\n                }\n                preCount = count;\n                pre = curr;\n                count = 1;\n                curr = nums[i];\n            }\n            i++;\n        }\n        if (preCount != -1 && curr == pre + 1 && (count + preCount) > res) {\n            res = count + preCount;\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/LongestIncreasingSubsequence300.java",
    "content": "/**\n * Given an unsorted array of integers, find the length of longest increasing\n * subsequence.\n *\n * For example,\n * Given [10, 9, 2, 5, 3, 7, 101, 18],\n * The longest increasing subsequence is [2, 3, 7, 101], therefore the length\n * is 4. Note that there may be more than one LIS combination, it is only\n * necessary for you to return the length.\n *\n * Your algorithm should run in O(n2) complexity.\n *\n * Follow up: Could you improve it to O(n log n) time complexity?\n */\n\npublic class LongestIncreasingSubsequence300 {\n    public int lengthOfLIS(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        int N = nums.length;\n        int[] dp = new int[N + 1];\n        int res = 0;\n        for (int i=1; i<=N; i++) {\n            dp[i] = 1;\n            for (int j=1; j<i; j++) {\n                if (nums[i-1] > nums[j-1]) {\n                    dp[i] = Math.max(dp[i], dp[j] + 1);\n                }\n            }\n            if (dp[i] > res) res = dp[i];\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/longest-increasing-subsequence/solution/\n     * https://www.geeksforgeeks.org/longest-monotonically-increasing-subsequence-size-n-log-n/\n     */\n    public int lengthOfLIS2(int[] nums) {\n        int[] dp = new int[nums.length];\n        int len = 0;\n        for (int num : nums) {\n            int i = Arrays.binarySearch(dp, 0, len, num);\n            if (i < 0) {\n                i = -(i + 1);\n            }\n            dp[i] = num;\n            if (i == len) {\n                len++;\n            }\n        }\n        return len;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/longest-increasing-subsequence/solution/\n     */\n    public int lengthOfLIS3(int[] nums) {\n        int memo[][] = new int[nums.length + 1][nums.length];\n        for (int[] l : memo) {\n            Arrays.fill(l, -1);\n        }\n        return lengthofLIS(nums, -1, 0, memo);\n    }\n\n    public int lengthofLIS(int[] nums, int previndex, int curpos, int[][] memo) {\n        if (curpos == nums.length) {\n            return 0;\n        }\n        if (memo[previndex + 1][curpos] >= 0) {\n            return memo[previndex + 1][curpos];\n        }\n        int taken = 0;\n        if (previndex < 0 || nums[curpos] > nums[previndex]) {\n            taken = 1 + lengthofLIS(nums, curpos, curpos + 1, memo);\n        }\n\n        int nottaken = lengthofLIS(nums, previndex, curpos + 1, memo);\n        memo[previndex + 1][curpos] = Math.max(taken, nottaken);\n        return memo[previndex + 1][curpos];\n    }\n\n\n    /**\n     * https://leetcode.com/problems/longest-increasing-subsequence/discuss/74824/JavaPython-Binary-search-O(nlogn)-time-with-explanation\n     */\n    public int lengthOfLIS4(int[] nums) {\n        int[] tails = new int[nums.length];\n        int size = 0;\n        for (int x : nums) {\n            int i = 0, j = size;\n            while (i != j) {\n                int m = (i + j) / 2;\n                if (tails[m] < x)\n                    i = m + 1;\n                else\n                    j = m;\n            }\n            tails[i] = x;\n            if (i == size) ++size;\n        }\n        return size;\n    }\n\n}\n"
  },
  {
    "path": "src/LongestMountainInArray845.java",
    "content": "/**\n * Let's call any (contiguous) subarray B (of A) a mountain if the following\n * properties hold:\n * - B.length >= 3\n * - There exists some 0 < i < B.length - 1 such that\n * B[0] < B[1] < ... B[i-1] < B[i] > B[i+1] > ... > B[B.length - 1]\n * (Note that B could be any subarray of A, including the entire array A.)\n * \n * Given an array A of integers, return the length of the longest mountain. \n * \n * Return 0 if there is no mountain.\n * \n * Example 1:\n * Input: [2,1,4,7,3,2,5]\n * Output: 5\n * Explanation: The largest mountain is [1,4,7,3,2] which has length 5.\n * \n * Example 2:\n * Input: [2,2,2]\n * Output: 0\n * Explanation: There is no mountain.\n * \n * Note:\n * 0 <= A.length <= 10000\n * 0 <= A[i] <= 10000\n * \n * Follow up:\n * Can you solve it using only one pass?\n * Can you solve it in O(1) space?\n */\n\npublic class LongestMountainInArray845 {\n    public int longestMountain(int[] A) {\n        if (A == null || A.length < 3) return 0;\n        int len = A.length;\n        boolean up = false;\n        boolean down = false;\n        int left = 0;\n        int longest = 0;\n        for (int i=1; i<len; i++) {\n            if (A[i] == A[i-1]) {\n                left = i;\n                up = false;\n                down = false;\n            } else if (A[i] > A[i-1]) {\n                if (!(up && !down)) {\n                    up = true;\n                    down = false;\n                    left = i-1;\n                }\n            } else {\n                down = up;\n                if (!up) {\n                    left = i;\n                }\n            }\n            \n            if (up && down && i - left + 1 > longest) {\n                longest = i - left + 1;\n            }\n        }\n        return longest;\n    }\n\n}\n"
  },
  {
    "path": "src/LongestPalindrome409.java",
    "content": "/**\n * Given a string which consists of lowercase or uppercase letters, find the\n * length of the longest palindromes that can be built with those letters.\n * \n * This is case sensitive, for example \"Aa\" is not considered a palindrome here.\n * \n * Note:\n * Assume the length of given string will not exceed 1,010.\n * \n * Example:\n * Input:\n * \"abccccdd\"\n * Output:\n * 7\n * \n * Explanation:\n * One longest palindrome that can be built is \"dccaccd\", whose length is 7.\n */\n\npublic class LongestPalindrome409 {\n    public int longestPalindrome(String s) {\n        Map<Character, Integer> map = new HashMap<>();\n        for (char ch: s.toCharArray()) {\n            map.put(ch, map.getOrDefault(ch, 0) + 1);\n        }\n        \n        int res = 0;\n        boolean hasOdd = false;\n        for (int i: map.values()) {\n            if (i % 2 == 0) {\n                res += i;\n            } else {\n                res += i - 1;\n                hasOdd = true;\n            }\n        }\n        return res + (hasOdd ? 1 : 0);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/longest-palindrome/discuss/89604/Simple-HashSet-solution-Java\n     */\n    public int longestPalindrome2(String s) {\n        if(s==null || s.length()==0) return 0;\n        HashSet<Character> hs = new HashSet<Character>();\n        int count = 0;\n        for(int i=0; i<s.length(); i++){\n            if(hs.contains(s.charAt(i))){\n                hs.remove(s.charAt(i));\n                count++;\n            }else{\n                hs.add(s.charAt(i));\n            }\n        }\n        if(!hs.isEmpty()) return count*2+1;\n        return count*2;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/longest-palindrome/discuss/89610/Simple-Java-Solution-in-One-Pass\n     */\n    public int longestPalindrome3(String s) {\n        boolean[] map = new boolean[128];\n        int len = 0;\n        for (char c : s.toCharArray()) {\n            map[c] = !map[c];         // flip on each occurrence, false when seen n*2 times\n            if (!map[c]) len+=2;\n        }\n        if (len < s.length()) len++; // if more than len, atleast one single is present\n        return len;\n    }\n\n}\n"
  },
  {
    "path": "src/LongestPalindromicSubsequence516.java",
    "content": "/**\n * Given a string s, find the longest palindromic subsequence's length in s.\n * You may assume that the maximum length of s is 1000.\n * \n * Example 1:\n * Input:\n * \"bbbab\"\n * Output:\n * 4\n * One possible longest palindromic subsequence is \"bbbb\".\n * \n * Example 2:\n * Input:\n * \"cbbd\"\n * Output:\n * 2\n * One possible longest palindromic subsequence is \"bb\".\n */\n\npublic class LongestPalindromicSubsequence516 {\n    public int longestPalindromeSubseq(String s) {\n        if (s == null || s.length() == 0) return 0;\n        int len = s.length();\n        char[] chars = s.toCharArray();\n        int[][] dp = new int[len][len];\n        for (int i=len-1; i>=0; i--) {\n            dp[i][i] = 1;\n            for (int j=i+1; j<len; j++) {\n                int notEqual = Math.max(dp[i+1][j], dp[i][j-1]);\n                int equal = 1;\n                if (i + 1 == j) {\n                    if (chars[i] == chars[j]) {\n                        equal = 2;\n                    }\n                } else {\n                    equal = dp[i+1][j-1] + (chars[i] == chars[j] ? 2 : 0);\n                }\n                dp[i][j] = Math.max(equal, notEqual);\n            }\n        }\n        return dp[0][len-1];\n    }\n\n\n    public int longestPalindromeSubseq2(String s) {\n        if (s == null || s.length() == 0) return 0;\n        int len = s.length();\n        return helper(s.toCharArray(), 0, len-1, new int[len][len]);\n    }\n    \n    private int helper(char[] chars, int i, int j, int[][] dp) {\n        if (dp[i][j] != 0) return dp[i][j];\n        if (i > j) return 0;\n        if (i == j) return 1;\n        if (chars[i] == chars[j]) {\n            dp[i][j] = helper(chars, i+1, j-1, dp) + 2;\n        } else {\n            dp[i][j] = Math.max(helper(chars, i+1, j, dp), helper(chars, i, j-1, dp));\n        }\n        return dp[i][j];\n    }\n\n}\n"
  },
  {
    "path": "src/LongestPalindromicSubstring5.java",
    "content": "/**\n * Given a string s, find the longest palindromic substring in s. You may\n * assume that the maximum length of s is 1000.\n *\n * Example:\n *\n * Input: \"babad\"\n *\n * Output: \"bab\"\n *\n * Note: \"aba\" is also a valid answer.\n * Example:\n *\n * Input: \"cbbd\"\n *\n * Output: \"bb\"\n */\n\n\nimport java.util.Arrays;\n\npublic class LongestPalindromicSubstring5 {\n    public String longestPalindrome(String s) {\n        char[] input = s.toCharArray();\n        int length = input.length;\n        if (length == 1) {\n            return s;\n        }\n\n        String output = \"\";\n        for (int i = 0; i < length; i++) {\n            for (int j = 0; j < 2; j++) {\n                int left = i;\n                int right = i + j;\n                while (left >= 0 && right < length && input[left] == input[right]) {\n                    left--;\n                    right++;\n                }\n                left++;\n                right--;\n                if (output.length() < right - left + 1) {\n                    output = String.valueOf(Arrays.copyOfRange(input, left, right+1));\n                }\n            }\n        }\n\n        return output;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/23498/very-simple-clean-java-solution\n     */\n    private int lo, maxLen;\n\n    public String longestPalindrome2(String s) {\n      \tint len = s.length();\n      \tif (len < 2) return s;\n        for (int i = 0; i < len-1; i++) {\n            extendPalindrome(s, i, i);  //assume odd length, try to extend Palindrome as possible\n            extendPalindrome(s, i, i+1); //assume even length.\n        }\n        return s.substring(lo, lo + maxLen);\n    }\n\n    private void extendPalindrome(String s, int j, int k) {\n      \twhile (j >= 0 && k < s.length() && s.charAt(j) == s.charAt(k)) {\n            j--;\n            k++;\n      \t}\n      \tif (maxLen < k - j - 1) {\n            lo = j + 1;\n            maxLen = k - j - 1;\n      \t}\n    }\n\n\n    /**\n     * https://leetcode.com/problems/longest-palindromic-substring/discuss/2921/Share-my-Java-solution-using-dynamic-programming\n     */\n    public String longestPalindrome3(String s) {\n        int n = s.length();\n        String res = null;\n        boolean[][] dp = new boolean[n][n];\n        for (int i = n - 1; i >= 0; i--) {\n            for (int j = i; j < n; j++) {\n                dp[i][j] = s.charAt(i) == s.charAt(j) && (j - i < 3 || dp[i + 1][j - 1]);\n\n                if (dp[i][j] && (res == null || j - i + 1 > res.length())) {\n                    res = s.substring(i, j + 1);\n                }\n            }\n        }\n        return res;\n    }\n\n\n    public String longestPalindrome4(String s) {\n        if (s == null || s.length() <= 1) return s;\n        int N = s.length();\n        int[][] dp = new int[N][N];\n        \n        char[] chars = s.toCharArray();\n        int end = -1;\n        int len = Integer.MIN_VALUE;\n        for (int i=N-1; i>=0; i--) {\n            for (int j=i; j<N; j++) {\n                if (i == j) {\n                    dp[i][j] = 1;\n                } else if (i == j - 1) {\n                    dp[i][j] = chars[i] == chars[j] ? 2 : 1;\n                } else {\n                    if (chars[i] == chars[j] && dp[i+1][j-1] == (j-i-1)) {\n                        dp[i][j] = j-i+1;\n                    }\n                    \n                    dp[i][j] = Math.max(dp[i][j], dp[i+1][j]);\n                }\n                if (dp[i][j] > len) {\n                    len = dp[i][j];\n                    end = j;\n                }\n            }\n        }\n        return s.substring(end+1-len, end+1);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/longest-palindromic-substring/solution/\n     */\n    public String longestPalindrome5(String s) {\n        if (s == null || s.length() < 1) return \"\";\n        int start = 0, end = 0;\n        for (int i = 0; i < s.length(); i++) {\n            int len1 = expandAroundCenter(s, i, i);\n            int len2 = expandAroundCenter(s, i, i + 1);\n            int len = Math.max(len1, len2);\n            if (len > end - start) {\n                start = i - (len - 1) / 2;\n                end = i + len / 2;\n            }\n        }\n        return s.substring(start, end + 1);\n    }\n\n    private int expandAroundCenter(String s, int left, int right) {\n        int L = left, R = right;\n        while (L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)) {\n            L--;\n            R++;\n        }\n        return R - L - 1;\n    }\n\n}\n"
  },
  {
    "path": "src/LongestRepeatingCharacterReplacement424.java",
    "content": "/**\n * Given a string that consists of only uppercase English letters, you can\n * replace any letter in the string with another letter at most k times. Find\n * the length of a longest substring containing all repeating letters you can\n * get after performing the above operations.\n * \n * Note:\n * Both the string's length and k will not exceed 104.\n * \n * Example 1:\n * Input:\n * s = \"ABAB\", k = 2\n * Output:\n * 4\n * \n * Explanation:\n * Replace the two 'A's with two 'B's or vice versa.\n * \n * Example 2:\n * Input:\n * s = \"AABABBA\", k = 1\n * Output:\n * 4\n * \n * Explanation:\n * Replace the one 'A' in the middle with 'B' and form \"AABBBBA\".\n * The substring \"BBBB\" has the longest repeating letters, which is 4.\n */\n\npublic class LongestRepeatingCharacterReplacement424 {\n    public int characterReplacement(String s, int k) {\n        if (s == null || s.length() == 0) return 0;\n        int N = s.length();\n        char[] chars = s.toCharArray();\n        int[] map = new int[26];\n        Comparator<Point> comp = (p1, p2) -> Integer.compare(p2.count, p1.count);\n        PriorityQueue<Point> pq = new PriorityQueue(26, comp);\n        int res = 0;\n        int left = 0;\n        int right = 0;\n        while (right < N) {\n            char c = chars[right++];\n            pq.remove(new Point(c, map[c-'A']));\n            pq.add(new Point(c, map[c-'A'] + 1));\n            map[c-'A']++;\n\n            while (right - left - pq.peek().count > k) {\n                char leftC = chars[left++];\n                pq.remove(new Point(leftC, map[leftC-'A']));\n                pq.add(new Point(leftC, map[leftC-'A'] - 1));\n                map[leftC-'A']--;\n            }\n            if (right - left > res) {\n                res = right - left;\n            }\n        }\n        \n        return res;\n    }\n\n    class Point {\n        char ch;\n        int count;\n        Point(char c, int cnt) {\n            ch = c;\n            count = cnt;\n        }\n    }\n\n\n    public int characterReplacement2(String s, int k) {\n        if (s == null || s.length() == 0) return 0;\n        int N = s.length();\n        char[] chars = s.toCharArray();\n        int[] map = new int[26];\n        int res = 0;\n        int left = 0;\n        int right = 0;\n        while (right < N) {\n            char c = chars[right++];\n            map[c-'A']++;\n\n            while (right - left - getMax(map) > k) {\n                char leftC = chars[left++];\n                map[leftC-'A']--;\n            }\n            if (right - left > res) {\n                res = right - left;\n            }\n        }\n        \n        return res;\n    }\n\n    private int getMax(int[] map) {\n        int res = 0;\n        for (int c: map) {\n            if (c > res) {\n                res = c;\n            }\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/longest-repeating-character-replacement/discuss/91271/Java-12-lines-O(n)-sliding-window-solution-with-explanation\n     * \n     * maxCount may be invalid at some points, but this doesn't matter, because\n     * it was valid earlier in the string, and all that matters is finding the\n     * max window that occurred anywhere in the string. Additionally, it will\n     * expand if and only if enough repeating characters appear in the window\n     * to make it expand. So whenever it expands, it's a valid expansion.\n     */\n    public int characterReplacement3(String s, int k) {\n        int len = s.length();\n        int[] count = new int[26];\n        int start = 0, maxCount = 0, maxLength = 0;\n        for (int end = 0; end < len; end++) {\n            maxCount = Math.max(maxCount, ++count[s.charAt(end) - 'A']);\n            while (end - start + 1 - maxCount > k) {\n                count[s.charAt(start) - 'A']--;\n                start++;\n            }\n            maxLength = Math.max(maxLength, end - start + 1);\n        }\n        return maxLength;\n    }\n\n}\n"
  },
  {
    "path": "src/LongestSubstringWithAtMostKDistinctCharacters340.java",
    "content": "/**\n * Given a string, find the length of the longest substring T that contains\n * at most k distinct characters.\n * \n * For example, Given s = “eceba” and k = 2,\n * \n * T is \"ece\" which its length is 3.\n */\n\n\npublic class LongestSubstringWithAtMostKDistinctCharacters340 {\n    public int lengthOfLongestSubstringKDistinct(String s, int k) {\n        if (s == null || s.length() == 0) return 0;\n        int len = s.length();\n        int left = 0;\n        int right = 0;\n        int res = 0;\n        int count = 0;\n        int[] map = new int[256];\n        char[] chars = s.toCharArray();\n        while (right < len) {\n            if (map[chars[right]] == 0) {\n                count++;\n            }\n            map[chars[right]]++;\n            right++;\n            \n            if (count <= k && right - left > res) {\n                res = right - left;\n            }\n            while (count == k + 1) {\n                map[chars[left]]--;\n                if (map[chars[left]] == 0) {\n                    count--;\n                }\n                left++;\n            }\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/discuss/80044/Java-O(nlogk)-using-TreeMap-to-keep-last-occurrence-Interview-%22follow-up%22-question!\n     */\n    public int lengthOfLongestSubstringKDistinct2(String str, int k) {\n        if (str == null || str.isEmpty() || k == 0) {\n            return 0;\n        }\n        TreeMap<Integer, Character> lastOccurrence = new TreeMap<>();\n        Map<Character, Integer> inWindow = new HashMap<>();\n        int j = 0;\n        int max = 1;\n        for (int i = 0; i < str.length(); i++) {\n            char in = str.charAt(i);\n            while (inWindow.size() == k && !inWindow.containsKey(in)) {\n                int first = lastOccurrence.firstKey();\n                char out = lastOccurrence.get(first);\n                inWindow.remove(out);\n                lastOccurrence.remove(first);\n                j = first + 1;\n            }\n            //update or add in's position in both maps\n            if (inWindow.containsKey(in)) {\n                lastOccurrence.remove(inWindow.get(in));\n            }\n            inWindow.put(in, i);\n            lastOccurrence.put(i, in);\n            max = Math.max(max, i - j + 1);\n        }\n        return max;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/discuss/80082/Solution-to-the-follow-up\n     */\n    public int lengthOfLongestSubstringKDistinct3(String s, int k) {\n        if(s==null || s.length()==0 || k<=0) return 0;\n        int len=s.length();\n        int i=0, j=0;\n        int maxLen=0;\n        LinkedHashMap<Character,Integer> map=new LinkedHashMap<Character,Integer>();\n        for(char x:s.toCharArray()){\n            if(map.containsKey(x)){\n                map.remove(x);\n                map.put(x,j);\n            }else{\n                if(map.size()==k){\n                    maxLen=Math.max(maxLen,j-i);\n                    char toRemove=map.keySet().iterator().next();\n                    i=map.get(toRemove)+1;\n                    map.remove(toRemove);\n                }\n                map.put(x,j);\n            }\n            j++;\n        }\n        maxLen=Math.max(maxLen,j-i);\n        return maxLen;\n    }\n\n}\n"
  },
  {
    "path": "src/LongestSubstringWithAtMostTwoDistinctCharacters159.java",
    "content": "/**\n * Given a string s , find the length of the longest substring t  that contains\n * at most 2 distinct characters.\n * \n * Example 1:\n * Input: \"eceba\"\n * Output: 3\n * Explanation: t is \"ece\" which its length is 3.\n * \n * Example 2:\n * Input: \"ccaabbb\"\n * Output: 5\n * Explanation: t is \"aabbb\" which its length is 5.\n */\n\npublic class LongestSubstringWithAtMostTwoDistinctCharacters159 {\n    public int lengthOfLongestSubstringTwoDistinct(String s) {\n        return lengthOfLongestSubstringKDistinct(s, 2);\n    }\n\n    // 340. Longest Substring with At Most K Distinct Characters\n    public int lengthOfLongestSubstringKDistinct(String s, int k) {\n        if (s == null || s.length() == 0 || k == 0) return 0;\n        int[] map = new int[256];\n        int left = 0;\n        int right = 0;\n        int N = s.length();\n        char[] chars = s.toCharArray();\n        int num = 0;\n        int res = 0;\n        while (right < N) {\n            char c = chars[right++];\n            if (map[c] == 0) {\n                num++;\n            }\n            map[c]++;\n            \n            while (num > k) {\n                char leftC = chars[left++];\n                if (map[leftC] == 1) {\n                    num--;\n                }\n                map[leftC]--;\n            }\n            if (right - left > res) {\n                res = right - left;\n            }\n        }\n        \n        return res;\n    }\n}\n"
  },
  {
    "path": "src/LongestSubstringWithoutRepeatingCharacters3.java",
    "content": "/**\n * Given a string, find the length of the longest substring without repeating characters.\n *\n * Examples:\n *\n * Given \"abcabcbb\", the answer is \"abc\", which the length is 3.\n *\n * Given \"bbbbb\", the answer is \"b\", with the length of 1.\n *\n * Given \"pwwkew\", the answer is \"wke\", with the length of 3. Note that the\n * answer must be a substring, \"pwke\" is a subsequence and not a substring.\n */\n\n\nimport java.util.Map;\nimport java.util.HashMap;\n\n\npublic class LongestSubstringWithoutRepeatingCharacters3 {\n    public int lengthOfLongestSubstring(String s) {\n        if (s.length() < 2) {\n            return s.length();\n        }\n\n        int start = 0;\n        int ll = 1;\n        Map<Character, Integer> found = new HashMap<>();\n        found.put(s.charAt(0), 0);\n        int i;\n        for (i = 1; i < s.length(); i++) {\n            if (found.containsKey(s.charAt(i))) {\n                int newStart = remove(start, i, s.charAt(i), found, s);\n\n                if (i - start > ll) {\n                    ll = i - start;\n                }\n                start = newStart;\n            } else {\n                found.put(s.charAt(i), i);\n            }\n        }\n\n        return Math.max(ll, i - start);\n    }\n\n    private int remove(int start, int now, char re, Map<Character, Integer> found, String s) {\n        int j;\n        for (j = start; j < now; j++) {\n            if (s.charAt(j) == re) {\n                found.remove(s.charAt(j));\n                break;\n            }\n            found.remove(s.charAt(j));\n        }\n        found.put(s.charAt(now), now);\n        return j + 1;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/8232/11-line-simple-java-solution-o-n-with-explanation\n     */\n    public int lengthOfLongestSubstring2(String s) {\n         if (s.length()==0) return 0;\n         HashMap<Character, Integer> map = new HashMap<Character, Integer>();\n         int max=0;\n         for (int i=0, j=0; i<s.length(); ++i){\n             if (map.containsKey(s.charAt(i))){\n                 j = Math.max(j,map.get(s.charAt(i))+1);\n             }\n             map.put(s.charAt(i),i);\n             max = Math.max(max,i-j+1);\n         }\n         return max;\n     }\n\n\n     public int lengthOfLongestSubstring3(String s) {\n         int [] map = new int[256];\n         for(int i = 0; i < map.length; i++){\n             map[i] = -1;\n         }\n         int max = 0;\n         int pos = -1;\n         for(int i = 0; i < s.length(); i++){\n             pos = Math.max(pos, map[(int)s.charAt(i)]);\n             max = Math.max(max, i - pos);\n             map[(int)s.charAt(i)] = i;\n         }\n         return max;\n     }\n\n\n     public int lengthOfLongestSubstring4(String s) {\n        if (s == null || s.length() == 0) return 0;\n        int[] map = new int[256];\n        int left = 0;\n        int right = 0;\n        int N = s.length();\n        char[] chars = s.toCharArray();\n        int maxLen = 0;\n        while (right < N) {\n            char curr = chars[right++];\n            map[curr]++;\n            if (map[curr] == 1 && right - left > maxLen) {\n                maxLen = right - left;\n            }\n            while (map[curr] > 1) {\n                char leftChar = chars[left++];\n                map[leftChar]--;\n            }\n        }\n        return maxLen;\n    }\n\n}\n"
  },
  {
    "path": "src/LongestUnivaluePath687.java",
    "content": "/**\n * Given a binary tree, find the length of the longest path where each node in\n * the path has the same value. This path may or may not pass through the root.\n * \n * Note: The length of path between two nodes is represented by the number of edges between them.\n * \n * Example 1:\n * Input:\n * \n *               5\n *              / \\\n *             4   5\n *            / \\   \\\n *           1   1   5\n * Output: 2\n * \n * Example 2:\n * Input:\n * \n *               1\n *              / \\\n *             4   5\n *            / \\   \\\n *           4   4   5\n * Output: 2\n * \n * Note: The given binary tree has not more than 10000 nodes. The height of the\n * tree is not more than 1000.\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class LongestUnivaluePath687 {\n    public int longestUnivaluePath(TreeNode root) {\n        if (root == null) return 0;\n        return helper(root)[1];\n    }\n\n    private int[] helper(TreeNode root) {\n        int[] res = new int[]{0, 0};\n        if (root.left != null && root.right != null) {\n            int[] left = helper(root.left);\n            int[] right = helper(root.right);\n            if (root.val == root.left.val && root.val == root.right.val) {\n                res[0] = Math.max(left[0], right[0]) + 1;\n                res[1] = left[0] + right[0] + 2;\n            } else if (root.val == root.left.val) {\n                res[0] = left[0] + 1;\n            } else if (root.val == root.right.val) {\n                res[0] = right[0] + 1;\n            }\n            res[1] = Math.max(Math.max(Math.max(left[1], right[1]), res[1]), res[0]);\n        } else if (root.left != null) {\n            int[] left = helper(root.left);\n            res[0] = root.val == root.left.val ? left[0] + 1 : 0;\n            res[1] = Math.max(left[1], res[0]);\n        } else if (root.right != null) {\n            int[] right = helper(root.right);\n            res[0] = root.val == root.right.val ? right[0] + 1 : 0;\n            res[1] = Math.max(right[1], res[0]);\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/longest-univalue-path/solution/\n     */\n    int ans;\n    public int longestUnivaluePath2(TreeNode root) {\n        ans = 0;\n        arrowLength(root);\n        return ans;\n    }\n    public int arrowLength(TreeNode node) {\n        if (node == null) return 0;\n        int left = arrowLength(node.left);\n        int right = arrowLength(node.right);\n        int arrowLeft = 0, arrowRight = 0;\n        if (node.left != null && node.left.val == node.val) {\n            arrowLeft += left + 1;\n        }\n        if (node.right != null && node.right.val == node.val) {\n            arrowRight += right + 1;\n        }\n        ans = Math.max(ans, arrowLeft + arrowRight);\n        return Math.max(arrowLeft, arrowRight);\n    }\n\n\n}\n"
  },
  {
    "path": "src/LongestValidParentheses32.java",
    "content": "/**\n * Given a string containing just the characters '(' and ')', find the length\n * of the longest valid (well-formed) parentheses substring.\n * \n * Example 1:\n * Input: \"(()\"\n * Output: 2\n * Explanation: The longest valid parentheses substring is \"()\"\n * \n * Example 2:\n * Input: \")()())\"\n * Output: 4\n * Explanation: The longest valid parentheses substring is \"()()\"\n */\n\n\npublic class LongestValidParentheses32 {\n    public int longestValidParentheses(String s) {\n        int len = s.length();\n        if (len <= 1) return 0;\n        boolean[] valid = new boolean[len];\n        Stack<Integer> stack = new Stack<>();\n        char[] chars = s.toCharArray();\n        for (int i=0; i<len; i++) {\n            if (chars[i] == '(') {\n                stack.push(i);\n            } else {\n                if (!stack.isEmpty())  {\n                    int left = stack.pop();\n                    valid[left] = true;\n                    valid[i] = true;\n                }\n            }\n        }\n        \n        int curr = 0;\n        int max = 0;\n        for (int i=0; i<len; i++) {\n            if (valid[i]) {\n                curr++;\n            } else {\n                max = Math.max(max, curr);\n                curr = 0;\n            }\n        }\n        return Math.max(max, curr);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/longest-valid-parentheses/solution/\n     */\n    public int longestValidParentheses2(String s) {\n        int maxans = 0;\n        Stack<Integer> stack = new Stack<>();\n        stack.push(-1);\n        for (int i = 0; i < s.length(); i++) {\n            if (s.charAt(i) == '(') {\n                stack.push(i);\n            } else {\n                stack.pop();\n                if (stack.empty()) {\n                    stack.push(i);\n                } else {\n                    maxans = Math.max(maxans, i - stack.peek());\n                }\n            }\n        }\n        return maxans;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/longest-valid-parentheses/solution/\n     */\n    public int longestValidParentheses3(String s) {\n        int left = 0, right = 0, maxlength = 0;\n        for (int i = 0; i < s.length(); i++) {\n            if (s.charAt(i) == '(') {\n                left++;\n            } else {\n                right++;\n            }\n            if (left == right) {\n                maxlength = Math.max(maxlength, 2 * right);\n            } else if (right >= left) {\n                left = right = 0;\n            }\n        }\n        left = right = 0;\n        for (int i = s.length() - 1; i >= 0; i--) {\n            if (s.charAt(i) == '(') {\n                left++;\n            } else {\n                right++;\n            }\n            if (left == right) {\n                maxlength = Math.max(maxlength, 2 * left);\n            } else if (left >= right) {\n                left = right = 0;\n            }\n        }\n        return maxlength;\n    }\n\n}\n\n"
  },
  {
    "path": "src/LongestWordInDictionary720.java",
    "content": "/**\n * Given a list of strings words representing an English Dictionary, find the\n * longest word in words that can be built one character at a time by other\n * words in words. If there is more than one possible answer, return the\n * longest word with the smallest lexicographical order.\n * \n * If there is no answer, return the empty string.\n * \n * Example 1:\n * Input: \n * words = [\"w\",\"wo\",\"wor\",\"worl\", \"world\"]\n * Output: \"world\"\n * Explanation: \n * The word \"world\" can be built one character at a time by \"w\", \"wo\", \"wor\", and \"worl\".\n * \n * Example 2:\n * Input: \n * words = [\"a\", \"banana\", \"app\", \"appl\", \"ap\", \"apply\", \"apple\"]\n * Output: \"apple\"\n * Explanation: \n * Both \"apply\" and \"apple\" can be built from other words in the dictionary.\n * However, \"apple\" is lexicographically smaller than \"apply\".\n * \n * Note:\n * All the strings in the input will only contain lowercase letters.\n * The length of words will be in the range [1, 1000].\n * The length of words[i] will be in the range [1, 30].\n */\n\npublic class LongestWordInDictionary720 {\n    public String longestWord(String[] words) {\n        Arrays.sort(words);\n        int N = words.length;\n        String res = \"\";\n        Stack<String> stack = new Stack<>();\n        for (int i=0; i<N; i++) {\n            while (!stack.isEmpty() && stack.peek().length() >= words[i].length()) {\n                stack.pop();\n            }\n            String curr = stack.isEmpty() ? \"\" : stack.peek();\n            if (curr.length() + 1 == words[i].length() && words[i].startsWith(curr)) {\n                stack.push(words[i]);\n            }\n            if (!stack.isEmpty() && stack.peek().length() > res.length()) {\n                res = stack.peek();\n            }\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/longest-word-in-dictionary/discuss/109114/JavaC%2B%2B-Clean-Code\n     */\n    public String longestWord2(String[] words) {\n        Arrays.sort(words);\n        Set<String> built = new HashSet<String>();\n        String res = \"\";\n        for (String w : words) {\n            if (w.length() == 1 || built.contains(w.substring(0, w.length() - 1))) {\n                res = w.length() > res.length() ? w : res;\n                built.add(w);\n            }\n        }\n        return res;\n    }\n\n\n    public String longestWord3(String[] words) {\n        Trie trie = constructTrie(words);\n        trie.isWord = true;\n        String[] res = new String[]{\"\"};\n        dfs(trie, new StringBuilder(), res);\n        return res[0];\n    }\n  \n    private void dfs(Trie trie, StringBuilder sb, String[] res) {\n        if (trie == null || !trie.isWord) return;\n        if (sb.length() > res[0].length()) {\n            res[0] = sb.toString();\n        }\n        for (char ch='a'; ch<='z'; ch++) {\n            Trie child = trie.children[ch-'a'];\n            if (child == null) continue;\n            sb.append(ch);\n            dfs(child, sb, res);\n            sb.deleteCharAt(sb.length()-1);\n        }\n    }\n    \n    private Trie constructTrie(String[] words) {\n        Trie trie = new Trie();\n        for (String word: words) {\n            trie.add(word);\n        }\n        return trie;\n    }\n    \n    \n    class Trie {\n        Trie[] children = new Trie[26];\n        boolean isWord;\n        \n        void add(String word) {\n            add(word.toCharArray(), 0);\n        }\n        \n        void add(char[] word, int i) {\n            if (i == word.length) {\n                this.isWord = true;\n                return;\n            }\n            int idx = word[i] - 'a';\n            if (this.children[idx] == null) {\n                this.children[idx] = new Trie();\n            }\n            this.children[idx].add(word, i+1);\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/LowestCommonAncestorOfABinarySearchTree235.java",
    "content": "/**\n * Given a binary search tree (BST), find the lowest common ancestor (LCA) of\n * two given nodes in the BST.\n * \n * According to the definition of LCA on Wikipedia: “The lowest common ancestor\n * is defined between two nodes p and q as the lowest node in T that has both p\n * and q as descendants (where we allow a node to be a descendant of itself).”\n * \n * Given binary search tree:  root = [6,2,8,0,4,7,9,null,null,3,5]\n * \n *         _______6______\n *        /              \\\n *     ___2__          ___8__\n *    /      \\        /      \\\n *    0      _4       7       9\n *          /  \\\n *          3   5\n * \n * Example 1:\n * Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8\n * Output: 6\n * Explanation: The LCA of nodes 2 and 8 is 6.\n * \n * Example 2:\n * Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4\n * Output: 2\n * Explanation: The LCA of nodes 2 and 4 is 2, since a node can be a descendant\n * of itself according to the LCA definition.\n * \n * Note:\n * All of the nodes' values will be unique.\n * p and q are different and both values will exist in the BST.\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class LowestCommonAncestorOfABinarySearchTree235 {\n    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {\n        if (root == null) return root;\n        \n        if (p.val > root.val && q.val > root.val) {\n            return lowestCommonAncestor(root.right, p, q);\n        } else if (p.val < root.val && q.val < root.val) {\n            return lowestCommonAncestor(root.left, p, q);\n        } else {\n            return root;\n        }\n        \n    }\n\n\n    public TreeNode lowestCommonAncestor2(TreeNode root, TreeNode p, TreeNode q) {\n        while ((root.val - p.val) * (root.val - q.val) > 0)\n            root = p.val < root.val ? root.left : root.right;\n        return root;\n    }\n\n\n    public TreeNode lowestCommonAncestor3(TreeNode root, TreeNode p, TreeNode q) {\n        return (root.val - p.val) * (root.val - q.val) < 1 ? root :\n              lowestCommonAncestor(p.val < root.val ? root.left : root.right, p, q);\n    }\n\n\n    // in case the node p or q is not in the BST\n    public TreeNode lowestCommonAncestor4(TreeNode root, TreeNode p, TreeNode q) {\n        if (root == null || p == null || q == null) return null;\n        \n        if (root.val > p.val && root.val > q.val) {\n            return lowestCommonAncestor(root.left, p, q);\n        } else if (root.val < p.val && root.val < q.val) {\n            return lowestCommonAncestor(root.right, p, q);\n        } else if (find(root, p) && find(root, q)) {\n            return root;\n        } else {\n            return null;\n        }\n    }\n\n    private boolean find(TreeNode root, TreeNode n) {\n        if (root == null || n == null) return false;\n        \n        if (root.val == n.val) {\n            return true;\n        } else if (root.val > n.val) {\n            return find(root.left, n);\n        } else {\n            return find(root.right, n);\n        }\n        \n    }\n\n}\n"
  },
  {
    "path": "src/LowestCommonAncestorOfABinaryTree236.java",
    "content": "/**\n * Given a binary tree, find the lowest common ancestor (LCA) of two given\n * nodes in the tree.\n * \n * According to the definition of LCA on Wikipedia: “The lowest common ancestor\n * is defined between two nodes p and q as the lowest node in T that has both p\n * and q as descendants (where we allow a node to be a descendant of itself).”\n * \n * Given the following binary search tree:  root = [3,5,1,6,2,0,8,null,null,7,4]\n * \n *         _______3______\n *        /              \\\n *     ___5__          ___1__\n *    /      \\        /      \\\n *    6      _2       0       8\n *          /  \\\n *          7   4\n * \n * Example 1:\n * Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1\n * Output: 3\n * Explanation: The LCA of of nodes 5 and 1 is 3.\n * \n * Example 2:\n * Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4\n * Output: 5\n * Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant\n * of itself according to the LCA definition.\n * \n * Note:\n *    All of the nodes' values will be unique.\n *    p and q are different and both values will exist in the binary tree.\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class LowestCommonAncestorOfABinaryTree236 {\n    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {\n        if (root == null) return null;\n        if (root.val == p.val || root.val == q.val) return root;\n        TreeNode left = lowestCommonAncestor(root.left, p, q);\n        TreeNode right = lowestCommonAncestor(root.right, p, q);\n\n        if (left != null && right != null) {\n            return root;\n        } else if (left != null) {\n            return left;\n        } else {\n            return right;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/MagicalString481.java",
    "content": "/**\n * A magical string S consists of only '1' and '2' and obeys the following rules:\n * \n * The string S is magical because concatenating the number of contiguous\n * occurrences of characters '1' and '2' generates the string S itself.\n * \n * The first few elements of string S is the following: S = \"1221121221221121122……\"\n * \n * If we group the consecutive '1's and '2's in S, it will be:\n * \n * 1 22 11 2 1 22 1 22 11 2 11 22 ......\n * \n * and the occurrences of '1's or '2's in each group are:\n * \n * 1 2\t2 1 1 2 1 2 2 1 2 2 ......\n * \n * You can see that the occurrence sequence above is the S itself.\n * \n * Given an integer N as input, return the number of '1's in the first N number\n * in the magical string S.\n * \n * Note: N will not exceed 100,000.\n * \n * Example 1:\n * Input: 6\n * Output: 3\n * Explanation: The first 6 elements of magical string S is \"12211\" and it\n * contains three 1's, so return 3.\n */\n\npublic class MagicalString481 {\n    public int magicalString(int N) {\n        if (N == 0) return 0;\n        if (N <= 3) return 1;\n        int[] arr = new int[N];\n        arr[0] = 1;\n        arr[1] = 2;\n        arr[2] = 2;\n        int now = 1;\n        int i = 2;\n        int j = 3;\n        int res = 1;\n        while (j < N) {\n            int curr = arr[i];\n            for (int k=0; k<curr; k++) {\n                if (j >= N) break;\n                if (now == 1) res++;\n                arr[j++] = now;\n            }\n            now = now == 1 ? 2 : 1;\n            i++;\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/MajorityElement169.java",
    "content": "/**\n * Given an array of size n, find the majority element. The majority element is\n * the element that appears more than ⌊ n/2 ⌋ times.\n *\n * You may assume that the array is non-empty and the majority element always\n * exist in the array.\n */\n\npublic class MajorityElement169 {\n    public int majorityElement(int[] nums) {\n        Map<Integer, Integer> map = new HashMap<>();\n        int N = nums.length;\n\n        for (int i=0; i<N; i++) {\n            map.put(nums[i], map.getOrDefault(nums[i], 0)+1);\n            if (map.get(nums[i]) > (N/2)) {\n                return nums[i];\n            }\n        }\n        return nums[0];\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/8692/o-n-time-o-1-space-fastest-solution\n     * Moore voting algorithm\n     */\n    public int majorityElement2(int[] num) {\n        int major=num[0], count = 1;\n        for(int i=1; i<num.length;i++){\n            if(count==0){\n                count++;\n                major=num[i];\n            }else if(major==num[i]){\n                count++;\n            }else count--;\n\n        }\n        return major;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/28601/java-solutions-sorting-hashmap-moore-voting-bit-manipulation\n     * Sorting\n     */\n    public int majorityElement3(int[] num) {\n        Arrays.sort(num);\n        return num[num.length/2];\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/28601/java-solutions-sorting-hashmap-moore-voting-bit-manipulation\n     * Bit manipulation\n     */\n    public int majorityElement4(int[] nums) {\n        int[] bit = new int[32];\n        for (int num: nums)\n            for (int i=0; i<32; i++)\n                if ((num>>(31-i) & 1) == 1)\n                    bit[i]++;\n        int ret=0;\n        for (int i=0; i<32; i++) {\n            bit[i]=bit[i]>nums.length/2?1:0;\n            ret += bit[i]*(1<<(31-i));\n        }\n        return ret;\n    }\n\n}\n"
  },
  {
    "path": "src/MapSumPairs677.java",
    "content": "/**\n * Implement a MapSum class with insert, and sum methods.\n * \n * For the method insert, you'll be given a pair of (string, integer). The\n * string represents the key and the integer represents the value. If the key\n * already existed, then the original key-value pair will be overridden to\n * the new one.\n * \n * For the method sum, you'll be given a string representing the prefix, and\n * you need to return the sum of all the pairs' value whose key starts with\n * the prefix.\n * \n * Example 1:\n * Input: insert(\"apple\", 3), Output: Null\n * Input: sum(\"ap\"), Output: 3\n * Input: insert(\"app\", 2), Output: Null\n * Input: sum(\"ap\"), Output: 5\n *\n */\n\npublic class MapSumPairs677 {\n\n    class MapSum {\n        private Trie trie = new Trie();\n\n        /** Initialize your data structure here. */\n        public MapSum() {\n        }\n\n        public void insert(String key, int val) {\n            trie.add(key, val);\n        }\n\n        public int sum(String prefix) {\n            return trie.getSum(prefix);\n        }\n\n        class Trie {\n            Trie[] children = new Trie[256];\n            Integer value;\n            Integer sum = 0;\n\n            public void add(String key, int val) {\n                add(key.toCharArray(), val, 0);\n            }\n\n            private Integer add(char[] chars, int val, int i) {\n                if (i == chars.length) {\n                    int diff = (value == null) ? val : val - value;\n                    value = val;\n                    sum += diff;\n                    return diff;\n                }\n                int nextI = (int) (chars[i] - 'a');\n                if (children[nextI] == null) {\n                    children[nextI] = new Trie();\n                }\n                Integer pre = sum;\n                Integer diff = children[nextI].add(chars, val, i+1);\n                sum = pre + diff;\n                return diff;\n            }\n\n            public int getSum(String prefix) {\n                int s = getSum(prefix.toCharArray(), 0);\n                return s;\n            }\n\n            private int getSum(char[] chars, int i) {\n                if (i == chars.length) return sum;\n                if (children[chars[i] - 'a'] == null) return 0;\n                return children[chars[i] - 'a'].getSum(chars, i+1);\n            }\n        }\n    }\n\n\n\n    class MapSum2 {\n        private Map<String, Integer> map = new HashMap<>();\n        private Trie trie = new Trie();\n\n        /** Initialize your data structure here. */\n        public MapSum() {\n        }\n\n        public void insert(String key, int val) {\n            int now = map.getOrDefault(key, 0);\n            trie.add(key, val - now);\n            map.put(key, val);\n        }\n\n        public int sum(String prefix) {\n            return trie.getSum(prefix);\n        }\n\n        class Trie {\n            Trie[] children = new Trie[256];\n            Integer sum = 0;\n\n            public void add(String key, int diff) {\n                add(key.toCharArray(), diff, 0);\n            }\n\n            private void add(char[] chars, int diff, int i) {\n                if (i == chars.length) {\n                    sum += diff;\n                    return;\n                }\n                int nextI = (int) (chars[i] - 'a');\n                if (children[nextI] == null) {\n                    children[nextI] = new Trie();\n                }\n                sum += diff;\n                children[nextI].add(chars, diff, i+1);\n            }\n\n            public int getSum(String prefix) {\n                return getSum(prefix.toCharArray(), 0);\n            }\n\n            private int getSum(char[] chars, int i) {\n                if (i == chars.length) return sum;\n                if (children[chars[i] - 'a'] == null) return 0;\n                return children[chars[i] - 'a'].getSum(chars, i+1);\n            }\n        }\n    }\n\n\n/**\n * Your MapSum object will be instantiated and called as such:\n * MapSum obj = new MapSum();\n * obj.insert(key,val);\n * int param_2 = obj.sum(prefix);\n */\n\n}\n"
  },
  {
    "path": "src/MatchsticksToSquare473.java",
    "content": "/**\n * Remember the story of Little Match Girl? By now, you know exactly what\n * matchsticks the little match girl has, please find out a way you can make\n * one square by using up all those matchsticks. You should not break any\n * stick, but you can link them up, and each matchstick must be used exactly\n * one time.\n * \n * Your input will be several matchsticks the girl has, represented with their\n * stick length. Your output will either be true or false, to represent whether\n * you could make one square using all the matchsticks the little match girl\n * has.\n * \n * Example 1:\n * Input: [1,1,2,2,2]\n * Output: true\n * Explanation: You can form a square with length 2, one side of the square\n * came two sticks with length 1.\n * \n * Example 2:\n * Input: [3,3,3,3,4]\n * Output: false\n * Explanation: You cannot find a way to form a square with all the matchsticks.\n * \n * Note:\n * The length sum of the given matchsticks is in the range of 0 to 10^9.\n * The length of the given matchstick array will not exceed 15.\n */\n\npublic class MatchsticksToSquare473 {\n    public boolean makesquare(int[] nums) {\n        if (nums == null || nums.length <= 3) return false;\n        return canPartitionKSubsets(nums, 4);\n    }\n\n    // PartitionToKEqualSumSubsets698\n    public boolean canPartitionKSubsets(int[] nums, int k) {\n        int sum = 0;\n        int N = nums.length;\n        for (int i=0; i<N; i++) {\n            sum += nums[i];\n        }\n        if (sum % k != 0) return false;\n        int target = sum / k;\n        boolean[] visited = new boolean[N];\n        return valid(nums, visited, 0, 0, target, k, N);\n    }\n\n    private boolean valid(int[] nums, boolean[] visited, int start, int curr, int target, int k, int N) {\n        if (k == 1) return true;\n        if (curr == target) return valid(nums, visited, 0, 0, target, k-1, N);\n        for (int i=start; i<N; i++) {\n            if (visited[i]) continue;\n            visited[i] = true;\n            if (valid(nums, visited, i, curr + nums[i], target, k, N)) return true;\n            visited[i] = false;\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "src/MaxAreaOfIsland695.java",
    "content": "/**\n * Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's\n * (representing land) connected 4-directionally (horizontal or vertical.) You\n * may assume all four edges of the grid are surrounded by water.\n * \n * Find the maximum area of an island in the given 2D array. (If there is no\n * island, the maximum area is 0.)\n * \n * Example 1:\n * [[0,0,1,0,0,0,0,1,0,0,0,0,0],\n *  [0,0,0,0,0,0,0,1,1,1,0,0,0],\n *  [0,1,1,0,1,0,0,0,0,0,0,0,0],\n *  [0,1,0,0,1,1,0,0,1,0,1,0,0],\n *  [0,1,0,0,1,1,0,0,1,1,1,0,0],\n *  [0,0,0,0,0,0,0,0,0,0,1,0,0],\n *  [0,0,0,0,0,0,0,1,1,1,0,0,0],\n *  [0,0,0,0,0,0,0,1,1,0,0,0,0]]\n * \n * Given the above grid, return 6. Note the answer is not 11, because the\n * island must be connected 4-directionally.\n * \n * Example 2:\n * [[0,0,0,0,0,0,0,0]]\n * Given the above grid, return 0.\n * \n * Note: The length of each dimension in the given grid does not exceed 50.\n */\n\npublic class MaxAreaOfIsland695 {\n    private static int[][] DIRECTIONS = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};\n\n    // BFS\n    public int maxAreaOfIsland(int[][] grid) {\n        if (grid == null || grid.length == 0 || grid[0].length == 0) return 0;\n        int M = grid.length;\n        int N = grid[0].length;\n        boolean[][] visited = new boolean[M][N];\n        int res = 0;\n        for (int i=0; i<M; i++) {\n            for (int j=0; j<N; j++) {\n                if (grid[i][j] == 1 && !visited[i][j]) {\n                    res = Math.max(res, bfs(grid, visited, i, j));\n                }\n            }\n        }\n        return res;\n    }\n\n    private int bfs(int[][] grid, boolean[][] visited, int i, int j) {\n        Queue<int[]> q = new LinkedList<>();\n        q.add(new int[]{i, j});\n        visited[i][j] = true;\n        int res = 0;\n        while (!q.isEmpty()) {\n            int[] curr = q.poll();\n            res++;\n            for (int[] dir: DIRECTIONS) {\n                int x = curr[0] + dir[0];\n                int y = curr[1] + dir[1];\n                if (x < 0 || y < 0 || x >= grid.length || y >= grid[0].length || visited[x][y] || grid[x][y] != 1) continue;\n                q.add(new int[]{x, y});\n                visited[x][y] = true;\n            }\n        }\n        return res;\n    }\n\n\n    // DFS\n    public int maxAreaOfIsland2(int[][] grid) {\n        if (grid == null || grid.length == 0 || grid[0].length == 0) return 0;\n        int M = grid.length;\n        int N = grid[0].length;\n        boolean[][] visited = new boolean[M][N];\n        int res = 0;\n        for (int i=0; i<M; i++) {\n            for (int j=0; j<N; j++) {\n                if (grid[i][j] == 1 && !visited[i][j]) {\n                    res = Math.max(res, dfs(grid, visited, i, j));\n                }\n            }\n        }\n        return res;\n    }\n\n    private int dfs(int[][] grid, boolean[][] visited, int i, int j) {\n        if (i < 0 || j < 0 ||\n            i>= grid.length || j >= grid[0].length ||\n            grid[i][j] != 1 || visited[i][j]) return 0;\n\n        visited[i][j] = true;\n        int res = 1;\n        for (int[] dir: DIRECTIONS) {\n            int x = i + dir[0];\n            int y = j + dir[1];\n            res += dfs(grid, visited, x, y);\n        }\n        return res;\n    }\n\n\n    // Union-Find\n    public int maxAreaOfIsland3(int[][] grid) {\n        if (grid == null || grid.length == 0 || grid[0].length == 0) return 0;\n        int M = grid.length;\n        int N = grid[0].length;\n        int res = 0;\n        UinionFind uf = new UinionFind(grid);\n        for (int i=0; i<M; i++) {\n            for (int j=0; j<N; j++) {\n                if (grid[i][j] == 1) {\n                    res = Math.max(res, link(grid, i, j, uf, M, N));\n                }\n            }\n        }\n        return res;\n    }\n\n    \n    private int link(int[][] grid, int i, int j, UinionFind uf, int M, int N) {\n        int pre = i * N + j;\n        int res = uf.getSize(pre);\n        for (int[] dir: DIRECTIONS) {\n            int x = i + dir[0];\n            int y = j + dir[1];\n            if (x < 0 || y < 0 || x >= M || y >= N || grid[x][y] != 1) continue;\n            res = Math.max(res, uf.union(pre, x * N + y));\n        }\n        return res;\n    }\n\n    class UinionFind {\n        int[] parent;\n        int[] size;\n        int[] rank;\n\n        UinionFind(int[][] grid) {\n            int M = grid.length;\n            int N = grid[0].length;\n            this.parent = new int[M * N];\n            for (int i=0; i<M*N; i++) this.parent[i] = i;\n            this.rank = new int[M * N];\n            this.size = new int[M * N];\n            Arrays.fill(this.size, 1);\n        }\n\n        int find(int x) {\n            if (this.parent[x] != x) {\n                this.parent[x] = find(this.parent[x]);\n            }\n            return this.parent[x];\n        }\n\n        int union(int x, int y) {\n            int px = find(x);\n            int py = find(y);\n\n            if (px == py) return this.size[px];\n            if (this.rank[px] > this.rank[py]) {\n                this.parent[py] = px;\n                this.size[px] = this.size[px] + this.size[py];\n                return this.size[px];\n            } else if (this.rank[px] < this.rank[py]) {\n                this.parent[px] = py;\n                this.size[py] = this.size[px] + this.size[py];\n                return this.size[py];\n            } else {\n                this.parent[px] = py;\n                this.rank[py]++;\n                this.size[py] = this.size[px] + this.size[py];\n                return this.size[py];\n            }\n        }\n\n        int getSize(int x) {\n            return this.size[find(x)];\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/MaxChunksToMakeSorted769.java",
    "content": "/**\n * Given an array arr that is a permutation of [0, 1, ..., arr.length - 1], we\n * split the array into some number of \"chunks\" (partitions), and individually\n * sort each chunk.  After concatenating them, the result equals the sorted\n * array.\n * \n * What is the most number of chunks we could have made?\n * \n * Example 1:\n * Input: arr = [4,3,2,1,0]\n * Output: 1\n * Explanation:\n * Splitting into two or more chunks will not return the required result.\n * For example, splitting into [4, 3], [2, 1, 0] will result in [3, 4, 0, 1, 2],\n * which isn't sorted.\n * \n * Example 2:\n * Input: arr = [1,0,2,3,4]\n * Output: 4\n * Explanation:\n * We can split into two chunks, such as [1, 0], [2, 3, 4].\n * However, splitting into [1, 0], [2], [3], [4] is the highest number of\n * chunks possible.\n * \n *  Note:\n * arr will have length in range [1, 10].\n * arr[i] will be a permutation of [0, 1, ..., arr.length - 1].\n */\n\npublic class MaxChunksToMakeSorted769 {\n    public int maxChunksToSorted(int[] arr) {\n        if (arr == null || arr.length == 0) return 0;\n        int res = 0;\n        int max = arr[0];\n        for (int i=0; i<arr.length; i++) {\n            max = Math.max(max, arr[i]);\n            if (max == i) {\n                res++;\n            }\n        }\n        return res;\n    }\n}\n"
  },
  {
    "path": "src/MaxChunksToMakeSortedII768.java",
    "content": "/**\n * This question is the same as \"Max Chunks to Make Sorted\" except the integers\n * of the given array are not necessarily distinct, the input array could be\n * up to length 2000, and the elements could be up to 10**8.\n * \n * Given an array arr of integers (not necessarily distinct), we split the\n * array into some number of \"chunks\" (partitions), and individually sort\n * each chunk.  After concatenating them, the result equals the sorted array.\n * \n * What is the most number of chunks we could have made?\n * \n * Example 1:\n * Input: arr = [5,4,3,2,1]\n * Output: 1\n * Explanation:\n * Splitting into two or more chunks will not return the required result.\n * For example, splitting into [5, 4], [3, 2, 1] will result in\n * [4, 5, 1, 2, 3], which isn't sorted.\n * \n * Example 2:\n * Input: arr = [2,1,3,4,4]\n * Output: 4\n * Explanation:\n * We can split into two chunks, such as [2, 1], [3, 4, 4].\n * However, splitting into [2, 1], [3], [4], [4] is the highest number of\n * chunks possible.\n * \n * Note:\n * arr will have length in range [1, 2000].\n * arr[i] will be an integer in range [0, 10**8].\n */\n\npublic class MaxChunksToMakeSortedII768 {\n    public int maxChunksToSorted(int[] arr) {\n        Stack<Integer> stack = new Stack<>();\n        for (int i=0; i<arr.length; i++) {\n            if (stack.isEmpty() || stack.peek() <= arr[i]) {\n                stack.push(arr[i]);\n            } else {\n                int top = stack.peek();\n                while (!stack.isEmpty() && stack.peek() > arr[i]) {\n                    stack.pop();\n                }\n                stack.push(top);\n            }\n        }\n        return stack.size();\n    }\n\n\n    /**\n     * https://leetcode.com/problems/max-chunks-to-make-sorted-ii/discuss/113462/Java-solution-left-max-and-right-min.\n     */\n    public int maxChunksToSorted2(int[] arr) {\n        int n = arr.length;\n        int[] maxOfLeft = new int[n];\n        int[] minOfRight = new int[n];\n\n        maxOfLeft[0] = arr[0];\n        for (int i = 1; i < n; i++) {\n            maxOfLeft[i] = Math.max(maxOfLeft[i-1], arr[i]);\n        }\n\n        minOfRight[n - 1] = arr[n - 1];\n        for (int i = n - 2; i >= 0; i--) {\n            minOfRight[i] = Math.min(minOfRight[i + 1], arr[i]);\n        }\n\n        int res = 0;\n        for (int i = 0; i < n - 1; i++) {\n            if (maxOfLeft[i] <= minOfRight[i + 1]) res++;\n        }\n\n        return res + 1;\n    }\n\n}\n"
  },
  {
    "path": "src/MaxConsecutiveOnes485.java",
    "content": "/**\n * Given a binary array, find the maximum number of consecutive 1s in this array.\n * \n * Example 1:\n * Input: [1,1,0,1,1,1]\n * Output: 3\n * \n * Explanation: The first two digits or the last three digits are consecutive 1s.\n *     The maximum number of consecutive 1s is 3.\n * \n * Note:\n * The input array will only contain 0 and 1.\n * The length of input array is a positive integer and will not exceed 10,000\n */\n\npublic class MaxConsecutiveOnes485 {\n    public int findMaxConsecutiveOnes(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        int left = 0;\n        int right = 0;\n        int max = 0;\n        while (right < nums.length) {\n            if (nums[right] == 1) {\n                right++;\n                continue;\n            }\n            max = Math.max(max, right-left);\n            left = right;\n            while (left < nums.length && nums[left] == 0) left++;\n            right = left;\n        }\n        max = Math.max(max, right-left);\n        return max;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/max-consecutive-ones/discuss/96693/Java-4-lines-concise-solution-with-explanation\n     */\n    public int findMaxConsecutiveOnes2(int[] nums) {\n        int maxHere = 0, max = 0;\n        for (int n : nums)\n            max = Math.max(max, maxHere = n == 0 ? 0 : maxHere + 1);\n        return max; \n    }\n\n}\n"
  },
  {
    "path": "src/MaxConsecutiveOnesII487.java",
    "content": "/**\n * Given a binary array, find the maximum number of consecutive 1s in this\n * array if you can flip at most one 0.\n * \n * Example 1:\n * Input: [1,0,1,1,0]\n * Output: 4\n * Explanation: Flip the first zero will get the the maximum number of consecutive 1s.\n *     After flipping, the maximum number of consecutive 1s is 4.\n * \n * Note:\n * The input array will only contain 0 and 1.\n * The length of input array is a positive integer and will not exceed 10,000\n * \n * Follow up:\n * What if the input numbers come in one by one as an infinite stream? In other\n * words, you can't store all numbers coming from the stream as it's too large\n * to hold in memory. Could you solve it efficiently?\n */\n\npublic class MaxConsecutiveOnesII487 {\n    public int findMaxConsecutiveOnes(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        int left = 0;\n        int right = 0;\n        int max = 0;\n        int zeros = 0;\n        while (right < nums.length) {\n            if (nums[right] == 1) {\n                right++;\n                continue;\n            } else if (nums[right] == 0 && zeros == 0) {\n                right++;\n                zeros++;\n                continue;\n            }\n            max = Math.max(max, right - left);\n            while (left < nums.length && nums[left] == 1) left++;\n            if (left < nums.length && nums[left] == 0) {\n                left++;\n                zeros--;\n            }\n        }\n        return Math.max(max, right-left);\n    }\n}\n"
  },
  {
    "path": "src/MaxIncreaseToKeepCitySkyline807.java",
    "content": "/**\n * In a 2 dimensional array grid, each value grid[i][j] represents the height\n * of a building located there. We are allowed to increase the height of any\n * number of buildings, by any amount (the amounts can be different for\n * different buildings). Height 0 is considered to be a building as well. \n * \n * At the end, the \"skyline\" when viewed from all four directions of the grid,\n * i.e. top, bottom, left, and right, must be the same as the skyline of the\n * original grid. A city's skyline is the outer contour of the rectangles\n * formed by all the buildings when viewed from a distance. See the following\n * example.\n * \n * What is the maximum total sum that the height of the buildings can be\n * increased?\n * \n * Example:\n * Input: grid = [[3,0,8,4],[2,4,5,7],[9,2,6,3],[0,3,1,0]]\n * Output: 35\n * Explanation: \n * The grid is:\n * [ [3, 0, 8, 4], \n *   [2, 4, 5, 7],\n *   [9, 2, 6, 3],\n *   [0, 3, 1, 0] ]\n * \n * The skyline viewed from top or bottom is: [9, 4, 8, 7]\n * The skyline viewed from left or right is: [8, 7, 9, 3]\n * \n * The grid after increasing the height of buildings without affecting skylines\n * is:\n * \n * gridNew = [ [8, 4, 8, 7],\n *             [7, 4, 7, 7],\n *             [9, 4, 8, 7],\n *             [3, 3, 3, 3] ]\n * \n * Notes:\n * 1 < grid.length = grid[0].length <= 50.\n * All heights grid[i][j] are in the range [0, 100].\n * All buildings in grid[i][j] occupy the entire grid cell: that is, they are\n * a 1 x 1 x grid[i][j] rectangular prism.\n */\n\npublic class MaxIncreaseToKeepCitySkyline807 {\n    public int maxIncreaseKeepingSkyline(int[][] grid) {\n        int M = grid.length;\n        int N = grid[0].length;\n        int[] top = new int[N];\n        int[] left = new int[M];\n        for (int i=0; i<M; i++) {\n            for (int j=0; j<N; j++) {\n                top[j] = Math.max(top[j], grid[i][j]);\n                left[i] = Math.max(left[i], grid[i][j]);\n            }\n        }\n        \n        int res = 0;\n        for (int i=0; i<M; i++) {\n            for (int j=0; j<N; j++) {\n                res += Math.min(top[j], left[i]) - grid[i][j];\n            }\n        }\n        return res;\n    }\n}\n"
  },
  {
    "path": "src/MaxPointsOnALine149.java",
    "content": "/**\n * Given n points on a 2D plane, find the maximum number of points that lie on\n * the same straight line.\n */\n\n/**\n * Definition for a point.\n * class Point {\n *     int x;\n *     int y;\n *     Point() { x = 0; y = 0; }\n *     Point(int a, int b) { x = a; y = b; }\n * }\n */\n\n\npublic class MaxPointsOnALine149 {\n    /**\n     * Fail: [[0,0],[94911151,94911150],[94911152,94911151]]\n     */\n    public int maxPoints(Point[] points) {\n        if (points.length <= 2) return points.length;\n\n        int len = points.length;\n        int maxP = 0;\n        for (int i=0; i<len-1; i++) {\n            Map<Double, Integer> lines = new HashMap<>();\n            Point p1 = points[i];\n            int same = 0;\n            int localMax = 0;\n            for (int j=i+1; j<len; j++) {\n                Point p2 = points[j];\n                if (pointsEqual(p1, p2)) {\n                    same += 1;\n                    continue;\n                }\n                Double k = getSlope(p1, p2);\n                Integer ps = lines.getOrDefault(k, 0) + 1;\n                localMax = Math.max(localMax, ps);\n                lines.put(k, ps);\n            }\n            maxP = Math.max(maxP, localMax + same + 1);\n        }\n\n        return maxP;\n    }\n\n    private Double getSlope(Point p1, Point p2) {\n        if (p1.y == p2.y) return 0.0;\n        if (p1.x == p2.x) return Double.POSITIVE_INFINITY;\n        return (double) (p1.y - p2.y) / (double) (p1.x - p2.x);\n    }\n\n    private boolean pointsEqual(Point p1, Point p2) {\n        return (p1.y == p2.y) && (p1.x == p2.x);\n    }\n\n\n\n    public int maxPoints2(Point[] points) {\n        if (points.length <= 2) return points.length;\n\n        int len = points.length;\n        int maxP = 0;\n        for (int i=0; i<len-1; i++) {\n            Map<String, Integer> lines = new HashMap<>();\n            Point p1 = points[i];\n            int same = 0;\n            int localMax = 0;\n            for (int j=i+1; j<len; j++) {\n                Point p2 = points[j];\n                if (pointsEqual(p1, p2)) {\n                    same += 1;\n                    continue;\n                }\n                int dx = p1.x - p2.x;\n                int dy = p1.y - p2.y;\n                int d = gcd(dx, dy);\n                dx /= d;\n                dy /= d;\n                String k = String.valueOf(dx) + String.valueOf(dy);\n                Integer ps = lines.getOrDefault(k, 0) + 1;\n                localMax = Math.max(localMax, ps);\n                lines.put(k, ps);\n            }\n            maxP = Math.max(maxP, localMax + same + 1);\n        }\n\n        return maxP;\n    }\n\n    private int gcd(int a, int b) {\n        return (b == 0) ? a : gcd(b, a % b);\n    }\n\n\n\n}\n"
  },
  {
    "path": "src/MaxStack716.java",
    "content": "/**\n * Design a max stack that supports push, pop, top, peekMax and popMax.\n * \n * push(x) -- Push element x onto stack.\n * pop() -- Remove the element on top of the stack and return it.\n * top() -- Get the element on the top.\n * peekMax() -- Retrieve the maximum element in the stack.\n * popMax() -- Retrieve the maximum element in the stack, and remove it. If you\n * find more than one maximum elements, only remove the top-most one.\n * \n * Example 1:\n * MaxStack stack = new MaxStack();\n * stack.push(5); \n * stack.push(1);\n * stack.push(5);\n * stack.top(); -> 5\n * stack.popMax(); -> 5\n * stack.top(); -> 1\n * stack.peekMax(); -> 5\n * stack.pop(); -> 1\n * stack.top(); -> 5\n * \n * Note:\n * -1e7 <= x <= 1e7\n * Number of operations won't exceed 10000.\n * The last four operations won't be called when stack is empty.\n */\n\n\npublic class MaxStack716 {\n\n    class MaxStack {\n        \n        private Stack<Element> stack;\n        \n        /** initialize your data structure here. */\n        public MaxStack() {\n            this.stack = new Stack<>();\n        }\n        \n        public void push(int x) {\n            int max = this.stack.isEmpty() ? x : Math.max(x, this.peekMax());\n            this.stack.push(new Element(x, max));\n        }\n        \n        public int pop() {\n            return this.stack.pop().val;\n        }\n        \n        public int top() {\n            return this.stack.peek().val;\n        }\n        \n        public int peekMax() {\n            return this.stack.peek().max;\n        }\n        \n        public int popMax() {\n            int max = this.peekMax();\n            Stack<Integer> temp = new Stack<>();\n            while (this.top() != max) {\n                temp.push(this.pop());\n            }\n            this.pop();\n            while (!temp.isEmpty()) {\n                this.push(temp.pop());\n            }\n            return max;\n        }\n\n        class Element {\n            int val;\n            int max;\n            public Element(int val, int max) {\n                this.val = val;\n                this.max = max;\n            }\n        }\n    }\n\n    /**\n     * Your MaxStack object will be instantiated and called as such:\n     * MaxStack obj = new MaxStack();\n     * obj.push(x);\n     * int param_2 = obj.pop();\n     * int param_3 = obj.top();\n     * int param_4 = obj.peekMax();\n     * int param_5 = obj.popMax();\n     */\n\n\n\n\n}\n"
  },
  {
    "path": "src/MaxSumOfRectangleNoLargerThanK363.java",
    "content": "/**\n * Given a non-empty 2D matrix matrix and an integer k, find the max sum of a\n * rectangle in the matrix such that its sum is no larger than k.\n * \n * Example:\n * Given matrix = [\n *   [1,  0, 1],\n *   [0, -2, 3]\n * ]\n * k = 2\n * The answer is 2. Because the sum of rectangle [[0, 1], [-2, 3]] is 2 and 2\n * is the max number no larger than k (k = 2).\n * \n * Note:\n * The rectangle inside the matrix must have an area > 0.\n * What if the number of rows is much larger than the number of columns?\n */\n\n\npublic class MaxSumOfRectangleNoLargerThanK363 {\n    public int maxSumSubmatrix(int[][] matrix, int k) {\n        int m = matrix.length;\n        int n = matrix[0].length;\n        \n        int[][] sum = new int[m+1][n+1];\n        for (int i=0; i<m; i++) {\n            for (int j=0; j<n; j++) {\n                sum[i+1][j+1] = matrix[i][j] + sum[i][j+1] + sum[i+1][j] - sum[i][j];\n            }\n        }\n\n        int res = Integer.MIN_VALUE;\n        for (int y1=0; y1<m; y1++) {\n            for (int y2=y1+1; y2<=m; y2++) {\n                for (int x1=0; x1<n; x1++) {\n                    for (int x2=x1+1; x2<=n; x2++) {\n                        int tmp = sum[y2][x2] - sum[y2][x1] - sum[y1][x2] + sum[y1][x1];\n                        if (tmp == k) return tmp;\n                        if (tmp > res && tmp <= k) {\n                            res = tmp;\n                        }\n                    }\n                }\n            }\n        }\n        return res;\n    }\n\n\n\n\n\n\n\n\n\n\n\n\n}\n"
  },
  {
    "path": "src/MaximalRectangle85.java",
    "content": "/**\n * Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle\n * containing only 1's and return its area.\n *\n * For example, given the following matrix:\n *\n * 1 0 1 0 0\n * 1 0 1 1 1\n * 1 1 1 1 1\n * 1 0 0 1 0\n * Return 6.\n *\n */\n\npublic class MaximalRectangle85 {\n    public int maximalRectangle(char[][] matrix) {\n        int N = matrix.length;\n        if (N == 0) return 0;\n        int M = matrix[0].length;\n        if (M == 0) return 0;\n\n        int[][] left = new int[N+1][M+1];\n        int[][] top = new int[N+1][M+1];\n        int maxArea = 0;\n\n        for (int i=1; i<=N; i++) {\n            for (int j=1; j<=M; j++) {\n                if (matrix[i-1][j-1] == '1') {\n                    left[i][j] = left[i][j-1] + 1;\n                    top[i][j] = top[i-1][j] + 1;\n                    maxArea = Math.max(maxArea, helper(left, top, i, j));\n                }\n            }\n        }\n\n        return maxArea;\n    }\n\n    private int helper(int[][] left, int[][] top, int i, int j) {\n        int maxArea = 0;\n\n        int move = 0;\n        int minH = top[i][j];\n        while (move < left[i][j]) {\n            minH = Math.min(minH, top[i][j-move]);\n            maxArea = Math.max(maxArea, (move+1) * minH);\n            move++;\n        }\n\n        return maxArea;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/1634/a-o-n-2-solution-based-on-largest-rectangle-in-histogram\n     */\n    public int maximalRectangle2(char[][] matrix) {\n        if (matrix==null||matrix.length==0||matrix[0].length==0)\n            return 0;\n        int cLen = matrix[0].length;    // column length\n        int rLen = matrix.length;       // row length\n        // height array\n        int[] h = new int[cLen+1];\n        h[cLen]=0;\n        int max = 0;\n\n        for (int row=0;row<rLen;row++) {\n            Stack<Integer> s = new Stack<Integer>();\n            for (int i=0;i<cLen+1;i++) {\n                if (i<cLen)\n                    if(matrix[row][i]=='1')\n                        h[i]+=1;\n                    else h[i]=0;\n\n                if (s.isEmpty()||h[s.peek()]<=h[i])\n                    s.push(i);\n                else {\n                    while(!s.isEmpty()&&h[i]<h[s.peek()]){\n                        int top = s.pop();\n                        int area = h[top]*(s.isEmpty()?i:(i-s.peek()-1));\n                        if (area>max)\n                            max = area;\n                    }\n                    s.push(i);\n                }\n            }\n        }\n        return max;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/21772/my-java-solution-based-on-maximum-rectangle-in-histogram-with-explanation\n     */\n    public int maximalRectangle3(char[][] matrix) {\n        if(matrix == null || matrix.length == 0 || matrix[0].length == 0) return 0;\n\n        int[] height = new int[matrix[0].length];\n        for(int i = 0; i < matrix[0].length; i ++){\n            if(matrix[0][i] == '1') height[i] = 1;\n        }\n        int result = largestInLine(height);\n        for(int i = 1; i < matrix.length; i ++){\n            resetHeight(matrix, height, i);\n            result = Math.max(result, largestInLine(height));\n        }\n\n        return result;\n    }\n\n    private void resetHeight(char[][] matrix, int[] height, int idx){\n        for(int i = 0; i < matrix[0].length; i ++){\n            if(matrix[idx][i] == '1') height[i] += 1;\n            else height[i] = 0;\n        }\n    }\n\n    public int largestInLine(int[] height) {\n        if(height == null || height.length == 0) return 0;\n        int len = height.length;\n        Stack<Integer> s = new Stack<Integer>();\n        int maxArea = 0;\n        for(int i = 0; i <= len; i++){\n            int h = (i == len ? 0 : height[i]);\n            if(s.isEmpty() || h >= height[s.peek()]){\n                s.push(i);\n            }else{\n                int tp = s.pop();\n                maxArea = Math.max(maxArea, height[tp] * (s.isEmpty() ? i : i - 1 - s.peek()));\n                i--;\n            }\n        }\n        return maxArea;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/42761/java-7ms-solution-beats-100-using-largest-rectangle-in-histogram-solved-by-stack-simulation\n     */\n    public int maximalRectangle4(char[][] matrix) {\n        /**\n         * idea: using [LC84 Largest Rectangle in Histogram]. For each row\n         * of the matrix, construct the histogram based on the current row\n         * and the previous histogram (up to the previous row), then compute\n         * the largest rectangle area using LC84.\n         */\n        int m = matrix.length, n;\n        if (m == 0 || (n = matrix[0].length) == 0)\n            return 0;\n\n        int i, j, res = 0;\n        int[] heights = new int[n];\n        for (i = 0; i < m; i++) {\n            for (j = 0; j < n; j++) {\n                if (matrix[i][j] == '0')\n                    heights[j] = 0;\n                else\n                    heights[j] += 1;\n            }\n            res = Math.max(res, largestRectangleArea(heights));\n        }\n\n        return res;\n    }\n\n    public int largestRectangleArea(int[] heights) {\n        /**\n         * idea: scan and store if a[i-1]<=a[i] (increasing), then as long\n         * as a[i]<a[i-1], then we can compute the largest rectangle area\n         * with base a[j], for j<=i-1, and a[j]>a[i], which is a[j]*(i-j).\n         * And meanwhile, all these bars (a[j]'s) are already done, and thus\n         * are throwable (using pop() with a stack).\n         *\n         * We can use an array nLeftGeq[] of size n to simulate a stack.\n         * nLeftGeq[i] = the number of elements to the left of [i] having\n         * value greater than or equal to a[i] (including a[i] itself). It\n         * is also the index difference between [i] and the next index on\n         * the top of the stack.\n         */\n        int n = heights.length;\n        if (n == 0)\n            return 0;\n\n        int[] nLeftGeq = new int[n]; // the number of elements to the left\n                                        // of [i] with value >= heights[i]\n        nLeftGeq[0] = 1;\n\n        // preIdx=the index of stack.peek(), res=max area so far\n        int preIdx = 0, res = 0;\n\n        for (int i = 1; i < n; i++) {\n            nLeftGeq[i] = 1;\n\n            // notice that preIdx = i - 1 = peek()\n            while (preIdx >= 0 && heights[i] < heights[preIdx]) {\n                res = Math.max(res, heights[preIdx] * (nLeftGeq[preIdx] + i - preIdx - 1));\n                nLeftGeq[i] += nLeftGeq[preIdx]; // pop()\n\n                preIdx = preIdx - nLeftGeq[preIdx]; // peek() current top\n            }\n\n            if (preIdx >= 0 && heights[i] == heights[preIdx])\n                nLeftGeq[i] += nLeftGeq[preIdx]; // pop()\n            // otherwise nothing to do\n\n            preIdx = i;\n        }\n\n        // compute the rest largest rectangle areas with (indices of) bases\n        // on stack\n        while (preIdx >= 0 && 0 < heights[preIdx]) {\n            res = Math.max(res, heights[preIdx] * (nLeftGeq[preIdx] + n - preIdx - 1));\n            preIdx = preIdx - nLeftGeq[preIdx]; // peek() current top\n        }\n\n        return res;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/20902/my-solution-on-java-using-dp\n     */\n    public int maximalRectangle5(char[][] matrix) {\n        int area = 0, new_area, r, l;\n        if(matrix.length > 0){\n            int[] line = new int[matrix[0].length];\n            boolean[] is_processed = new boolean[matrix[0].length];\n            for(int i = 0; i < matrix.length; i++){\n                for(int j = 0; j < matrix[i].length; j++){\n                    if (matrix[i][j] == '1') {\n                        line[j]++;\n                        is_processed[j] = false;\n                    } else {\n                        line[j] = 0;\n                        is_processed[j] = true;\n                    }\n                }\n                for(int j = 0; j < matrix[i].length; j++){\n                    if(is_processed[j]) continue;\n                    r = l = 1;\n                    while((j + r < line.length)&&(line[j + r] >= line[j])){\n                        if(line[j + r] == line[j]) is_processed[j + r] = true;\n                        r++;\n                    }\n                    while((j - l >= 0)&&(line[j - l] >= line[j])) l++;\n                    new_area = (r + l - 1)*line[j];\n                    if (new_area > area) area = new_area;\n                }\n            }\n        } return area;\n    }\n\n\n    public int maximalRectangle6(char[][] matrix) {\n        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return 0;\n        int M = matrix.length;\n        int N = matrix[0].length;\n        int[][] dp = new int[M][N+1];\n        int res = 0;\n        for (int i=0; i<M; i++) {\n            for (int j=1; j<=N; j++) {\n                if (matrix[i][j-1] == '1') {\n                    int local = 0;\n                    dp[i][j] = dp[i][j-1] + 1;\n                    int width = Integer.MAX_VALUE;\n                    for (int k=i; k>=0; k--) {\n                        width = Math.min(width, dp[k][j]);\n                        local = Math.max(local, width * (i - k + 1));\n                    }\n                    res = Math.max(res, local);\n                }\n            }\n        }\n        return res;\n    }\n\n\n    public int maximalRectangle7(char[][] matrix) {\n        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return 0;\n        int M = matrix.length;\n        int N = matrix[0].length;\n        int[] left = new int[N];\n        int[] right = new int[N];\n        Arrays.fill(right, N);\n        int[] height = new int[N];\n        int res = 0;\n        for (int i=0; i<M; i++) {\n            int currLeft = 0;\n            int currRight = N;\n            for (int j=0; j<N; j++) {\n                if (matrix[i][j] == '1') {\n                    height[j]++;\n                } else {\n                    height[j] = 0;\n                }\n            }\n            for (int j=0; j<N; j++) {\n                if (matrix[i][j] == '1') {\n                    left[j] = Math.max(currLeft, left[j]);\n                } else {\n                    left[j] = 0;\n                    currLeft = j + 1;\n                }\n            }\n            for (int j=N-1; j>=0; j--) {\n                if (matrix[i][j] == '1') {\n                    right[j] = Math.min(currRight, right[j]);\n                } else {\n                    right[j] = N;\n                    currRight = j;\n                }\n            }\n            for (int j=0; j<N; j++) {\n                res = Math.max(res, (right[j] - left[j]) * height[j]);\n            }\n        }\n        return res;\n    }\n\n\n    public static void main(String[] args) {\n        MaximalRectangle85 mr = new MaximalRectangle85();\n\n        char[][] matrix = new char[][]{\n            { '0', '1', '1', '0', '1' },\n            { '1', '1', '0', '1', '0' },\n            { '0', '1', '1', '1', '0' },\n            { '1', '1', '1', '1', '0' },\n            { '1', '1', '1', '1', '1' },\n        };\n\n        System.out.println(mr.maximalRectangle(matrix));\n    }\n\n}\n"
  },
  {
    "path": "src/MaximalSquare221.java",
    "content": "/**\n * Given a 2D binary matrix filled with 0's and 1's, find the largest square\n * containing only 1's and return its area.\n *\n * For example, given the following matrix:\n *\n * 1 0 1 0 0\n * 1 0 1 1 1\n * 1 1 1 1 1\n * 1 0 0 1 0\n *\n * Return 4.\n *\n */\n\n\npublic class MaximalSquare221 {\n    public int maximalSquare(char[][] matrix) {\n        if (matrix == null || matrix.length == 0) return 0;\n\n        int y = matrix.length;\n        int x = matrix[0].length;\n\n        int len = 0;\n        int[][] dp = new int[y+1][x+1];\n        for (int j=1; j<=y; j++) {\n            for (int i=1; i<=x; i++) {\n                if (matrix[j-1][i-1] == '0') continue;\n                if (i == 1 || j == 1 || matrix[j-2][i-2] == '0') {\n                    dp[j][i] = 1;\n                    len = Math.max(len, 1);\n                } else if (matrix[j-1][i-1] == '1') {\n                    int preLen = dp[j-1][i-1];\n                    int p = 1;\n                    while (p <= preLen) {\n                        if (matrix[j-1-p][i-1] == '0' || matrix[j-1][i-1-p] == '0') break;\n                        p++;\n                    }\n                    int newLen = p;\n                    dp[j][i] = newLen;\n                    len = Math.max(len, newLen);\n                }\n            }\n        }\n        return len * len;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/maximal-square/solution/\n     */\n    public int maximalSquare2(char[][] matrix) {\n        int rows = matrix.length, cols = rows > 0 ? matrix[0].length : 0;\n        int[][] dp = new int[rows + 1][cols + 1];\n        int maxsqlen = 0;\n        for (int i = 1; i <= rows; i++) {\n            for (int j = 1; j <= cols; j++) {\n                if (matrix[i-1][j-1] == '1'){\n                    dp[i][j] = Math.min(Math.min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;\n                    maxsqlen = Math.max(maxsqlen, dp[i][j]);\n                }\n            }\n        }\n        return maxsqlen * maxsqlen;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/maximal-square/solution/\n     */\n    public int maximalSquare3(char[][] matrix) {\n        int rows = matrix.length, cols = rows > 0 ? matrix[0].length : 0;\n        int[] dp = new int[cols + 1];\n        int maxsqlen = 0, prev = 0;\n        for (int i = 1; i <= rows; i++) {\n            for (int j = 1; j <= cols; j++) {\n                int temp = dp[j];\n                if (matrix[i - 1][j - 1] == '1') {\n                    dp[j] = Math.min(Math.min(dp[j - 1], prev), dp[j]) + 1;\n                    maxsqlen = Math.max(maxsqlen, dp[j]);\n                } else {\n                    dp[j] = 0;\n                }\n                prev = temp;\n            }\n        }\n        return maxsqlen * maxsqlen;\n    }\n\n}\n"
  },
  {
    "path": "src/MaximizeDistanceToClosestPerson849.java",
    "content": "/**\n * In a row of seats, 1 represents a person sitting in that seat, and 0\n * represents that the seat is empty. \n * \n * There is at least one empty seat, and at least one person sitting.\n * \n * Alex wants to sit in the seat such that the distance between him and the\n * closest person to him is maximized. \n * \n * Return that maximum distance to closest person.\n * \n * Example 1:\n * Input: [1,0,0,0,1,0,1]\n * Output: 2\n * \n * Explanation: \n * If Alex sits in the second open seat (seats[2]), then the closest person\n * has distance 2.\n * If Alex sits in any other open seat, the closest person has distance 1.\n * Thus, the maximum distance to the closest person is 2.\n * \n * Example 2:\n * Input: [1,0,0,0]\n * Output: 3\n * \n * Explanation: \n * If Alex sits in the last seat, the closest person is 3 seats away.\n * This is the maximum distance possible, so the answer is 3.\n * \n * Note:\n * 1 <= seats.length <= 20000\n * seats contains only 0s or 1s, at least one 0, and at least one 1.\n */\n\npublic class MaximizeDistanceToClosestPerson849 {\n    public int maxDistToClosest(int[] seats) {\n        int L = seats.length;\n        int dis = -1;\n        int pre = -1;\n        for (int i=0; i<L; i++) {\n            if (seats[i] == 0) continue;\n            if (pre == -1) {\n                dis = i;\n            } else if (pre + 1 < i) {\n                int mid = (i - pre) / 2 + pre;\n                int d = Math.min(mid - pre, i - mid);\n                if (d > dis) dis = d;\n            }\n            pre = i;\n        }\n        return Math.max(L - 1 - pre, dis);\n    }\n}\n"
  },
  {
    "path": "src/MaximumAverageSubarrayI643.java",
    "content": "/**\n * Given an array consisting of n integers, find the contiguous subarray of\n * given length k that has the maximum average value. And you need to output\n * the maximum average value.\n * \n * Example 1:\n * Input: [1,12,-5,-6,50,3], k = 4\n * Output: 12.75\n * Explanation: Maximum average is (12-5-6+50)/4 = 51/4 = 12.75\n *\n * Note:\n * 1 <= k <= n <= 30,000.\n * Elements of the given array will be in the range [-10,000, 10,000].\n */\n\npublic class MaximumAverageSubarrayI643 {\n    public double findMaxAverage(int[] nums, int k) {\n        if (nums.length < k) return 0.0;\n        int len = nums.length;\n        long res = 0;\n        \n        for (int i=0; i<k; i++) {\n            res += (long) nums[i];\n        }\n        \n        long tmp = res;\n        for (int i=0; i<len-k; i++) {\n            tmp -= nums[i];\n            tmp += nums[i+k];\n            if (tmp > res) res = tmp;\n        }\n        \n        return res / (k * 1.0);\n    }\n}\n"
  },
  {
    "path": "src/MaximumBinaryTree654.java",
    "content": "/**\n * Given an integer array with no duplicates. A maximum tree building on this\n * array is defined as follow:\n * \n * The root is the maximum number in the array.\n * The left subtree is the maximum tree constructed from left part subarray\n * divided by the maximum number.\n * The right subtree is the maximum tree constructed from right part subarray\n * divided by the maximum number.\n * \n * Construct the maximum tree by the given array and output the root node of\n * this tree.\n * \n * Example 1:\n * Input: [3,2,1,6,0,5]\n * Output: return the tree root node representing the following tree:\n * \n *       6\n *     /   \\\n *    3     5\n *     \\    / \n *      2  0   \n *        \\\n *         1\n * Note:\n * The size of the given array will be in the range [1,1000].\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class MaximumBinaryTree654 {\n    public TreeNode constructMaximumBinaryTree(int[] nums) {\n        return constructMaximumBinaryTree(nums, 0, nums.length-1);\n    }\n\n    public TreeNode constructMaximumBinaryTree(int[] nums, int lo, int hi) {\n        if (lo > hi) return null;\n        if (lo == hi) return new TreeNode(nums[lo]);\n        \n        int idx = maxIndex(nums, lo, hi);\n        TreeNode root = new TreeNode(nums[idx]);\n        root.left = constructMaximumBinaryTree(nums, lo, idx-1);\n        root.right = constructMaximumBinaryTree(nums, idx+1, hi);\n        return root;\n    }\n\n    private int maxIndex(int[] nums, int lo, int hi) {\n        int res = lo;\n        int max = nums[lo];\n        for (int i=lo; i<=hi; i++) {\n            if (nums[i] > max) {\n                max = nums[i];\n                res = i;\n            }\n        }\n        return res;\n    }\n\n\n    public TreeNode constructMaximumBinaryTree2(int[] nums) {\n        Stack<TreeNode> stack = new Stack<>();\n        for (int i=0; i<nums.length; i++) {\n            TreeNode curr = new TreeNode(nums[i]);\n            if (stack.isEmpty() || stack.peek().val > nums[i]) {\n                stack.push(curr);\n                continue;\n            }\n\n            TreeNode left = null;\n            while (!stack.isEmpty() && stack.peek().val < nums[i]) {\n                TreeNode temp = stack.pop();\n                temp.right = left;\n                left = temp;                \n            }\n            curr.left = left;\n            stack.push(curr);\n        }\n    \n        TreeNode res = null;\n        while (!stack.isEmpty()) {\n            TreeNode temp = stack.pop();\n            temp.right = res;\n            res = temp;                \n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/maximum-binary-tree/discuss/106156/Java-worst-case-O(N)-solution\n     */\n    public TreeNode constructMaximumBinaryTree3(int[] nums) {\n        Deque<TreeNode> stack = new LinkedList<>();\n        for(int i = 0; i < nums.length; i++) {\n            TreeNode curr = new TreeNode(nums[i]);\n            while(!stack.isEmpty() && stack.peek().val < nums[i]) {\n                curr.left = stack.pop();\n            }\n            if(!stack.isEmpty()) {\n                stack.peek().right = curr;\n            }\n            stack.push(curr);\n        }\n        \n        return stack.isEmpty() ? null : stack.removeLast();\n    }\n\n}\n\n"
  },
  {
    "path": "src/MaximumDepthOfBinaryTree104.java",
    "content": "/**\n * Given a binary tree, find its maximum depth.\n *\n * The maximum depth is the number of nodes along the longest path from the\n * root node down to the farthest leaf node.\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\n\nimport java.util.Stack;\n\n\npublic class MaximumDepthOfBinaryTree104 {\n    public int maxDepth(TreeNode root) {\n       if (root == null){\n           return 0;\n       }\n\n       int left = maxDepth(root.left);\n       int right = maxDepth(root.right);\n       return Math.max(left, right) + 1;\n   }\n\n}\n"
  },
  {
    "path": "src/MaximumFrequencyStack895.java",
    "content": "/**\n * Implement FreqStack, a class which simulates the operation of a stack-like\n * data structure.\n * \n * FreqStack has two functions:\n * push(int x), which pushes an integer x onto the stack.\n * pop(), which removes and returns the most frequent element in the stack.\n * \n * If there is a tie for most frequent element, the element closest to the top\n * of the stack is removed and returned.\n * \n * Example 1:\n * Input: \n * [\"FreqStack\",\"push\",\"push\",\"push\",\"push\",\"push\",\"push\",\"pop\",\"pop\",\"pop\",\"pop\"],\n * [[],[5],[7],[5],[7],[4],[5],[],[],[],[]]\n * Output: [null,null,null,null,null,null,null,5,7,5,4]\n * Explanation:\n * After making six .push operations, the stack is [5,7,5,7,4,5] from bottom\n * to top.  Then:\n * \n * pop() -> returns 5, as 5 is the most frequent.\n * The stack becomes [5,7,5,7,4].\n * \n * pop() -> returns 7, as 5 and 7 is the most frequent, but 7 is closest to the top.\n * The stack becomes [5,7,5,4].\n * \n * pop() -> returns 5.\n * The stack becomes [5,7,4].\n * \n * pop() -> returns 4.\n * The stack becomes [5,7].\n * \n * Note:\n * Calls to FreqStack.push(int x) will be such that 0 <= x <= 10^9.\n * It is guaranteed that FreqStack.pop() won't be called if the stack has zero elements.\n * The total number of FreqStack.push calls will not exceed 10000 in a single test case.\n * The total number of FreqStack.pop calls will not exceed 10000 in a single test case.\n * The total number of FreqStack.push and FreqStack.pop calls will not exceed 150000 across all test cases.\n */\n\npublic class MaximumFrequencyStack895 {\n    /**\n     * https://leetcode.com/problems/maximum-frequency-stack/solution/\n     */\n    class FreqStack {\n        Map<Integer, Integer> freq;\n        Map<Integer, Stack<Integer>> group;\n        int maxfreq;\n\n        public FreqStack() {\n            freq = new HashMap();\n            group = new HashMap();\n            maxfreq = 0;\n        }\n\n        public void push(int x) {\n            int f = freq.getOrDefault(x, 0) + 1;\n            freq.put(x, f);\n            if (f > maxfreq)\n                maxfreq = f;\n\n            group.computeIfAbsent(f, z-> new Stack()).push(x);\n        }\n\n        public int pop() {\n            int x = group.get(maxfreq).pop();\n            freq.put(x, freq.get(x) - 1);\n            if (group.get(maxfreq).size() == 0)\n                maxfreq--;\n            return x;\n        }\n    }\n\n\n/**\n * Your FreqStack object will be instantiated and called as such:\n * FreqStack obj = new FreqStack();\n * obj.push(x);\n * int param_2 = obj.pop();\n */\n\n}\n"
  },
  {
    "path": "src/MaximumLengthOfPairChain646.java",
    "content": "/**\n * You are given n pairs of numbers. In every pair, the first number is always\n * smaller than the second number.\n * \n * Now, we define a pair (c, d) can follow another pair (a, b) if and\n * only if b < c. Chain of pairs can be formed in this fashion.\n * \n * Given a set of pairs, find the length longest chain which can be formed.\n * You needn't use up all the given pairs. You can select pairs in any order.\n * \n * Example 1:\n * Input: [[1,2], [2,3], [3,4]]\n * Output: 2\n * Explanation: The longest chain is [1,2] -> [3,4]\n * \n * Note:\n * The number of given pairs will be in the range [1, 1000].\n */\n\npublic class MaximumLengthOfPairChain646 {\n    public int findLongestChain(int[][] pairs) {\n        if (pairs == null || pairs.length == 0) return 0;\n        Arrays.sort(pairs, (p1, p2) -> Integer.compare(p1[0], p2[0]));\n        int N = pairs.length;\n        int[] dp = new int[N + 1];\n        int res = 0;\n        for (int i=1; i<=N; i++) {\n            int local = 1;\n            for (int j=1; j<i; j++) {\n                if (pairs[i-1][0] > pairs[j-1][1] && dp[j] + 1 > local) {\n                    local = dp[j] + 1;\n                }\n            }\n            dp[i] = local;\n            if (local > res) {\n                res = local;\n            }\n        }\n        return res;\n    }\n\n\n    public int findLongestChain2(int[][] pairs) {\n        if (pairs == null || pairs.length == 0) return 0;\n        Arrays.sort(pairs, (p1, p2) -> Integer.compare(p1[0], p2[0]));\n        LinkedList<int[]> list = new LinkedList<>();\n        for (int[] p: pairs) {\n            if (list.isEmpty() || list.getLast()[1] < p[0]) {\n                list.add(p);\n            } else {\n                if (p[1] < list.getLast()[1]) {\n                    list.removeLast();\n                    list.add(p);\n                }\n            }\n        }\n        return list.size();\n    }\n\n\n    public int findLongestChain3(int[][] pairs) {\n        if (pairs == null || pairs.length == 0) return 0;\n        Arrays.sort(pairs, (p1, p2) -> Integer.compare(p1[0], p2[0]));\n        int[] last = null;\n        int res = 0;\n        for (int[] p: pairs) {\n            if (last == null || last[1] < p[0]) {\n                last = p;\n                res++;\n            } else {\n                if (p[1] < last[1]) {\n                    last = p;\n                }\n            }\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/MaximumLengthOfRepeatedSubarray718.java",
    "content": "/**\n * Given two integer arrays A and B, return the maximum length of an subarray\n * that appears in both arrays.\n *\n * Example 1:\n * Input:\n * A: [1,2,3,2,1]\n * B: [3,2,1,4,7]\n * Output: 3\n *\n * Explanation:\n * The repeated subarray with maximum length is [3, 2, 1].\n *\n * Note:\n * 1 <= len(A), len(B) <= 1000\n * 0 <= A[i], B[i] < 100\n *\n */\n\n\npublic class MaximumLengthOfRepeatedSubarray718 {\n    public int findLength(int[] A, int[] B) {\n        int[][] res = new int[A.length+1][B.length+1];\n        int[][] lens = new int[A.length+1][B.length+1];\n\n        for (int i=1; i<=A.length; i++) {\n            for (int j=1; j<=B.length; j++) {\n                lens[i][j] = (A[i-1] == B[j-1]) ? lens[i-1][j-1] + 1 : 0 ;\n                res[i][j] = Math.max(lens[i][j], Math.max(res[i][j-1], res[i-1][j]));\n            }\n        }\n\n        return res[A.length][B.length];\n    }\n\n    public int findLength2(int[] A, int[] B) {\n        int[] res = new int[B.length+1];\n        int[] lens = new int[B.length+1];\n        int lens0 = 0;\n\n        for (int i=1; i<=A.length; i++) {\n            for (int j=1; j<=B.length; j++) {\n                int tempLens = lens[j];\n                lens[j] = (A[i-1] == B[j-1]) ? lens0 + 1 : 0;\n                lens0 = tempLens;\n                res[j] = Math.max(lens[j], Math.max(res[j-1], res[j]));\n            }\n            lens0 = 0;\n        }\n\n        return res[B.length];\n    }\n\n    /**\n     * https://leetcode.com/problems/maximum-length-of-repeated-subarray/solution/\n     */\n    public int findLength3(int[] A, int[] B) {\n        int ans = 0;\n        int[][] memo = new int[A.length + 1][B.length + 1];\n        for (int i = A.length - 1; i >= 0; --i) {\n            for (int j = B.length - 1; j >= 0; --j) {\n                if (A[i] == B[j]) {\n                    memo[i][j] = memo[i+1][j+1] + 1;\n                    ans = Math.max(ans, memo[i][j]);\n                }\n            }\n        }\n        return ans;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/108760/java-c-clean-code-8-lines\n     */\n    public int findLength4(int[] a, int[] b) {\n        int m = a.length, n = b.length;\n        if (m == 0 || n == 0) return 0;\n        int[] dp = new int[n + 1];\n        int max = 0;\n        for (int i = m - 1; i >= 0; i--)\n            for (int j = 0; j < n; j++)\n                max = Math.max(max, dp[j] = a[i] == b[j] ? 1 + dp[j + 1] : 0);\n        return max;\n    }\n\n\n    public int findLength5(int[] A, int[] B) {\n        int lenA = A.length;\n        int lenB = B.length;\n        int res = 0;\n        int[][] dp = new int[lenA + 1][lenB + 1];\n        \n        for (int i=1; i<=lenA; i++) {\n            for (int j=1; j<=lenB; j++) {\n                if (A[i-1] == B[j-1]) {\n                    dp[i][j] = dp[i-1][j-1] + 1;\n                    if (dp[i][j] > res) res = dp[i][j];\n                }\n            }\n        }\n        \n        return res;\n    }\n\n\n    public int findLength6(int[] A, int[] B) {\n        int lenA = A.length;\n        int lenB = B.length;\n        int res = 0;\n        int[] dp = new int[lenB + 1];\n        for (int i=1; i<=lenA; i++) {\n            int pre = 0;\n            for (int j=1; j<=lenB; j++) {\n                int tmp = dp[j];\n                if (A[i-1] == B[j-1]) {\n                    dp[j] = pre + 1;\n                    if (dp[j] > res) res = dp[j];\n                } else {\n                    dp[j] = 0;\n                }\n                pre = tmp;\n            }\n        }\n        \n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/MaximumProductOfThreeNumbers628.java",
    "content": "/**\n * Given an integer array, find three numbers whose product is maximum and\n * output the maximum product.\n *\n * Example 1:\n * Input: [1,2,3]\n * Output: 6\n *\n * Example 2:\n * Input: [1,2,3,4]\n * Output: 24\n *\n * Note:\n * The length of the given array will be in range [3,104] and all elements are\n * in the range [-1000, 1000].\n * Multiplication of any three numbers in the input won't exceed the range of\n * 32-bit signed integer.\n *\n */\n\n\npublic class MaximumProductOfThreeNumbers628 {\n    public int maximumProduct(int[] nums) {\n        if (nums == null || nums.length < 3) return 0;\n        int len = nums.length;\n        Arrays.sort(nums);\n        return Math.max(nums[0] * nums[1] * nums[len - 1], nums[len - 1] * nums[len - 2] * nums[len - 3]);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/maximum-product-of-three-numbers/solution/\n     */\n    public int maximumProduct2(int[] nums) {\n        int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;\n        int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE;\n        for (int n: nums) {\n            if (n <= min1) {\n                min2 = min1;\n                min1 = n;\n            } else if (n <= min2) {     // n lies between min1 and min2\n                min2 = n;\n            }\n            if (n >= max1) {            // n is greater than max1, max2 and max3\n                max3 = max2;\n                max2 = max1;\n                max1 = n;\n            } else if (n >= max2) {     // n lies betweeen max1 and max2\n                max3 = max2;\n                max2 = n;\n            } else if (n >= max3) {     // n lies betwen max2 and max3\n                max3 = n;\n            }\n        }\n        return Math.max(min1 * min2 * max1, max1 * max2 * max3);\n    }\n\n}\n"
  },
  {
    "path": "src/MaximumProductOfWordLengths318.java",
    "content": "/**\n * Given a string array words, find the maximum value of\n * length(word[i]) * length(word[j]) where the two words do not share common\n * letters. You may assume that each word will contain only lower case letters.\n * If no such two words exist, return 0.\n * \n * Example 1:\n * Input: [\"abcw\",\"baz\",\"foo\",\"bar\",\"xtfn\",\"abcdef\"]\n * Output: 16 \n * Explanation: The two words can be \"abcw\", \"xtfn\".\n * \n * Example 2:\n * Input: [\"a\",\"ab\",\"abc\",\"d\",\"cd\",\"bcd\",\"abcd\"]\n * Output: 4 \n * Explanation: The two words can be \"ab\", \"cd\".\n * \n * Example 3:\n * Input: [\"a\",\"aa\",\"aaa\",\"aaaa\"]\n * Output: 0 \n * Explanation: No such pair of words.\n */\n\npublic class MaximumProductOfWordLengths318 {\n    public int maxProduct(String[] words) {\n        if (words == null || words.length == 0) return 0;\n        int len = words.length;\n        int[] map = new int[len];\n        for (int i=0; i<len; i++) map[i] = bits(words[i]);\n        \n        int max = 0;\n        for (int i=0; i<len; i++) {\n            String a = words[i];\n            int bitsA = map[i];\n            for (int j=i+1; j<len; j++) {\n                String b = words[j];\n                int bitsB = map[j];\n                if ((bitsA & bitsB) == 0) {\n                    max = Math.max(max, a.length() * b.length());\n                }\n            }\n        }\n        \n        return max;\n    }\n    \n    private int bits(String word) {\n        int res = 0;\n        for (char c: word.toCharArray()) {\n            res |= 1 << (c - 'a');\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/MaximumProductSubarray152.java",
    "content": "/**\n * Given an integer array nums, find the contiguous subarray within an array\n * (containing at least one number) which has the largest product.\n * \n * Example 1:\n * Input: [2,3,-2,4]\n * Output: 6\n * Explanation: [2,3] has the largest product 6.\n * \n * Example 2:\n * Input: [-2,0,-1]\n * Output: 0\n * Explanation: The result cannot be 2, because [-2,-1] is not a subarray.\n */\n\npublic class MaximumProductSubarray152 {\n    // time O(n), space O(n)\n    public int maxProduct(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        int len = nums.length;\n        if (len == 1) return nums[0];\n        boolean hasZero = false;\n        int[] pos = new int[len+1];\n        int[] neg = new int[len+1];\n        int res = Integer.MIN_VALUE;\n        for (int i=0; i<nums.length; i++) {\n            int now = nums[i];\n            if (now > 0) {\n                pos[i+1] = pos[i] == 0 ? now : pos[i] * now;\n                neg[i+1] = neg[i] == 0 ? 0 : neg[i] * now;\n            } else if (now < 0) {\n                pos[i+1] = neg[i] == 0 ? 0 : neg[i] * now;\n                neg[i+1] = pos[i] == 0 ? now : pos[i] * now;\n            } else {\n                hasZero = true;\n            }\n            if (pos[i+1] != 0 && pos[i+1] > res) {\n                res = pos[i+1];\n            }\n            if (neg[i+1] != 0 && neg[i+1] > res) {\n                res = neg[i+1];\n            }\n        }\n        return (hasZero && res < 0) ? 0 : res;\n    }\n\n    // time O(n), space O(1)\n    public int maxProduct2(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        int len = nums.length;\n        if (len == 1) return nums[0];\n        boolean hasZero = false;\n        int pos = 0;\n        int neg = 0;\n        int res = Integer.MIN_VALUE;\n        for (int i=0; i<nums.length; i++) {\n            int now = nums[i];\n            int oldPos = pos;\n            int oldNeg = neg;\n            if (now > 0) {\n                pos = oldPos == 0 ? now : oldPos * now;\n                neg = oldNeg == 0 ? 0 : oldNeg * now;\n            } else if (now < 0) {\n                pos = oldNeg == 0 ? 0 : oldNeg * now;\n                neg = oldPos == 0 ? now : oldPos * now;\n            } else {\n                hasZero = true;\n                pos = 0;\n                neg = 0;\n            }\n            if (pos != 0 && pos > res) {\n                res = pos;\n            }\n            if (neg != 0 && neg > res) {\n                res = neg;\n            }\n        }\n        return (hasZero && res < 0) ? 0 : res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/maximum-product-subarray/discuss/48330/Simple-Java-code\n     */\n    public int maxProduct3(int[] A) {\n        if (A == null || A.length == 0) {\n            return 0;\n        }\n        int max = A[0], min = A[0], result = A[0];\n        for (int i = 1; i < A.length; i++) {\n            int temp = max;\n            max = Math.max(Math.max(max * A[i], min * A[i]), A[i]);\n            min = Math.min(Math.min(temp * A[i], min * A[i]), A[i]);\n            if (max > result) {\n                result = max;\n            }\n        }\n        return result;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/maximum-product-subarray/discuss/48230/Possibly-simplest-solution-with-O(n)-time-complexity\n     */\n    public int maxProduct4(int A[]) {\n        // store the result that is the max we have found so far\n        int r = A[0];\n    \n        // imax/imin stores the max/min product of\n        // subarray that ends with the current number A[i]\n        for (int i = 1, imax = r, imin = r; i < A.length; i++) {\n            // multiplied by a negative makes big number smaller, small number bigger\n            // so we redefine the extremums by swapping them\n            if (A[i] < 0) {\n                int t = imax;\n                imax = imin;\n                imin = t;\n            }\n    \n            // max/min product for the current number is either the current number itself\n            // or the max/min by the previous number times the current one\n            imax = Math.max(A[i], imax * A[i]);\n            imin = Math.min(A[i], imin * A[i]);\n    \n            // the newly computed max value is a candidate for our global result\n            r = Math.max(r, imax);\n        }\n        return r;\n    }\n\n}\n"
  },
  {
    "path": "src/MaximumSizeSubarraySumEqualsK325.java",
    "content": "/**\n * Given an array nums and a target value k, find the maximum length of a\n * subarray that sums to k. If there isn't one, return 0 instead.\n *\n * Note:\n * The sum of the entire nums array is guaranteed to fit within the 32-bit\n * signed integer range.\n *\n * Example 1:\n * Given nums = [1, -1, 5, -2, 3], k = 3,\n * return 4. (because the subarray [1, -1, 5, -2] sums to 3 and is the longest)\n *\n * Example 2:\n * Given nums = [-2, -1, 2, 1], k = 1,\n * return 2. (because the subarray [-1, 2] sums to 1 and is the longest)\n *\n * Follow Up:\n * Can you do it in O(n) time?\n *\n */\n\n\npublic class MaximumSizeSubarraySumEqualsK325 {\n    // brute force\n    public int maxSubArrayLen(int[] nums, int k) {\n        int max = Integer.MIN_VALUE;\n        for (int i=0; i<nums.length; i++) {\n            int sum = 0;\n            for (int j=i; j<nums.length; j++) {\n                sum += nums[j];\n                if (sum == k) max = Math.max(max, j-i+1);\n            }\n        }\n\n        return max == Integer.MIN_VALUE ? 0 : max;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/maximum-size-subarray-sum-equals-k/discuss/77784/O(n)-super-clean-9-line-Java-solution-with-HashMap\n     */\n    public int maxSubArrayLen2(int[] nums, int k) {\n        int max = 0;\n        int sum = 0;\n        Map<Integer, Integer> map = new HashMap<>();\n        for (int i=0; i<nums.length; i++) {\n            sum += nums[i];\n            if (sum == k) {\n                max = i + 1;\n            } else if (map.containsKey(sum-k)) {\n                max = Math.max(max, i-map.get(sum-k));\n            }\n            if (!map.containsKey(sum)) map.put(sum, i);\n        }\n\n        return max;\n    }\n\n\n    public int maxSubArrayLen3(int[] nums, int k) {\n        if (nums == null || nums.length == 0) return 0; \n\n        Map<Integer, Integer> map = new HashMap<>();\n        int len = nums.length;\n        int res = 0;\n        int sum = 0;\n        map.put(0, -1);\n        for (int i=0; i<len; i++) {\n            sum += nums[i];\n            int remain = sum - k;\n            if (map.containsKey(remain)) {\n                int idx = map.get(remain);\n                if (i - idx > res) res = i - idx;\n            }\n            if (!map.containsKey(sum)) map.put(sum, i);\n        }\n\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/MaximumSubarray53.java",
    "content": "/**\n * Find the contiguous subarray within an array (containing at least one number)\n * which has the largest sum.\n *\n * For example, given the array [-2,1,-3,4,-1,2,1,-5,4],\n * the contiguous subarray [4,-1,2,1] has the largest sum = 6.\n *\n * More practice:\n * If you have figured out the O(n) solution, try coding another solution using\n * the divide and conquer approach, which is more subtle.\n */\n\nimport java.util.Arrays;\n\npublic class MaximumSubarray53 {\n    public int maxSubArray(int[] nums) {\n        int n = nums.length;\n        if (n == 0) {\n            return 0;\n        }\n\n        int[] dp = new int[n];\n        dp[0] = nums[0];\n\n        for (int i = 1; i < n; i++) {\n            dp[i] = Math.max(nums[i], Math.max(dp[i-1] + nums[i], nums[i-1] + nums[i]));\n        }\n\n        int max = Integer.MIN_VALUE;\n        for(int i = 0; i < dp.length; i++) {\n            if(dp[i] > max) {\n                max = dp[i];\n            }\n        }\n        return max;\n    }\n\n    /**\n     * https://leetcode.com/problems/maximum-subarray/discuss/20210/O(n)-Java-solution\n     */\n    public int maxSubArray2(int[] A) {\n        int max = Integer.MIN_VALUE, sum = 0;\n        for (int i = 0; i < A.length; i++) {\n            if (sum < 0)\n                sum = A[i];\n            else\n                sum += A[i];\n            if (sum > max)\n                max = sum;\n        }\n        return max;\n    }\n\n\n    // divide-and-conquer\n    public int maxSubArray3(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        return maxSubArray(nums, 0, nums.length-1);\n    }\n    \n    private int maxSubArray(int[] nums, int left, int right) {\n        if (left > right) return Integer.MIN_VALUE;\n        if (left == right) return nums[left];\n        int mid = (left + right) / 2;\n        int L = maxSubArray(nums, left, mid-1);\n        int R = maxSubArray(nums, mid+1, right);\n        int leftSum = 0;\n        int tmp = 0;\n        for (int i=mid-1; i>=left; i--) {\n            tmp += nums[i];\n            if (tmp > leftSum) leftSum = tmp;\n        }\n        tmp = 0;\n        int rightSum = 0;\n        for (int i=mid+1; i<=right; i++) {\n            tmp += nums[i];\n            if (tmp > rightSum) rightSum = tmp;\n        }\n        return Math.max(Math.max(L, R), leftSum + rightSum + nums[mid]);\n    }\n\n\n    public static void main(String[] args) {\n        MaximumSubarray53 ms = new MaximumSubarray53();\n\n        System.out.println(ms.maxSubArray(new int[]{-2, 1, -3, 4, -1, 2, 1, -5, 4}));\n        System.out.println(ms.maxSubArray(new int[]{-2, 1, -3, 4, -1, 2, 1, -5, 8}));\n        System.out.println(ms.maxSubArray(new int[]{-2, -1}));\n        System.out.println(ms.maxSubArray(new int[]{8, -19, 5, -4, 20}));\n    }\n\n\n}\n"
  },
  {
    "path": "src/MaximumSumOf3NonOverlappingSubarrays689.java",
    "content": "/**\n * In a given array nums of positive integers, find three non-overlapping\n * subarrays with maximum sum.\n *\n * Each subarray will be of size k, and we want to maximize the sum of all\n * 3*k entries.\n *\n * Return the result as a list of indices representing the starting position of\n * each interval (0-indexed). If there are multiple answers, return the\n * lexicographically smallest one.\n *\n * Example:\n * Input: [1,2,1,2,6,7,5,1], 2\n * Output: [0, 3, 5]\n * Explanation: Subarrays [1, 2], [2, 6], [7, 5] correspond to the starting\n * indices [0, 3, 5].\n *\n * We could have also taken [2, 1], but an answer of [1, 3, 5] would be\n * lexicographically larger.\n *\n * Note:\n * nums.length will be between 1 and 20000.\n * nums[i] will be between 1 and 65535.\n * k will be between 1 and floor(nums.length / 3).\n *\n */\n\n\npublic class MaximumSumOf3NonOverlappingSubarrays689 {\n    public int[] maxSumOfThreeSubarrays(int[] nums, int k) {\n        int[] sums = new int[nums.length+1];\n        for (int i=1; i<=nums.length; i++) sums[i] = sums[i-1] + nums[i-1];\n\n        int[][] dp = new int[4][nums.length+1];\n        boolean[][] choose = new boolean[3][nums.length];\n        for (int i=1; i<=3; i++) {\n            int start = i * k;\n            for (int j=start; j<=nums.length; j++) {\n                int pre = dp[i][j-1];\n                int cur = dp[i-1][j-k] + sums[j] - sums[j-k];\n                dp[i][j] = Math.max(cur, pre);\n                if (cur > pre) choose[i-1][j-1] = true;\n            }\n        }\n\n        int[] res = new int[3];\n        int i = 2;\n        int j = nums.length-1;\n        while (i >= 0) {\n            while (choose[i][j] == false) j--;\n            res[i] = j-k+1;\n            i--;\n            j = j-k;\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/maximum-sum-of-3-non-overlapping-subarrays/solution/\n     */\n    public int[] maxSumOfThreeSubarrays2(int[] nums, int K) {\n        //W is an array of sums of windows\n        int[] W = new int[nums.length - K + 1];\n        int sum = 0;\n        for (int i = 0; i < nums.length; i++) {\n            sum += nums[i];\n            if (i >= K) sum -= nums[i-K];\n            if (i >= K-1) W[i-K+1] = sum;\n        }\n\n        int[] left = new int[W.length];\n        int best = 0;\n        for (int i = 0; i < W.length; i++) {\n            if (W[i] > W[best]) best = i;\n            left[i] = best;\n        }\n\n        int[] right = new int[W.length];\n        best = W.length - 1;\n        for (int i = W.length - 1; i >= 0; i--) {\n            if (W[i] >= W[best]) best = i;\n            right[i] = best;\n        }\n\n        int[] ans = new int[]{-1, -1, -1};\n        for (int j = K; j < W.length - K; j++) {\n            int i = left[j - K], k = right[j + K];\n            if (ans[0] == -1 || W[i] + W[j] + W[k] >\n                    W[ans[0]] + W[ans[1]] + W[ans[2]]) {\n\n                ans[0] = i;\n                ans[1] = j;\n                ans[2] = k;\n            }\n        }\n        return ans;\n    }\n\n}\n"
  },
  {
    "path": "src/MaximumVacationDays568.java",
    "content": "/**\n * LeetCode wants to give one of its best employees the option to travel among\n * N cities to collect algorithm problems. But all work and no play makes Jack\n * a dull boy, you could take vacations in some particular cities and weeks.\n * Your job is to schedule the traveling to maximize the number of vacation\n * days you could take, but there are certain rules and restrictions you need\n * to follow.\n * \n * Rules and restrictions:\n * You can only travel among N cities, represented by indexes from 0 to N-1.\n * Initially, you are in the city indexed 0 on Monday.\n *\n * The cities are connected by flights. The flights are represented as a N*N\n * matrix (not necessary symmetrical), called flights representing the airline\n * status from the city i to the city j. If there is no flight from the city i\n * to the city j, flights[i][j] = 0; Otherwise, flights[i][j] = 1. Also,\n * flights[i][i] = 0 for all i.\n * \n * You totally have K weeks (each week has 7 days) to travel. You can only take\n * flights at most once per day and can only take flights on each week's Monday\n * morning. Since flight time is so short, we don't consider the impact of\n * flight time.\n * \n * For each city, you can only have restricted vacation days in different\n * weeks, given an N*K matrix called days representing this relationship.\n * For the value of days[i][j], it represents the maximum days you could take\n * vacation in the city i in the week j.\n * \n * You're given the flights matrix and days matrix, and you need to output the\n * maximum vacation days you could take during K weeks.\n * \n * Example 1:\n * Input:flights = [[0,1,1],[1,0,1],[1,1,0]], days = [[1,3,1],[6,0,3],[3,3,3]]\n * Output: 12\n * Explanation: \n * Ans = 6 + 3 + 3 = 12. \n * \n * One of the best strategies is:\n * 1st week : fly from city 0 to city 1 on Monday, and play 6 days and work 1 day. \n * (Although you start at city 0, we could also fly to and start at other cities since it is Monday.) \n * 2nd week : fly from city 1 to city 2 on Monday, and play 3 days and work 4 days.\n * 3rd week : stay at city 2, and play 3 days and work 4 days.\n * \n * Example 2:\n * Input:flights = [[0,0,0],[0,0,0],[0,0,0]], days = [[1,1,1],[7,7,7],[7,7,7]]\n * Output: 3\n * Explanation: \n * Ans = 1 + 1 + 1 = 3. \n * \n * Since there is no flights enable you to move to another city, you have to\n * stay at city 0 for the whole 3 weeks. \n * For each week, you only have one day to play and six days to work. \n * So the maximum number of vacation days is 3.\n * \n * Example 3:\n * Input:flights = [[0,1,1],[1,0,1],[1,1,0]], days = [[7,0,0],[0,7,0],[0,0,7]]\n * Output: 21\n * Explanation:\n * Ans = 7 + 7 + 7 = 21\n * \n * One of the best strategies is:\n * 1st week : stay at city 0, and play 7 days. \n * 2nd week : fly from city 0 to city 1 on Monday, and play 7 days.\n * 3rd week : fly from city 1 to city 2 on Monday, and play 7 days.\n *\n * Note:\n * N and K are positive integers, which are in the range of [1, 100].\n * In the matrix flights, all the values are integers in the range of [0, 1].\n * In the matrix days, all the values are integers in the range [0, 7].\n * You could stay at a city beyond the number of vacation days, but you should\n * work on the extra days, which won't be counted as vacation days.\n * If you fly from the city A to the city B and take the vacation on that day,\n * the deduction towards vacation days will count towards the vacation days of\n * city B in that week.\n * We don't consider the impact of flight hours towards the calculation of\n * vacation days.\n */\n\npublic class MaximumVacationDays568 {\n    public int maxVacationDays(int[][] flights, int[][] days) {\n        if (days.length == 0 || days[0].length == 0) return 0;\n        int N = days.length;\n        int K = days[0].length;\n        int[][] dp = new int[N][K];\n        for (int i=0; i<N; i++) dp[i][K-1] = days[i][K-1];\n        for (int k=K-2; k>=0; k--) {\n            for (int i=0; i<N; i++) {\n                int temp = 0;\n                for (int j=0; j<N; j++) {\n                    if ((flights[i][j] == 1 || i == j) && dp[j][k+1] > temp) {\n                        temp = dp[j][k+1];\n                    }\n                    \n                }\n                dp[i][k] = temp + days[i][k];\n            }\n        }\n        int res = 0;\n        for (int i=0; i<N; i++) {\n            if ((flights[0][i] == 1 || i == 0) && dp[i][0] > res) {\n                res = dp[i][0];\n            }\n        }\n        return res;\n    }\n\n\n    public int maxVacationDays2(int[][] flights, int[][] days) {\n        if (days.length == 0 || days[0].length == 0) return 0;\n        int N = days.length;\n        int K = days[0].length;\n        int[][] dp = new int[N][2];\n        int col = K;\n        for (int i=0; i<N; i++) dp[i][col%2] = days[i][K-1];\n        col--;\n        for (int k=K-2; k>=0; k--) {\n            for (int i=0; i<N; i++) {\n                int temp = 0;\n                int pre = (col+1) % 2;\n                for (int j=0; j<N; j++) {\n                    if ((flights[i][j] == 1 || i == j) && dp[j][pre] > temp) {\n                        temp = dp[j][pre];\n                    }\n                    \n                }\n                dp[i][col%2] = temp + days[i][k];\n            }\n            col--;\n        }\n        col++;\n        int res = 0;\n        for (int i=0; i<N; i++) {\n            if ((flights[0][i] == 1 || i == 0) && dp[i][col%2] > res) {\n                res = dp[i][col%2];\n            }\n        }\n        return res;\n    }\n  \n\n    /**\n     * https://leetcode.com/problems/maximum-vacation-days/discuss/138174/Beats-99.82-without-any-extra-space.-DP-solution\n     */\n    public int maxVacationDays3(int[][] flights, int[][] days) {\n        for(int day=days[0].length-2;day>=0;day--){\n            for(int city=0;city<flights.length;city++){\n                int max=days[city][day+1];\n                for(int flight=0;flight<flights.length;flight++){\n                    max=Math.max(days[flight][day+1]*flights[city][flight],max);\n                }\n                days[city][day]+=max;\n            }\n        }       \n        int ans=days[0][0];\n        for(int city=0;city<flights.length;city++){\n                ans=Math.max(days[city][0]*flights[0][city],ans);\n            }\n        return ans;\n    }\n\n}\n"
  },
  {
    "path": "src/MaximumWidthOfBinaryTree662.java",
    "content": "/**\n * Given a binary tree, write a function to get the maximum width of the given\n * tree. The width of a tree is the maximum width among all levels. The binary\n * tree has the same structure as a full binary tree, but some nodes are null.\n * \n * The width of one level is defined as the length between the end-nodes (the\n * leftmost and right most non-null nodes in the level, where the null nodes\n * between the end-nodes are also counted into the length calculation.\n * \n * Example 1:\n * Input: \n * \n *            1\n *          /   \\\n *         3     2\n *        / \\     \\  \n *       5   3     9 \n * \n * Output: 4\n * Explanation: The maximum width existing in the third level with the\n * length 4 (5,3,null,9).\n * \n * \n * Example 2:\n * Input: \n * \n *           1\n *          /  \n *         3    \n *        / \\       \n *       5   3     \n * \n * Output: 2\n * Explanation: The maximum width existing in the third level with the\n * length 2 (5,3).\n * \n * \n * Example 3:\n * Input: \n * \n *           1\n *          / \\\n *         3   2 \n *        /        \n *       5      \n * \n * Output: 2\n * Explanation: The maximum width existing in the second level with the\n * length 2 (3,2).\n * \n * \n * Example 4:\n * Input: \n * \n *           1\n *          / \\\n *         3   2\n *        /     \\  \n *       5       9 \n *      /         \\\n *     6           7\n * Output: 8\n * Explanation:The maximum width existing in the fourth level with the\n * length 8 (6,null,null,null,null,null,null,7).\n * \n * Note: Answer will in the range of 32-bit signed integer.\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class MaximumWidthOfBinaryTree662 {\n    // Memory Limit Exceeded \n    public int widthOfBinaryTree(TreeNode root) {\n        if (root == null) return 0;\n        \n        Queue<TreeNode> q = new LinkedList<>();\n        q.add(root);\n        int maxWidth = 0;\n        while (!q.isEmpty()) {\n            int count = 0;\n            int left = -1;\n            int size = q.size();\n            for (int i=0; i<size; i++) {\n                TreeNode curr = q.poll();\n                if (curr != null && left == -1) left = i;\n                if (curr == null) {\n                    q.add(null);\n                    q.add(null);\n                } else {\n                    count++;\n                    q.add(curr.left);\n                    q.add(curr.right);\n                }\n                if (curr != null && left != -1 && (i - left + 1) > maxWidth) {\n                    maxWidth = i - left + 1;\n                }\n            }\n            if (count == 0) break;\n        }\n        return maxWidth;\n    }\n\n\n    public int widthOfBinaryTree2(TreeNode root) {\n        if (root == null) return 0;\n        \n        Queue<NodeWrapper> q = new LinkedList<>();\n        q.add(new NodeWrapper(root, 0));\n        int maxWidth = 0;\n        while (!q.isEmpty()) {\n            int count = 0;\n            int left = -1;\n            int size = q.size();\n            for (int i=0; i<size; i++) {\n                NodeWrapper wrapper = q.poll();\n                TreeNode curr = wrapper.node;\n                if (curr != null && left == -1) left = wrapper.idx;\n                if (curr != null) {\n                    count++;\n                    q.add(new NodeWrapper(curr.left, wrapper.idx * 2));\n                    q.add(new NodeWrapper(curr.right, wrapper.idx * 2 + 1));\n                }\n                if (curr != null && left != -1 && (wrapper.idx - left + 1) > maxWidth) {\n                    maxWidth = wrapper.idx - left + 1;\n                }\n            }\n            if (count == 0) break;\n        }\n        return maxWidth;\n    }\n    \n    class NodeWrapper {\n        TreeNode node;\n        int idx;\n        NodeWrapper(TreeNode n, int i) {\n            node = n;\n            idx = i;\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/maximum-width-of-binary-tree/solution/\n     */\n    int ans;\n    Map<Integer, Integer> left;\n    public int widthOfBinaryTree3(TreeNode root) {\n        ans = 0;\n        left = new HashMap();\n        dfs(root, 0, 0);\n        return ans;\n    }\n    public void dfs(TreeNode root, int depth, int pos) {\n        if (root == null) return;\n        left.computeIfAbsent(depth, x-> pos);\n        ans = Math.max(ans, pos - left.get(depth) + 1);\n        dfs(root.left, depth + 1, 2 * pos);\n        dfs(root.right, depth + 1, 2 * pos + 1);\n    }\n\n}\n"
  },
  {
    "path": "src/MaximumXOROfTwoNumbersInAnArray421.java",
    "content": "/**\n * Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231.\n * \n * Find the maximum result of ai XOR aj, where 0 ≤ i, j < n.\n * \n * Could you do this in O(n) runtime?\n * \n * Example:\n * Input: [3, 10, 5, 25, 2, 8]\n * Output: 28\n * Explanation: The maximum result is 5 ^ 25 = 28.\n */\n\npublic class MaximumXOROfTwoNumbersInAnArray421 {\n    public int findMaximumXOR(int[] nums) {\n        Trie trie = new Trie();\n        for (int n: nums) trie.add(n);\n        \n        int res = Integer.MIN_VALUE;\n        for (int n: nums) {\n            int d = trie.search(n);\n            if ((n ^ d) > res) res = n ^ d;\n        }\n        return Math.max(res, 0);\n    }\n\n    class Trie {\n        Trie zero;\n        Trie one;\n        Integer num;\n\n        void add(int n) {\n            add(n, 31);\n        }\n\n        void add(int n, int i) {\n            if (i == -1) {\n                num = n;\n                return;\n            }\n            int k = (n >> i) & 1;\n            if (k == 0) {\n                if (zero == null) zero = new Trie();\n                zero.add(n, i-1);\n            } else {\n                if (one == null) one = new Trie();\n                one.add(n, i-1);\n            }\n        }\n\n        int search(int n) {\n            return search(n, 31);\n        }\n\n        int search(int n, int i) {\n            if (i == -1) {\n                return num;\n            }\n            int k = (n >> i) & 1;\n            if (zero == null) return one.search(n, i-1);\n            if (one == null) return zero.search(n, i-1);\n            if (k == 0) return one.search(n, i-1);\n            return zero.search(n, i-1);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/maximum-xor-of-two-numbers-in-an-array/discuss/91049/Java-O(n)-solution-using-bit-manipulation-and-HashMap\n     */\n    public int findMaximumXOR2(int[] nums) {\n        int max = 0, mask = 0;\n        for(int i = 31; i >= 0; i--){\n            mask = mask | (1 << i);\n            Set<Integer> set = new HashSet<>();\n            for(int num : nums){\n                set.add(num & mask);\n            }\n            int tmp = max | (1 << i);\n            for(int prefix : set){\n                if(set.contains(tmp ^ prefix)) {\n                    max = tmp;\n                    break;\n                }\n            }\n        }\n        return max;\n    }\n\n    public int findMaximumXOR3(int[] nums){\n        int N = nums.length;\n        if (N == 1) return 0;\n        int res = Integer.MIN_VALUE;\n        for (int i=0; i<N-1; i++) {\n            for (int j=i+1; j<N; j++) {\n                int newRes = nums[i] ^ nums[j];\n                if (newRes > res) res = newRes;\n            }\n        }\n        return Math.max(res, 0);\n    }\n\n}\n"
  },
  {
    "path": "src/MedianOfTwoSortedArrays4.java",
    "content": "/**\n * There are two sorted arrays nums1 and nums2 of size m and n respectively.\n *\n * Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).\n *\n * Example 1:\n * nums1 = [1, 3]\n * nums2 = [2]\n *\n * The median is 2.0\n *\n *\n * Example 2:\n * nums1 = [1, 2]\n * nums2 = [3, 4]\n *\n * The median is (2 + 3)/2 = 2.5\n *\n */\n\n\npublic class MedianOfTwoSortedArrays4 {\n    public double findMedianSortedArrays(int[] nums1, int[] nums2) {\n        int l1 = 0;\n        int r1 = nums1.length-1;\n        int l2 = 0;\n        int r2 = nums2.length-1;\n        int L = 0;\n        int R = 0;\n\n        while (l1 <= r1 && l2 <= r2) {\n            if (nums1[l1] <= nums2[l2]) {\n                L = nums1[l1];\n                l1++;\n            } else {\n                L = nums2[l2];\n                l2++;\n            }\n\n            if (nums1[r1] <= nums2[r2]) {\n                R = nums2[r2];\n                r2--;\n            } else {\n                R = nums1[r1];\n                r1--;\n            }\n        }\n\n        if (l1 > r1 && l2 > r2) {\n            return (L + R) / 2.0;\n        } else if (l1 > r1) {\n            int mid = (l2 + r2) / 2;\n            if ((l2 + r2)%2 == 0) {\n                return nums2[mid];\n            } else {\n                return (nums2[mid] + nums2[mid+1]) / 2.0;\n            }\n        } else {\n            int mid = (l1 + r1) / 2;\n            if ((l1 + r1)%2 == 0) {\n                return nums1[mid];\n            } else {\n                return (nums1[mid] + nums1[mid+1]) / 2.0;\n            }\n        }\n    }\n\n    /**\n     * https://leetcode.com/articles/median-of-two-sorted-arrays/\n     */\n    public double findMedianSortedArrays2(int[] A, int[] B) {\n        int m = A.length;\n        int n = B.length;\n        if (m > n) { // to ensure m<=n\n            int[] temp = A; A = B; B = temp;\n            int tmp = m; m = n; n = tmp;\n        }\n        int iMin = 0, iMax = m, halfLen = (m + n + 1) / 2;\n        while (iMin <= iMax) {\n            int i = (iMin + iMax) / 2;\n            int j = halfLen - i;\n            if (i < iMax && B[j-1] > A[i]){\n                iMin = iMin + 1; // i is too small\n            }\n            else if (i > iMin && A[i-1] > B[j]) {\n                iMax = iMax - 1; // i is too big\n            }\n            else { // i is perfect\n                int maxLeft = 0;\n                if (i == 0) { maxLeft = B[j-1]; }\n                else if (j == 0) { maxLeft = A[i-1]; }\n                else { maxLeft = Math.max(A[i-1], B[j-1]); }\n                if ( (m + n) % 2 == 1 ) { return maxLeft; }\n\n                int minRight = 0;\n                if (i == m) { minRight = B[j]; }\n                else if (j == n) { minRight = A[i]; }\n                else { minRight = Math.min(B[j], A[i]); }\n\n                return (maxLeft + minRight) / 2.0;\n            }\n        }\n        return 0.0;\n    }\n\n\n}\n"
  },
  {
    "path": "src/MeetingRooms252.java",
    "content": "/**\n * Given an array of meeting time intervals consisting of start and end times\n * [[s1,e1],[s2,e2],...] (si < ei), determine if a person could attend all\n * meetings.\n * \n * Example 1:\n * Input: [[0,30],[5,10],[15,20]]\n * Output: false\n * \n * Example 2:\n * Input: [[7,10],[2,4]]\n * Output: true\n */\n\n/**\n * Definition for an interval.\n * public class Interval {\n *     int start;\n *     int end;\n *     Interval() { start = 0; end = 0; }\n *     Interval(int s, int e) { start = s; end = e; }\n * }\n */\n\npublic class MeetingRooms252 {\n    public boolean canAttendMeetings(Interval[] intervals) {\n        Arrays.sort(intervals, (i1, i2) -> Integer.compare(i1.start, i2.start));\n        for (int i=1; i<intervals.length; i++) {\n            if (intervals[i-1].end > intervals[i].start) return false;\n        }\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/meeting-rooms/discuss/67780/Easy-JAVA-solution-beat-98/148985\n     */\n    public boolean canAttendMeetings2(Interval[] intervals) {\n        int len=intervals.length;\n        if(len==0){\n            return true;\n        }\n        int[]begin=new int[len];\n        int[]stop=new int[len];\n        for(int i=0;i<len;i++){\n            begin[i]=intervals[i].start;\n            stop[i]=intervals[i].end;\n        }\n        Arrays.sort(begin);\n        Arrays.sort(stop);\n        int endT=0;\n        for(int i=1;i<len;i++){\n            if(begin[i]<stop[i-1]){\n                return false;\n            }\n        }\n        return true;\n    }\n\n}\n\n"
  },
  {
    "path": "src/MeetingRoomsII253.java",
    "content": "/**\n * Given an array of meeting time intervals consisting of start and end times\n * [[s1,e1],[s2,e2],...] (si < ei), find the minimum number of conference rooms\n * required.\n *\n * For example,\n * Given [[0, 30],[5, 10],[15, 20]],\n * return 2.\n *\n */\n\n/**\n * Definition for an interval.\n * public class Interval {\n *     int start;\n *     int end;\n *     Interval() { start = 0; end = 0; }\n *     Interval(int s, int e) { start = s; end = e; }\n * }\n */\n\npublic class MeetingRoomsII253 {\n    public int minMeetingRooms(Interval[] intervals) {\n        if (intervals == null || intervals.length == 0) return 0;\n\n        Comparator<Interval> comparator = new Comparator<Interval>() {\n            @Override\n            public int compare(Interval i1, Interval i2) {\n                return Integer.compare(i1.start, i2.start);\n            }\n        };\n\n        Arrays.sort(intervals, comparator);\n\n        Set<List<Interval>> set = new HashSet<>();\n\n        for (Interval i: intervals) {\n            boolean createNewList = true;\n            for (List<Interval> l: set) {\n                Interval ii = l.get(l.size()-1);\n                if (ii.end <= i.start) {\n                    l.add(i);\n                    createNewList = false;\n                    break;\n                }\n            }\n\n            if (createNewList) {\n                List<Interval> newList = new ArrayList<>();\n                newList.add(i);\n                set.add(newList);\n            }\n        }\n\n        return set.size();\n    }\n\n\n    /**\n     * https://leetcode.com/problems/meeting-rooms-ii/discuss/67855/Explanation-of-%22Super-Easy-Java-Solution-Beats-98.8%22-from-@pinkfloyda\n     */\n    public int minMeetingRooms2(Interval[] intervals) {\n        int[] starts = new int[intervals.length];\n        int[] ends = new int[intervals.length];\n        for(int i=0; i<intervals.length; i++) {\n            starts[i] = intervals[i].start;\n            ends[i] = intervals[i].end;\n        }\n        Arrays.sort(starts);\n        Arrays.sort(ends);\n        int rooms = 0;\n        int endsItr = 0;\n        for(int i=0; i<starts.length; i++) {\n            if(starts[i]<ends[endsItr])\n                rooms++;\n            else\n                endsItr++;\n        }\n        return rooms;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/meeting-rooms-ii/discuss/67857/AC-Java-solution-using-min-heap\n     */\n    public int minMeetingRooms3(Interval[] intervals) {\n        if (intervals == null || intervals.length == 0)\n            return 0;\n\n        // Sort the intervals by start time\n        Arrays.sort(intervals, new Comparator<Interval>() {\n            public int compare(Interval a, Interval b) { return a.start - b.start; }\n        });\n\n        // Use a min heap to track the minimum end time of merged intervals\n        PriorityQueue<Interval> heap = new PriorityQueue<Interval>(intervals.length, new Comparator<Interval>() {\n            public int compare(Interval a, Interval b) { return a.end - b.end; }\n        });\n\n        // start with the first meeting, put it to a meeting room\n        heap.offer(intervals[0]);\n\n        for (int i = 1; i < intervals.length; i++) {\n            // get the meeting room that finishes earliest\n            Interval interval = heap.poll();\n\n            if (intervals[i].start >= interval.end) {\n                // if the current meeting starts right after\n                // there's no need for a new room, merge the interval\n                interval.end = intervals[i].end;\n            } else {\n                // otherwise, this meeting needs a new room\n                heap.offer(intervals[i]);\n            }\n\n            // don't forget to put the meeting room back\n            heap.offer(interval);\n        }\n\n        return heap.size();\n    }\n\n}\n"
  },
  {
    "path": "src/MergeIntervals56.java",
    "content": "/**\n * Given a collection of intervals, merge all overlapping intervals.\n *\n * For example,\n * Given [1,3],[2,6],[8,10],[15,18],\n * return [1,6],[8,10],[15,18].\n */\n\n/**\n * Definition for an interval.\n * public class Interval {\n *     int start;\n *     int end;\n *     Interval() { start = 0; end = 0; }\n *     Interval(int s, int e) { start = s; end = e; }\n * }\n */\n\n\npublic class MergeIntervals56 {\n    public List<Interval> merge(List<Interval> intervals) {\n        if (intervals == null || intervals.size() <= 1) return intervals;\n        Collections.sort(intervals, new SortByLeft());\n\n        List<Interval> res = new ArrayList<>();\n        Interval acc = intervals.get(0);\n        int i=1;\n        while (i < intervals.size()) {\n            Interval curr = intervals.get(i);\n            if (curr.start > acc.end) {\n                res.add(acc);\n                acc = curr;\n            } else {\n                acc = new Interval(acc.start, Math.max(acc.end, curr.end));\n            }\n            i++;\n        }\n        res.add(acc);\n        return res;\n    }\n\n    class SortByLeft implements Comparator<Interval> {\n        @Override\n        public int compare(Interval a, Interval b) {\n            return a.start - b.start;\n        }\n    }\n\n\n    public List<Interval> merge2(List<Interval> intervals) {\n        List<Interval> res = new ArrayList<>();\n        int N = intervals.size();\n        if (N == 0) return res;\n        int[] starts = new int[N];\n        int[] ends = new int[N];\n        int i = 0;\n        for (Interval inv: intervals) {\n            starts[i] = inv.start;\n            ends[i] = inv.end;\n            i++;\n        }\n        Arrays.sort(starts);\n        Arrays.sort(ends);\n\n        int s = 0;\n        for (int e=1; e<N; e++) {\n            if (starts[e] > ends[e-1]) {\n                res.add(new Interval(starts[s], ends[e-1]));\n                s = e;\n            }\n        }\n        res.add(new Interval(starts[s], ends[N-1]));\n        return res;\n    }\n\n\n    public List<Interval> merge3(List<Interval> intervals) {\n        Comparator<Interval> comp = (in1, in2) -> Integer.compare(in1.start, in2.start);\n        Collections.sort(intervals, comp);\n\n        List<Interval> res = new ArrayList<>();\n        if (intervals.size() == 0) return res;\n        Interval tmp = intervals.get(0);\n        for (Interval inv: intervals) {\n            if (inv.start <= tmp.end) {\n                tmp.start = Math.min(tmp.start, inv.start);\n                tmp.end = Math.max(tmp.end, inv.end);\n            } else {\n                res.add(tmp);\n                tmp = inv;\n            }\n        }\n        res.add(tmp);\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/MergeKSortedLists23.java",
    "content": "/**\n * Merge k sorted linked lists and return it as one sorted list.\n */\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\n\npublic class MergeKSortedLists23 {\n    /**\n     * https://discuss.leetcode.com/topic/26095/my-simple-java-solution-use-recursion\n     */\n    public static ListNode mergeKLists(ListNode[] lists){\n        return partion(lists,0,lists.length-1);\n    }\n\n    public static ListNode partion(ListNode[] lists,int s,int e){\n        if(s==e)  return lists[s];\n        if(s<e){\n            int q=(s+e)/2;\n            ListNode l1=partion(lists,s,q);\n            ListNode l2=partion(lists,q+1,e);\n            return merge(l1,l2);\n        }else\n            return null;\n    }\n\n    //This function is from Merge Two Sorted Lists.\n    public static ListNode merge(ListNode l1,ListNode l2){\n        if(l1==null) return l2;\n        if(l2==null) return l1;\n        if(l1.val<l2.val){\n            l1.next=merge(l1.next,l2);\n            return l1;\n        }else{\n            l2.next=merge(l1,l2.next);\n            return l2;\n        }\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/2780/a-java-solution-based-on-priority-queue\n     */\n    public ListNode mergeKLists2(ListNode[] lists) {\n        if (lists==null||lists.length==0) return null;\n\n        PriorityQueue<ListNode> queue= new PriorityQueue<ListNode>(lists.length,new Comparator<ListNode>(){\n            @Override\n            public int compare(ListNode o1,ListNode o2){\n                if (o1.val<o2.val)\n                    return -1;\n                else if (o1.val==o2.val)\n                    return 0;\n                else\n                    return 1;\n            }\n        });\n\n        ListNode dummy = new ListNode(0);\n        ListNode tail=dummy;\n\n        for (ListNode node:lists)\n            if (node!=null)\n                queue.add(node);\n\n        while (!queue.isEmpty()){\n            tail.next=queue.poll();\n            tail=tail.next;\n\n            if (tail.next!=null)\n                queue.add(tail.next);\n        }\n        return dummy.next;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/26095/my-simple-java-solution-use-recursion\n     */\n    public ListNode mergeKLists3(ListNode[] lists) {\n        return mL(lists, 0, lists.length - 1);\n    }\n\n    private ListNode mL(ListNode[] lists, int l, int r) {\n        if (r < l) return null;\n        if (r == l) return lists[r];\n\n        int mid = (l + r) / 2;\n        ListNode a = mL(lists, l, mid), b = mL(lists, mid + 1, r);\n        ListNode dmHead = new ListNode(0), cur = dmHead;\n        while (a != null && b != null) {\n            if (a.val < b.val) {\n                cur.next = a;\n                a = a.next;\n            } else {\n                cur.next = b;\n                b = b.next;\n            }\n            cur = cur.next;\n        }\n        cur.next = (a != null) ? a : b;\n\n        return dmHead.next;\n    }\n\n\n    public ListNode mergeKLists4(ListNode[] lists) {\n        if (lists == null || lists.length == 0) return null;\n        ListNode dummy = new ListNode(0);\n        ListNode p = dummy;\n        PriorityQueue<ListNode> q = new PriorityQueue<ListNode>((l1, l2) -> Integer.compare(l1.val, l2.val));\n        for (ListNode node: lists) {\n            if (node != null) q.add(node);\n        }\n        while (!q.isEmpty()) {\n            ListNode curr = q.poll();\n            if (curr.next != null) q.add(curr.next);\n            curr.next = null;\n            p.next = curr;\n            p = p.next;\n        }\n\n        return dummy.next;\n    }\n\n\n    public ListNode mergeKLists5(ListNode[] lists) {\n        if (lists == null || lists.length == 0) return null;\n\n        int len = lists.length;\n        int interval = 1;\n        while (interval < len) {\n            for (int i=0; i < len-interval; i+=interval*2)\n                lists[i] = mergeTwoLists5(lists[i], lists[i + interval]);\n            interval *= 2;\n        }\n\n        return lists[0];\n    }\n\n    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {\n        ListNode dummy = new ListNode(0);\n        ListNode p = dummy;\n        while (l1 != null && l2 != null) {\n            if (l1.val >= l2.val) {\n                p.next = l2;\n                l2 = l2.next;\n            } else {\n                p.next = l1;\n                l1 = l1.next;\n            }\n            p = p.next;\n            p.next = null;\n        }\n        if (l1 != null) p.next = l1;\n        if (l2 != null) p.next = l2;\n        return dummy.next;\n    }\n\n\n    public ListNode mergeKLists6(ListNode[] lists) {\n        if (lists == null || lists.length == 0) return null;\n        return mergeKLists(lists, 0, lists.length-1);\n    }\n\n\n    public ListNode mergeKLists(ListNode[] lists, int i, int j) {\n        if (i == j) return lists[i];\n        else if (j - i == 1) return mergeTwoLists(lists[i], lists[j]);\n        else {\n            int mid = (i + j) / 2;\n            return mergeTwoLists(mergeKLists(lists, i, mid), mergeKLists(lists, mid+1, j));\n        }\n    }\n\n    private ListNode mergeTwoLists(ListNode l1, ListNode l2) {\n        ListNode prehead = new ListNode(-1);\n        ListNode prev = prehead;\n        while (l1 != null && l2 != null) {\n            if (l1.val <= l2.val) {\n                prev.next = l1;\n                l1 = l1.next;\n            } else {\n                prev.next = l2;\n                l2 = l2.next;\n            }\n            prev = prev.next;\n        }\n        prev.next = l1 == null ? l2 : l1;\n        return prehead.next;\n    }\n\n}\n"
  },
  {
    "path": "src/MergeSortedArray88.java",
    "content": "/**\n * Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as\n * one sorted array.\n *\n * Note:\n * You may assume that nums1 has enough space (size that is greater or equal to\n * m + n) to hold additional elements from nums2. The number of elements\n * initialized in nums1 and nums2 are m and n respectively.\n *\n */\n\n\npublic class MergeSortedArray88 {\n    public void merge(int[] nums1, int m, int[] nums2, int n) {\n        if (n == 0) return;\n\n        int i = m-1;\n        int j = n-1;\n\n        while (i >= 0 && j >= 0) {\n            if (nums1[i] >= nums2[j]) {\n                nums1[i+j+1] = nums1[i];\n                i--;\n            } else {\n                nums1[i+j+1] = nums2[j];\n                j--;\n            }\n        }\n\n        while (j >= 0) {\n            nums1[j] = nums2[j];\n            j--;\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/merge-sorted-array/discuss/29505/1-Line-Solution\n     */\n    public void merge2(int[] nums1, int m, int[] nums2, int n) {\n        while (n > 0) nums1[m+n-1] = (m == 0 || nums2[n-1] > nums1[m-1]) ? nums2[--n] : nums1[--m];\n    }\n\n}\n"
  },
  {
    "path": "src/MergeTwoSortedLists21.java",
    "content": "/**\n * Merge two sorted linked lists and return it as a new list. The new list\n * should be made by splicing together the nodes of the first two lists.\n *\n * Example:\n *\n * Input: 1->2->4, 1->3->4\n * Output: 1->1->2->3->4->4\n *\n */\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\npublic class MergeTwoSortedLists21 {\n    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {\n        ListNode dummy = new ListNode(0);\n        ListNode p = dummy;\n        while (l1 != null && l2 != null) {\n            if (l1.val >= l2.val) {\n                p.next = l2;\n                l2 = l2.next;\n            } else {\n                p.next = l1;\n                l1 = l1.next;\n            }\n            p = p.next;\n            p.next = null;\n        }\n        if (l1 != null) p.next = l1;\n        if (l2 != null) p.next = l2;\n        return dummy.next;\n    }\n\n    public ListNode mergeTwoLists2(ListNode l1, ListNode l2) {\n        if (l1 == null) return l2;\n        if (l2 == null) return l1;\n\n        if (l1.val >= l2.val) {\n            l2.next = mergeTwoLists2(l1, l2.next);\n            return l2;\n        } else {\n            l1.next = mergeTwoLists2(l1.next, l2);\n            return l1;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/MiddleOfTheLinkedList876.java",
    "content": "/**\n * Given a non-empty, singly linked list with head node head, return a middle\n * node of linked list.\n * \n * If there are two middle nodes, return the second middle node.\n * \n * Example 1:\n * \n * Input: [1,2,3,4,5]\n * Output: Node 3 from this list (Serialization: [3,4,5])\n * The returned node has value 3.  (The judge's serialization of this node is [3,4,5]).\n * Note that we returned a ListNode object ans, such that:\n * ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, and ans.next.next.next = NULL.\n * \n * Example 2:\n * \n * Input: [1,2,3,4,5,6]\n * Output: Node 4 from this list (Serialization: [4,5,6])\n * Since the list has two middle nodes with values 3 and 4, we return the second one.\n * \n * Note:\n * The number of nodes in the given list will be between 1 and 100.\n */\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\npublic class MiddleOfTheLinkedList876 {\n    public ListNode middleNode(ListNode head) {\n        ListNode slow = head;\n        ListNode fast = head;\n        \n        while (fast != null && fast.next != null) {\n            slow = slow.next;\n            fast = fast.next.next;\n        }\n        \n        return slow;\n    }\n\n}\n"
  },
  {
    "path": "src/MinCostClimbingStairs746.java",
    "content": "/**\n * On a staircase, the i-th step has some non-negative cost cost[i] assigned\n * (0 indexed).\n *\n * Once you pay the cost, you can either climb one or two steps. You need to\n * find minimum cost to reach the top of the floor, and you can either start\n * from the step with index 0, or the step with index 1.\n *\n * Example 1:\n * Input: cost = [10, 15, 20]\n * Output: 15\n * Explanation: Cheapest is start on cost[1], pay that cost and go to the top.\n *\n * Example 2:\n * Input: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]\n * Output: 6\n * Explanation: Cheapest is start on cost[0], and only step on 1s, skipping cost[3].\n *\n * Note:\n * cost will have a length in the range [2, 1000].\n * Every cost[i] will be an integer in the range [0, 999].\n */\n\npublic class MinCostClimbingStairs746 {\n    public int minCostClimbingStairs(int[] cost) {\n        int cost0 = 0;\n        int cost1 = 0;\n        for (int i=0; i<=cost.length; i++) {\n            int newCost = Math.min(cost0, cost1) + ((i == cost.length) ? 0 : cost[i]);\n            cost0 = cost1;\n            cost1 = newCost;\n        }\n        return cost1;\n    }\n\n    /**\n     * https://leetcode.com/problems/min-cost-climbing-stairs/solution/\n     */\n    public int minCostClimbingStairs2(int[] cost) {\n        int f1 = 0, f2 = 0;\n        for (int i = cost.length - 1; i >= 0; --i) {\n            int f0 = cost[i] + Math.min(f1, f2);\n            f2 = f1;\n            f1 = f0;\n        }\n        return Math.min(f1, f2);\n    }\n\n}\n"
  },
  {
    "path": "src/MinStack.java",
    "content": "/**\n * Design a stack that supports push, pop, top, and retrieving the minimum\n * element in constant time.\n *\n * push(x) -- Push element x onto stack.\n * pop() -- Removes the element on top of the stack.\n * top() -- Get the top element.\n * getMin() -- Retrieve the minimum element in the stack.\n *\n * Example:\n * MinStack minStack = new MinStack();\n * minStack.push(-2);\n * minStack.push(0);\n * minStack.push(-3);\n * minStack.getMin();   --> Returns -3.\n * minStack.pop();\n * minStack.top();      --> Returns 0.\n * minStack.getMin();   --> Returns -2.\n *\n */\n\n\nimport java.util.SortedMap;\nimport java.util.TreeMap;\n\n\nclass MinStack {\n    SortedMap<Integer, Integer> map = new TreeMap<>();;\n    Stack<Integer> st = new Stack<>();\n\n    /** initialize your data structure here. */\n    public MinStack() { }\n\n    public void push(int x) {\n        if (map.containsKey(x)) {\n            map.put(x, map.get(x)+1);\n        } else {\n            map.put(x, 1);\n        }\n\n        st.push(x);\n    }\n\n    public void pop() {\n        Integer topEle = st.peek();\n        int count = map.get(topEle);\n        count--;\n        if (count <= 0) {\n            map.remove(topEle);\n        } else {\n            map.put(topEle, count);\n        }\n\n        st.pop();\n    }\n\n    public int top() {\n        return st.peek();\n    }\n\n    public int getMin() {\n        return map.firstKey();\n    }\n}\n\n\n/**\n * https://discuss.leetcode.com/topic/4953/share-my-java-solution-with-only-one-stack\n */\nclass MinStack2 {\n    static class Element\n    {\n        final int value;\n        final int min;\n        Element(final int value, final int min)\n        {\n            this.value = value;\n            this.min = min;\n        }\n    }\n    final Stack<Element> stack = new Stack<>();\n\n    public void push(int x) {\n        final int min = (stack.empty()) ? x : Math.min(stack.peek().min, x);\n        stack.push(new Element(x, min));\n    }\n\n    public void pop()\n    {\n        stack.pop();\n    }\n\n    public int top()\n    {\n        return stack.peek().value;\n    }\n\n    public int getMin()\n    {\n        return stack.peek().min;\n    }\n}\n\n\n/**\n * https://discuss.leetcode.com/topic/4953/share-my-java-solution-with-only-one-stack\n */\nclass MinStack3 {\n    long min;\n    Stack<Long> stack;\n\n    public MinStack(){\n        stack=new Stack<>();\n    }\n\n    public void push(int x) {\n        if (stack.isEmpty()){\n            stack.push(0L);\n            min=x;\n        }else{\n            stack.push(x-min);//Could be negative if min value needs to change\n            if (x<min) min=x;\n        }\n    }\n\n    public void pop() {\n        if (stack.isEmpty()) return;\n\n        long pop=stack.pop();\n\n        if (pop<0)  min=min-pop;//If negative, increase the min value\n\n    }\n\n    public int top() {\n        long top=stack.peek();\n        if (top>0){\n            return (int)(top+min);\n        }else{\n           return (int)(min);\n        }\n    }\n\n    public int getMin() {\n        return (int)min;\n    }\n}\n\n\n/**\n * Your MinStack object will be instantiated and called as such:\n * MinStack obj = new MinStack();\n * obj.push(x);\n * obj.pop();\n * int param_3 = obj.top();\n * int param_4 = obj.getMin();\n */\n"
  },
  {
    "path": "src/Minesweeper529.java",
    "content": "/**\n * Let's play the minesweeper game (Wikipedia, online game)!\n * \n * You are given a 2D char matrix representing the game board. 'M' represents\n * an unrevealed mine, 'E' represents an unrevealed empty square, 'B'\n * represents a revealed blank square that has no adjacent (above, below, left,\n * right, and all 4 diagonals) mines, digit ('1' to '8') represents how many\n * mines are adjacent to this revealed square, and finally 'X' represents a\n * revealed mine.\n * \n * Now given the next click position (row and column indices) among all the\n * unrevealed squares ('M' or 'E'), return the board after revealing this\n * position according to the following rules:\n * \n * If a mine ('M') is revealed, then the game is over - change it to 'X'.\n * If an empty square ('E') with no adjacent mines is revealed, then change it\n * to revealed blank ('B') and all of its adjacent unrevealed squares should be\n * revealed recursively.\n * If an empty square ('E') with at least one adjacent mine is revealed, then\n * change it to a digit ('1' to '8') representing the number of adjacent mines.\n * Return the board when no more squares will be revealed.\n * \n * Example 1:\n * Input: \n * \n * [['E', 'E', 'E', 'E', 'E'],\n *  ['E', 'E', 'M', 'E', 'E'],\n *  ['E', 'E', 'E', 'E', 'E'],\n *  ['E', 'E', 'E', 'E', 'E']]\n * \n * lick : [3,0]\n * \n * Output: \n * \n * [['B', '1', 'E', '1', 'B'],\n *  ['B', '1', 'M', '1', 'B'],\n *  ['B', '1', '1', '1', 'B'],\n *  ['B', 'B', 'B', 'B', 'B']]\n * \n * Explanation:\n * https://leetcode.com/static/images/problemset/minesweeper_example_1.png\n * \n * Example 2:\n * Input: \n * \n * [['B', '1', 'E', '1', 'B'],\n *  ['B', '1', 'M', '1', 'B'],\n *  ['B', '1', '1', '1', 'B'],\n *  ['B', 'B', 'B', 'B', 'B']]\n * \n * Click : [1,2]\n * \n * Output: \n\n * [['B', '1', 'E', '1', 'B'],\n *  ['B', '1', 'X', '1', 'B'],\n *  ['B', '1', '1', '1', 'B'],\n *  ['B', 'B', 'B', 'B', 'B']]\n * \n * Explanation:\n * https://leetcode.com/static/images/problemset/minesweeper_example_2.png\n * \n * Note:\n * he range of the input matrix's height and width is [1,50].\n * The click position will only be an unrevealed square ('M' or 'E'), which\n * also means the input board contains at least one clickable square.\n * The input board won't be a stage when game is over (some mines have\n * been revealed).\n * For simplicity, not mentioned rules should be ignored in this problem.\n * For example, you don't need to reveal all the unrevealed mines when the game\n * is over, consider any cases that you will win the game or flag any squares.\n */\n\npublic class Minesweeper529 {\n    private int[][] directions = new int[][]{{-1, -1}, {-1, 0}, {-1, 1}, {1, 1}, {1, 0}, {1, -1}, {0, 1}, {0, -1}};\n\n    public char[][] updateBoard(char[][] board, int[] click) {\n        if (board == null || board.length == 0|| board[0].length == 0) return board;\n        int M = board.length;\n        int N = board[0].length;\n        helper(board, click[0], click[1], M, N);\n        return board;\n    }\n\n    public void helper(char[][] board, int i, int j, int M, int N) {\n        if (i < 0 || i >= M || j < 0 || j >= N || board[i][j] == 'B' || isDigit(board[i][j]) || board[i][j] == 'X') return;\n        if (board[i][j] == 'M') {\n            board[i][j] = 'X';\n            return;\n        }\n\n        // board[i][j] == 'E'\n        int numMines = numAdjacentMines(board, i, j, M, N);\n        if (numMines == 0) {\n            board[i][j] = 'B';\n            for (int[] d: directions) {\n                helper(board, i + d[0], j + d[1], M, N);\n            }\n        } else {\n            board[i][j] = Character.forDigit(numMines, 10);\n        }\n    }\n\n    private boolean isDigit(char c) {\n        return c >= '1' && c <= '8';\n    }\n\n    private int numAdjacentMines(char[][] board, int i, int j, int M, int N) {\n        int numMines = 0;\n        for (int[] d: directions) {\n            int ii = i + d[0];\n            int jj = j + d[1];\n            if (ii < 0 || ii >= M || jj < 0 || jj >= N) continue;\n            if (board[ii][jj] == 'M' || board[ii][jj] == 'X') numMines++;\n        }\n        return numMines;\n    }\n\n\n}\n"
  },
  {
    "path": "src/MinimumASCIIDeleteSumForTwoStrings712.java",
    "content": "/**\n * Given two strings s1, s2, find the lowest ASCII sum of deleted characters to\n * make two strings equal.\n * \n * Example 1:\n * Input: s1 = \"sea\", s2 = \"eat\"\n * Output: 231\n * Explanation: Deleting \"s\" from \"sea\" adds the ASCII value of \"s\" (115) to the sum.\n * Deleting \"t\" from \"eat\" adds 116 to the sum.\n * At the end, both strings are equal, and 115 + 116 = 231 is the minimum sum possible to achieve this.\n * \n * Example 2:\n * Input: s1 = \"delete\", s2 = \"leet\"\n * Output: 403\n * Explanation: Deleting \"dee\" from \"delete\" to turn the string into \"let\",\n * adds 100[d]+101[e]+101[e] to the sum.  Deleting \"e\" from \"leet\" adds 101[e] to the sum.\n * At the end, both strings are equal to \"let\", and the answer is 100+101+101+101 = 403.\n * If instead we turned both strings into \"lee\" or \"eet\", we would get answers of 433 or 417, which are higher.\n * \n * Note:\n * 0 < s1.length, s2.length <= 1000.\n * All elements of each string will have an ASCII value in [97, 122].\n */\n\npublic class MinimumASCIIDeleteSumForTwoStrings712 {\n    public int minimumDeleteSum(String s1, String s2) {\n        if (s1.equals(s2)) return 0;\n        int len1 = s1.length();\n        int len2 = s2.length();\n        int[][] dp = new int[len1 + 1][len2 + 1];\n        for (int i=1; i<=len1; i++) dp[i][0] = (int) s1.charAt(i-1) + dp[i-1][0];\n        for (int j=1; j<=len2; j++) dp[0][j] = (int) s2.charAt(j-1) + dp[0][j-1];\n        for (int i=1; i<=len1; i++) {\n            for (int j=1; j<=len2; j++) {\n                if (s1.charAt(i-1) == s2.charAt(j-1)) {\n                    dp[i][j] = dp[i-1][j-1];\n                } else {\n                    int noI = (int) s1.charAt(i-1) + dp[i-1][j];\n                    int noJ = (int) s2.charAt(j-1) + dp[i][j-1];\n                    dp[i][j] = Math.min(noI, noJ);\n                }\n            }\n        }\n        return dp[len1][len2];\n    }\n\n}\n"
  },
  {
    "path": "src/MinimumAbsoluteDifferenceInBST530.java",
    "content": "/**\n * Given a binary search tree with non-negative values, find the minimum\n * absolute difference between values of any two nodes.\n * \n * Example:\n * \n * Input:\n * \n *    1\n *     \\\n *      3\n *     /\n *    2\n * \n * Output:\n * 1\n * \n * Explanation:\n * The minimum absolute difference is 1, which is the difference between 2\n * and 1 (or between 2 and 3).\n * \n * Note: There are at least two nodes in this BST.\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class MinimumAbsoluteDifferenceInBST530 {\n    public int getMinimumDifference(TreeNode root) {\n        int[] res = new int[]{Integer.MAX_VALUE};\n        helper(root, res);\n        return res[0];\n    }\n\n    public int[] helper(TreeNode root, int[] res) {\n        int[] bound = new int[]{root.val, root.val};\n        if (root.left == null && root.right == null) return bound;\n        if (root.left != null) {\n            int[] leftRes = helper(root.left, res);\n            bound[0] = Math.min(bound[0], leftRes[0]);\n            bound[1] = Math.max(bound[1], leftRes[1]);\n            res[0] = Math.min(res[0], Math.abs(leftRes[1] - root.val));\n        }\n        if (root.right != null) {\n            int[] rightRes = helper(root.right, res);\n            bound[0] = Math.min(bound[0], rightRes[0]);\n            bound[1] = Math.max(bound[1], rightRes[1]);\n            res[0] = Math.min(res[0], Math.abs(rightRes[0] - root.val));\n        }\n        return bound;\n    }\n\n}\n"
  },
  {
    "path": "src/MinimumDepthOfBinaryTree111.java",
    "content": "/**\n * Given a binary tree, find its minimum depth.\n * \n * The minimum depth is the number of nodes along the shortest path from the\n * root node down to the nearest leaf node.\n * \n * Note: A leaf is a node with no children.\n * \n * Example:\n * \n * Given binary tree [3,9,20,null,null,15,7],\n * \n *     3\n *    / \\\n *   9  20\n *     /  \\\n *    15   7\n * return its minimum depth = 2.\n * \n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class MinimumDepthOfBinaryTree111 {\n    public int minDepth(TreeNode root) {\n        if (root == null) return 0;\n        Queue<TreeNode> q = new LinkedList<>();\n        int depth = 1;\n        q.add(root);\n        while (!q.isEmpty()) {\n            int size = q.size();\n            for (int i=0; i<size; i++) {\n                TreeNode node = q.remove();\n                boolean isLeaf = true;\n                if (node.left != null) {\n                    isLeaf = false;\n                    q.add(node.left);\n                }\n                if (node.right != null) {\n                    isLeaf = false;\n                    q.add(node.right);\n                }\n                if (isLeaf) return depth;\n            }\n            depth++;\n        }\n        return depth;\n    }\n    \n}\n"
  },
  {
    "path": "src/MinimumDistanceBetweenBSTNodes783.java",
    "content": "/**\n * Given a Binary Search Tree (BST) with the root node root, return the minimum\n * difference between the values of any two different nodes in the tree.\n * \n * Example :\n * \n * Input: root = [4,2,6,1,3,null,null]\n * Output: 1\n * Explanation:\n * Note that root is a TreeNode object, not an array.\n * \n * The given tree [4,2,6,1,3,null,null] is represented by the following diagram:\n * \n *           4\n *         /   \\\n *       2      6\n *      / \\    \n *     1   3  \n * \n * while the minimum difference in this tree is 1, it occurs between node 1 and\n * node 2, also between node 3 and node 2.\n * \n * Note:\n * The size of the BST will be between 2 and 100.\n * The BST is always valid, each node's value is an integer, and each node's\n * value is different.\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class MinimumDistanceBetweenBSTNodes783 {\n    public int minDiffInBST(TreeNode root) {        \n        int[] res = new int[]{Integer.MAX_VALUE};\n        minDiffInBST(root, new LinkedList<>(), res);\n        return res[0];\n    }\n\n    public void minDiffInBST(TreeNode root, LinkedList<Integer> list, int[] res) {\n        if (root.left != null) minDiffInBST(root.left, list, res);\n        if (!list.isEmpty() && root.val - list.getLast() < res[0]) {\n            res[0] = root.val - list.getLast();\n        }\n        list.add(root.val);\n        if (root.right != null) minDiffInBST(root.right, list, res);\n    }\n\n\n    public int minDiffInBST2(TreeNode root) {        \n        int[] res = new int[]{Integer.MAX_VALUE};\n        Integer[] pre = new Integer[]{null};\n        minDiffInBST2(root, new LinkedList<>(), pre, res);\n        return res[0];\n    }\n\n    public void minDiffInBST2(TreeNode root, LinkedList<Integer> list, Integer[] pre, int[] res) {\n        if (root.left != null) minDiffInBST2(root.left, list, pre, res);\n        if (pre[0] != null && root.val - pre[0] < res[0]) {\n            res[0] = root.val - pre[0];\n        }\n        pre[0] = root.val;\n        if (root.right != null) minDiffInBST2(root.right, list, pre, res);\n    }\n\n}\n"
  },
  {
    "path": "src/MinimumGeneticMutation433.java",
    "content": "/**\n * A gene string can be represented by an 8-character long string,\n * with choices from \"A\", \"C\", \"G\", \"T\".\n *\n * Suppose we need to investigate about a mutation (mutation from \"start\" to \"end\"),\n * where ONE mutation is defined as ONE single character changed in the gene string.\n *\n * For example, \"AACCGGTT\" -> \"AACCGGTA\" is 1 mutation.\n *\n * Also, there is a given gene \"bank\", which records all the valid gene mutations.\n * A gene must be in the bank to make it a valid gene string.\n *\n * Now, given 3 things - start, end, bank, your task is to determine what is the\n * minimum number of mutations needed to mutate from \"start\" to \"end\". If there\n * is no such a mutation, return -1.\n *\n * Note:\n *\n * Starting point is assumed to be valid, so it might not be included in the bank.\n * If multiple mutations are needed, all mutations during in the sequence must be valid.\n * You may assume start and end string is not the same.\n *\n * Example 1:\n *\n * start: \"AACCGGTT\"\n * end:   \"AACCGGTA\"\n * bank: [\"AACCGGTA\"]\n *\n * return: 1\n *\n * Example 2:\n *\n * start: \"AACCGGTT\"\n * end:   \"AAACGGTA\"\n * bank: [\"AACCGGTA\", \"AACCGCTA\", \"AAACGGTA\"]\n *\n * return: 2\n *\n * Example 3:\n *\n * start: \"AAAAACCC\"\n * end:   \"AACCCCCC\"\n * bank: [\"AAAACCCC\", \"AAACCCCC\", \"AACCCCCC\"]\n *\n * return: 3\n */\n\n\npublic class MinimumGeneticMutation433 {\n    public int minMutation(String start, String end, String[] bank) {\n        int len = bank.length;\n        boolean[] marked = new boolean[len];\n        Integer res = helper(start, end, bank, len, marked, 0, Integer.MAX_VALUE);\n        return res.equals(Integer.MAX_VALUE) ? -1 : res;\n    }\n\n    private int helper(String start, String end, String[] bank, int len, boolean[] marked, int step, Integer res) {\n        for (Integer i=0; i<len; i++) {\n            if (!marked[i] && diff(start, bank[i]) == 1) {\n                if (bank[i].equals(end)) {\n                    return Math.min(res, step+1);\n                }\n                marked[i] = true;\n                int found = helper(bank[i], end, bank, len, marked, step+1, res);\n                res = Math.min(res, found);\n                marked[i] = false;\n            }\n        }\n\n        return res;\n    }\n\n    private Integer diff(String a, String b) {\n        int d = 0;\n        for (int i=0; i<8; i++) {\n            if (a.charAt(i) != b.charAt(i)) d++;\n        }\n        return d;\n    }\n\n}\n"
  },
  {
    "path": "src/MinimumHeightTrees310.java",
    "content": "/**\n * For a undirected graph with tree characteristics, we can choose any node as\n * the root. The result graph is then a rooted tree. Among all possible rooted\n * trees, those with minimum height are called minimum height trees (MHTs).\n * Given such a graph, write a function to find all the MHTs and return a list\n * of their root labels.\n *\n * Format\n * The graph contains n nodes which are labeled from 0 to n - 1. You will be\n * given the number n and a list of undirected edges (each edge is a pair of\n * labels).\n *\n * You can assume that no duplicate edges will appear in edges. Since all edges\n * are undirected, [0, 1] is the same as [1, 0] and thus will not appear\n * together in edges.\n *\n * Example 1:\n *\n * Given n = 4, edges = [[1, 0], [1, 2], [1, 3]]\n *\n *         0\n *         |\n *         1\n *        / \\\n *       2   3\n * return [1]\n *\n * Example 2:\n *\n * Given n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]\n *\n *      0  1  2\n *       \\ | /\n *         3\n *         |\n *         4\n *         |\n *         5\n * return [3, 4]\n *\n * Note:\n *\n * (1) According to the definition of tree on Wikipedia: “a tree is an\n * undirected graph in which any two vertices are connected by exactly one path.\n * In other words, any connected graph without simple cycles is a tree.”\n *\n * (2) The height of a rooted tree is the number of edges on the longest\n * downward path between the root and a leaf.\n *\n */\n\npublic class MinimumHeightTrees310 {\n    public List<Integer> findMinHeightTrees(int n, int[][] edges) {\n        Map<Integer, Map<Integer, Integer>> map = new HashMap<>();\n        for (int i=0; i<n; i++) {\n            map.put(i, new HashMap<>());\n        }\n\n        for (int[] e: edges) {\n            map.get(e[0]).put(e[1], -1);\n            map.get(e[1]).put(e[0], -1);\n        }\n\n        List<Integer> res = new ArrayList<>();\n        int minH = Integer.MAX_VALUE;\n        for (int p=0; p<n; p++) {\n            boolean[] marked = new boolean[n];\n            marked[p] = true;\n            int newHeight = search(p, 0, map, marked);\n            marked[p] = false;\n            if (newHeight < minH) {\n                res = new ArrayList<>();\n                res.add(p);\n                minH = newHeight;\n            } else if (newHeight == minH) {\n                res.add(p);\n            }\n        }\n\n        return res;\n\n    }\n\n    private int search(Integer p, Integer h, Map<Integer, Map<Integer, Integer>> map, boolean[] marked) {\n        Map<Integer, Integer> connects = map.get(p);\n        int max = 0;\n        for (Map.Entry<Integer, Integer> c: connects.entrySet()) {\n            if (marked[c.getKey()]) {\n                max = Math.max(max, h);\n                continue;\n            }\n            if (c.getValue() != -1) {\n                max = Math.max(max, c.getValue());\n                continue;\n            }\n            marked[c.getKey()] = true;\n            int cValue = search(c.getKey(), h, map, marked);\n            marked[c.getKey()] = false;\n            c.setValue(cValue);\n            max = Math.max(max, cValue);\n        }\n\n        return max+1;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/30572/share-some-thoughts\n     */\n    public List<Integer> findMinHeightTrees2(int n, int[][] edges) {\n        if (n == 1) return Collections.singletonList(0);\n\n        List<Set<Integer>> adj = new ArrayList<>(n);\n        for (int i = 0; i < n; ++i) adj.add(new HashSet<>());\n        for (int[] edge : edges) {\n            adj.get(edge[0]).add(edge[1]);\n            adj.get(edge[1]).add(edge[0]);\n        }\n\n        List<Integer> leaves = new ArrayList<>();\n        for (int i = 0; i < n; ++i)\n            if (adj.get(i).size() == 1) leaves.add(i);\n\n        while (n > 2) {\n            n -= leaves.size();\n            List<Integer> newLeaves = new ArrayList<>();\n            for (int i : leaves) {\n                int j = adj.get(i).iterator().next();\n                adj.get(j).remove(i);\n                if (adj.get(j).size() == 1) newLeaves.add(j);\n            }\n            leaves = newLeaves;\n        }\n        return leaves;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/30956/two-o-n-solutions\n     */\n    int n;\n    List<Integer>[] e;\n\n    private void bfs(int start, int[] dist, int[] pre) {\n        boolean[] visited = new boolean[n];\n        Queue<Integer> queue = new ArrayDeque<>();\n        queue.add(start);\n        dist[start] = 0;\n        visited[start] = true;\n        pre[start] = -1;\n        while (!queue.isEmpty()) {\n            int u = queue.poll();\n            for (int v : e[u])\n                if (!visited[v]) {\n                    visited[v] = true;\n                    dist[v] = dist[u] + 1;\n                    queue.add(v);\n                    pre[v] = u;\n                }\n        }\n    }\n\n    public List<Integer> findMinHeightTree3(int n, int[][] edges) {\n        if (n <= 0) return new ArrayList<>();\n        this.n = n;\n        e = new List[n];\n        for (int i = 0; i < n; i++)\n            e[i] = new ArrayList<>();\n        for (int[] pair : edges) {\n            int u = pair[0];\n            int v = pair[1];\n            e[u].add(v);\n            e[v].add(u);\n        }\n\n        int[] d1 = new int[n];\n        int[] d2 = new int[n];\n        int[] pre = new int[n];\n        bfs(0, d1, pre);\n        int u = 0;\n        for (int i = 0; i < n; i++)\n            if (d1[i] > d1[u]) u = i;\n\n        bfs(u, d2, pre);\n        int v = 0;\n        for (int i = 0; i < n; i++)\n            if (d2[i] > d2[v]) v = i;\n\n        List<Integer> list = new ArrayList<>();\n        while (v != -1) {\n            list.add(v);\n            v = pre[v];\n        }\n\n        if (list.size() % 2 == 1) return Arrays.asList(list.get(list.size() / 2));\n        else return Arrays.asList(list.get(list.size() / 2 - 1), list.get(list.size() / 2));\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/30956/two-o-n-solutions\n     */\n    int n;\n    List<Integer>[] e;\n    int[] height1;\n    int[] height2;\n    int[] dp;\n\n    private void dfs4(int u, int parent) {\n        height1[u] = height2[u] = -Integer.MIN_VALUE / 10;\n        for (int v : e[u])\n            if (v != parent) {\n                dfs4(v, u);\n                int tmp = height1[v] + 1;\n                if (tmp > height1[u]) {\n                    height2[u] = height1[u];\n                    height1[u] = tmp;\n                } else if (tmp > height2[u]) {\n                    height2[u] = tmp;\n                }\n            }\n        height1[u] = Math.max(height1[u], 0); // in case u is a leaf.\n    }\n\n    private void dfs4(int u, int parent, int acc) {\n        dp[u] = Math.max(height1[u], acc);\n        for (int v : e[u])\n            if (v != parent) {\n                int newAcc = Math.max(acc + 1, (height1[v] + 1 == height1[u] ? height2[u] : height1[u]) + 1);\n                dfs4(v, u, newAcc);\n            }\n    }\n\n    public List<Integer> findMinHeightTrees4(int n, int[][] edges) {\n        if (n <= 0) return new ArrayList<>();\n        if (n == 1) return Arrays.asList(0);\n\n        this.n = n;\n        e = new List[n];\n        for (int i = 0; i < n; i++)\n            e[i] = new ArrayList<>();\n        for (int[] pair : edges) {\n            int u = pair[0];\n            int v = pair[1];\n            e[u].add(v);\n            e[v].add(u);\n        }\n\n        height1 = new int[n];\n        height2 = new int[n];\n        dp = new int[n];\n\n        dfs4(0, -1);\n        dfs4(0, -1, 0);\n\n        int min = dp[0];\n        for (int i : dp)\n            if (i < min) min = i;\n\n        List<Integer> ans = new ArrayList<>();\n        for (int i = 0; i < n; i++)\n            if (dp[i] == min) ans.add(i);\n        return ans;\n    }\n\n\n}\n"
  },
  {
    "path": "src/MinimumMovesToEqualArrayElementsII462.java",
    "content": "/**\n * Given a non-empty integer array, find the minimum number of moves required\n * to make all array elements equal, where a move is incrementing a selected\n * element by 1 or decrementing a selected element by 1.\n * \n * You may assume the array's length is at most 10,000.\n * \n * Example:\n * \n * Input:\n * [1,2,3]\n * \n * Output:\n * 2\n * \n * Explanation:\n * Only two moves are needed (remember each move increments or decrements one element):\n * \n * [1,2,3]  =>  [2,2,3]  =>  [2,2,2]\n */\n\npublic class MinimumMovesToEqualArrayElementsII462 {\n    public int minMoves2(int[] nums) {\n        Arrays.sort(nums);\n        int m = 0;\n        int midIndex = nums.length / 2;\n        if (nums.length % 2 == 1) {\n            m = nums[midIndex];\n        } else {\n            m = (nums[midIndex - 1] + nums[midIndex]) /2;\n        }\n        \n        int res = 0;\n        for (int n: nums) {\n            res += Math.abs(n - m);\n        }\n        return res;\n    }\n}\n"
  },
  {
    "path": "src/MinimumPathSum64.java",
    "content": "/**\n * Given a m x n grid filled with non-negative numbers, find a path from top\n * left to bottom right which minimizes the sum of all numbers along its path.\n *\n * Note: You can only move either down or right at any point in time.\n */\n\n\npublic class MinimumPathSum64 {\n    public int minPathSum(int[][] grid) {\n        int m = grid.length;\n        int n = grid[0].length;\n        int[][] dp = new int[m][n];\n\n        for (int i = 0; i < m; i++)\n            for (int j = 0; j < n; j++)\n                dp[i][j] = Integer.MAX_VALUE;\n\n        dp[0][0] = grid[0][0];\n        for (int i = 1; i < m; i++)\n            dp[i][0] = grid[i][0] + dp[i - 1][0];\n        for (int i = 1; i < n; i++)\n            dp[0][i] = grid[0][i] + dp[0][i - 1];\n\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < n; j++) {\n                dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1]) + grid[i][j];\n            }\n        }\n\n        return dp[m-1][n-1];\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/22732/my-solution-beats-100-java-solutions\n     */\n    public int minPathSum1(int[][] grid) {\n        if(grid.length == 0)  return 0;\n\n        int r = grid.length;\n        int c = grid[0].length;\n\n        for(int i=0;i<r; i++) {\n            for(int j=0; j<c; j++) {\n                int leftSum = (j>0) ? grid[i][j-1] : Integer.MAX_VALUE;\n                int topSum = (i>0) ? grid[i-1][j] : Integer.MAX_VALUE;\n                if(i==0 && j==0) continue;\n\n                grid[i][j] += Math.min(leftSum, topSum);\n            }\n        }\n        return grid[r-1][c-1];\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/38213/my-java-solution-using-dp-with-memorization-beats-about-98-submissions\n     */\n    public int minPathSum2(int[][] grid) {\n        int[][] memo = new int[grid.length][grid[0].length];\n        return minPathSumHelper(grid, 0, 0, memo);\n    }\n\n    public int minPathSumHelper(int[][] grid, int row, int col, int[][] memo) {\n        if(row == grid.length-1 && col == grid[0].length-1) return grid[row][col];\n        if(memo[row][col] != 0) return memo[row][col];\n\n        int rowInc = Integer.MAX_VALUE, colInc = Integer.MAX_VALUE;\n        if(row < grid.length-1) rowInc = minPathSumHelper(grid, row+1, col, memo);\n        if(col < grid[0].length-1) colInc = minPathSumHelper(grid, row, col+1, memo);\n        memo[row][col] = Math.min(rowInc, colInc) + grid[row][col];\n        return memo[row][col];\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/85826/java-solution-1ms-recursive-and-4ms-iterative\n     */\n    public int minPathSum3(int[][] grid) {\n        int[][] dp = new int[grid.length][grid[0].length];\n        return minPathSum(grid, 0, 0, dp);\n    }\n\n    public int minPathSum(int[][] grid, int i, int j, int[][] dp) {\n        if (i == grid.length || j == grid[0].length) {\n            return Integer.MAX_VALUE;\n        }\n        if (i == grid.length - 1 && j == grid[0].length - 1) {\n            return grid[i][j];\n        }\n        if (dp[i][j] != 0) {\n            return dp[i][j];\n        }\n\n        int min = grid[i][j];\n        min += Math.min(minPathSum(grid, i, j + 1, dp), minPathSum(grid, i + 1, j, dp));\n        dp[i][j] = min;\n        return min;\n    }\n\n\n    public int minPathSum4(int[][] grid) {\n        int M = grid.length;\n        if (M == 0) return 0;\n        int N = grid[0].length;\n        if (N == 0) return 0; \n        for (int j=1; j<N; j++) grid[0][j] += grid[0][j-1];\n        for (int i=1; i<M; i++) grid[i][0] += grid[i-1][0];\n        for (int i=1; i<M; i++) {\n            for (int j=1; j<N; j++) {\n                grid[i][j] += Math.min(grid[i-1][j], grid[i][j-1]);\n            }\n        }\n        return grid[M-1][N-1];\n    }\n\n}\n"
  },
  {
    "path": "src/MinimumSizeSubarraySum209.java",
    "content": "/**\n * Given an array of n positive integers and a positive integer s, find the\n * minimal length of a contiguous subarray of which the sum ≥ s. If there isn't\n * one, return 0 instead.\n *\n * For example, given the array [2,3,1,2,4,3] and s = 7,\n * the subarray [4,3] has the minimal length under the problem constraint.\n *\n * More practice:\n * If you have figured out the O(n) solution, try coding another solution of\n * which the time complexity is O(n log n).\n *\n */\n\n\npublic class MinimumSizeSubarraySum209 {\n    public int minSubArrayLen(int s, int[] nums) {\n        if (nums == null || nums.length == 0 || s == 0) return 0;\n\n        int slow = 0;\n        int sum = 0;\n        int min = Integer.MAX_VALUE;\n        for (int fast=0; fast<nums.length; fast++) {\n            sum += nums[fast];\n            while (sum >= s && slow < nums.length) {\n                min = Math.min(min, fast-slow+1);\n                sum -= nums[slow];\n                slow++;\n            }\n        }\n\n        return min == Integer.MAX_VALUE ? 0 : min;\n    }\n\n    public int minSubArrayLen2(int s, int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        \n        int minLen = Integer.MAX_VALUE;\n        int sum = 0;\n        int left = 0;\n        int right = 0;\n        while (right < nums.length) {\n            sum += nums[right++];\n            while (sum >= s) {\n                if (right - left < minLen) {\n                    minLen = right - left;\n                }\n                sum -= nums[left++];\n            }\n        }\n        \n        return minLen == Integer.MAX_VALUE ? 0 : minLen;\n    }\n\n\n    public int minSubArrayLen3(int s, int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        \n        int lo = 1;\n        int hi = nums.length;\n        int minLen = Integer.MAX_VALUE;\n        while (lo <= hi) {\n            int mid = lo + (hi - lo) / 2;\n            if (isValid(nums, mid, s)) {\n                if (mid < minLen) minLen = mid;\n                hi = mid - 1;\n            } else {\n                lo = mid + 1;\n            }\n        }\n        \n        return minLen == Integer.MAX_VALUE ? 0 : minLen;\n    }\n    \n    private boolean isValid(int[] nums, int len, int s) {\n        int sum = 0;\n        for (int i=0; i<len; i++) {\n            sum += nums[i];\n            if (sum >= s) return true;\n        }\n        for (int i=len; i<nums.length; i++) {\n            sum -= nums[i-len];\n            sum += nums[i];\n            if (sum >= s) return true;\n        }\n        return false;\n    }\n\n\n}\n"
  },
  {
    "path": "src/MinimumWindowSubsequence727.java",
    "content": "/**\n * Given strings S and T, find the minimum (contiguous) substring W of S, so\n * that T is a subsequence of W.\n *\n * If there is no such window in S that covers all characters in T, return the\n * empty string \"\". If there are multiple such minimum-length windows, return\n * the one with the left-most starting index.\n *\n * Example 1:\n * Input:\n * S = \"abcdebdde\", T = \"bde\"\n * Output: \"bcde\"\n *\n * Explanation:\n * \"bcde\" is the answer because it occurs before \"bdde\" which has the same length.\n * \"deb\" is not a smaller window because the elements of T in the window must occur in order.\n *\n * Note:\n *\n * All the strings in the input will only contain lowercase letters.\n * The length of S will be in the range [1, 20000].\n * The length of T will be in the range [1, 100].\n *\n */\n\n\npublic class MinimumWindowSubsequence727 {\n    public String minWindow(String S, String T) {\n        if (S.length() == 0 || T.length() == 0) return \"\";\n        char[] schars = S.toCharArray();\n        char[] tchars = T.toCharArray();\n        int sl = schars.length;\n        int tl = tchars.length;\n\n        int[][] n = new int[tl+1][sl+1];\n        for (int j=0; j<=sl; j++) n[0][j] = 0;\n        for (int i=1; i<=tl; i++) n[i][0] = -1;\n\n        for (int i=1; i<=tl; i++) {\n            for (int j=1; j<=sl; j++) {\n                n[i][j] = Math.max(\n                    (schars[j-1] == tchars[i-1] && n[i-1][j-1] != -1) ? j : -1,\n                    n[i][j-1]\n                );\n            }\n        }\n\n        int[] edges = new int[2];\n        int diff = Integer.MAX_VALUE;\n        int j = 1;\n        while (j <= sl && n[tl][j] == -1) j++;\n        while (j <= sl) {\n            int lastJ = j;\n            int i = tl;\n            while (i > 1 && j > 1) {\n                i--;\n                j--;\n                j = n[i][j];\n            }\n            if (i == 1 && j > 0 && diff > lastJ - j + 1) {\n                edges[0] = j;\n                edges[1] = lastJ;\n                diff = lastJ - j + 1;\n            }\n            j = lastJ;\n            while (j <= sl && n[tl][j] == lastJ) j++;\n        }\n\n        return (diff == Integer.MAX_VALUE) ? \"\" : S.substring(edges[0]-1, edges[1]);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/minimum-window-subsequence/solution/\n     */\n    public String minWindow2s(String S, String T) {\n        int[][] dp = new int[2][S.length()];\n\n        for (int i = 0; i < S.length(); ++i)\n            dp[0][i] = S.charAt(i) == T.charAt(0) ? i : -1;\n\n        /*At time j when considering T[:j+1],\n          the smallest window [s, e] where S[e] == T[j]\n          is represented by dp[j & 1][e] = s, and the\n          previous information of the smallest window\n          [s, e] where S[e] == T[j-1] is stored as\n          dp[~j & 1][e] = s.\n        */\n        for (int j = 1; j < T.length(); ++j) {\n            int last = -1;\n            Arrays.fill(dp[j & 1], -1);\n            //Now we would like to calculate the candidate windows\n            //\"dp[j & 1]\" for T[:j+1].  'last' is the last window seen.\n            for (int i = 0; i < S.length(); ++i) {\n                if (last >= 0 && S.charAt(i) == T.charAt(j))\n                    dp[j & 1][i] = last;\n                if (dp[~j & 1][i] >= 0)\n                    last = dp[~j & 1][i];\n            }\n        }\n\n        //Looking at the window data dp[~T.length & 1],\n        //choose the smallest length window [s, e].\n        int start = 0, end = S.length();\n        for (int e = 0; e < S.length(); ++e) {\n            int s = dp[~T.length() & 1][e];\n            if (s >= 0 && e - s < end - start) {\n                start = s;\n                end = e;\n            }\n        }\n        return end < S.length() ? S.substring(start, end+1) : \"\";\n    }\n\n\n    /**\n     * https://leetcode.com/problems/minimum-window-subsequence/solution/\n     */\n    public String minWindow3(String S, String T) {\n        int N = S.length();\n        int[] last = new int[26];\n        int[][] nxt = new int[N][26];\n        Arrays.fill(last, -1);\n\n        for (int i = N - 1; i >= 0; --i) {\n            last[S.charAt(i) - 'a'] = i;\n            for (int k = 0; k < 26; ++k) {\n                nxt[i][k] = last[k];\n            }\n        }\n\n        List<int[]> windows = new ArrayList();\n        for (int i = 0; i < N; ++i) {\n            if (S.charAt(i) == T.charAt(0))\n                windows.add(new int[]{i, i});\n        }\n        for (int j = 1; j < T.length(); ++j) {\n            int letterIndex = T.charAt(j) - 'a';\n            for (int[] window: windows) {\n                if (window[1] < N-1 && nxt[window[1]+1][letterIndex] >= 0) {\n                    window[1] = nxt[window[1]+1][letterIndex];\n                }\n                else {\n                    window[0] = window[1] = -1;\n                    break;\n                }\n            }\n        }\n\n        int[] ans = {-1, S.length()};\n        for (int[] window: windows) {\n            if (window[0] == -1) break;\n            if (window[1] - window[0] < ans[1] - ans[0]) {\n                ans = window;\n            }\n\n        }\n        return ans[0] >= 0 ? S.substring(ans[0], ans[1] + 1) : \"\";\n    }\n\n\n    /**\n     * https://leetcode.com/problems/minimum-window-subsequence/discuss/109362/Java-Super-Easy-DP-Solution-(O(mn))\n     */\n    public String minWindow4(String S, String T) {\n        int m = T.length(), n = S.length();\n        int[][] dp = new int[m + 1][n + 1];\n        for (int j = 0; j <= n; j++) {\n            dp[0][j] = j + 1;\n        }\n        for (int i = 1; i <= m; i++) {\n            for (int j = 1; j <= n; j++) {\n                if (T.charAt(i - 1) == S.charAt(j - 1)) {\n                    dp[i][j] = dp[i - 1][j - 1];\n                } else {\n                    dp[i][j] = dp[i][j - 1];\n                }\n            }\n        }\n\n        int start = 0, len = n + 1;\n        for (int j = 1; j <= n; j++) {\n            if (dp[m][j] != 0) {\n                if (j - dp[m][j] + 1 < len) {\n                    start = dp[m][j] - 1;\n                    len = j - dp[m][j] + 1;\n                }\n            }\n        }\n        return len == n + 1 ? \"\" : S.substring(start, start + len);\n    }\n\n\n    public String minWindow5(String S, String T) {\n        if (S == null || T == null || T.length() > S.length()) return \"\";\n        int lenS = S.length();\n        int lenT = T.length();\n        char[] charS = S.toCharArray();\n        char[] charT = T.toCharArray();\n        int[][] pos = new int[lenT][lenS];\n        for (int i=0; i<lenT; i++) {\n            for (int j=0; j<lenS; j++) {\n                if (charT[i] == charS[j]) {\n                    pos[i][j] = i == 0 ? j : (j == 0 ? -1 : pos[i-1][j-1]);\n                } else {\n                    pos[i][j] = j == 0 ? -1 : pos[i][j-1];\n                }\n            }\n        }\n\n        int start = -1;\n        int minSize = Integer.MAX_VALUE;\n        for (int j=lenS-1; j>=0; j--) {\n            if (pos[lenT-1][j] == -1) break;\n            if (j - pos[lenT-1][j] + 1 <= minSize) {\n                start = pos[lenT-1][j];\n                minSize = j - pos[lenT-1][j] + 1;\n            }\n        }\n        return start == -1 ? \"\" : S.substring(start, start + minSize);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/minimum-window-subsequence/discuss/109373/m-pointer-technique-Java-O(S.length()-*-T.length())-solution\n     */\n    public String minWindow6(String S, String T) {\n        int n = S.length(), m = T.length();\n        int l = 0, r = n;\n            \n        for (int i = 0; i < n; i++) {\n            if (S.charAt(i) != T.charAt(0)) continue;  // No group of mapping is found, so continue\n            \n            int k = i + 1;\n                \n            for (int j = 1; j < m; j++, k++) {  // Greedy algorithm to find the greedy mapping\n                while (k < n && S.charAt(k) != T.charAt(j)) k++;\n                if (k == n) return (r == n ? \"\" : S.substring(l, r + 1));  // Link for T[j] does not exist, so return\n            }\n            \n            if (k - 1 - i < r - l) {  // Update the result substring if one with a smaller length is found\n                l = i; r = k - 1;\n            }\n        }\n        \n        return (r == n ? \"\" : S.substring(l, r + 1));\n    }\n    /**\n     * https://leetcode.com/problems/minimum-window-subsequence/discuss/109373/m-pointer-technique-Java-O(S.length()-*-T.length())-solution\n     */\n    public String minWindow7(String S, String T) {\n        int n = S.length(), m = T.length();\n        int l = 0, r = n;\n        \n        int[] p = new int[m];\n            \n        for (int i = 0; i < n; i++) {\n            if (S.charAt(i) != T.charAt(0)) continue;  // No group of mapping is found, so continue\n            \n            p[0] = i;  // Group of mapping is found, so update the first link\n            \n            for (int j = 1, k = i + 1; j < m; j++, k++) {  // Greedy algorithm to find the greedy mapping\n                if (k <= p[j]) break;    // Early termination, since the remaining links have been computed in previous groups\n                while (k < n && S.charAt(k) != T.charAt(j)) k++;\n                if (k == n) return (r == n ? \"\" : S.substring(l, r + 1));  // Link for T[j] does not exist, so return\n                p[j] = k;  // Else update the link for T[j]\n            }\n                \n            if (p[m - 1] - p[0] < r - l) {  // Update the result substring if one with a smaller length is found\n                l = p[0]; r = p[m - 1];\n            }\n        }\n            \n        return (r == n ? \"\" : S.substring(l, r + 1));\n    }\n\n\n\n    public String minWindow8(String S, String T) {\n        int lenS = S.length();\n        int lenT = T.length();\n        char[] charS = S.toCharArray();\n        char[] charT = T.toCharArray();\n        \n        int left = 0;\n        int right = 0;\n        int flag = 0;\n        \n        int start = -1;\n        int minLen = lenS + 1;\n        while (right < lenS) {\n            while (left <= lenS - lenT && charS[left] != charT[0]) left++;\n            if (left > lenS - lenT) break;\n            right = left;\n            flag = 0;\n            while (flag < lenT && right < lenS) {\n                if (charS[right] == charT[flag]) {\n                    flag++;\n                }\n                right++;\n            }\n            if (flag != lenT) break;\n            if (right - left < minLen) {\n                minLen = right - left;\n                start = left;\n            }\n            left++;\n            right = left;\n        }\n        return start == -1 ? \"\" : S.substring(start, start + minLen);\n    }\n\n\n    public String minWindow9(String S, String T) {\n        int lenS = S.length();\n        int lenT = T.length();\n        char[] charS = S.toCharArray();\n        char[] charT = T.toCharArray();\n        \n        int left = 0;\n        int right = 0;\n        int flag = 0;\n        \n        int start = -1;\n        int minLen = lenS + 1;\n        while (right < lenS) {\n            while (left <= lenS - lenT && charS[left] != charT[0]) left++;\n            if (left > lenS - lenT) break;\n            right = left;\n            flag = 0;\n            while (flag < lenT && right < lenS) {\n                if (charS[right] == charT[flag]) {\n                    flag++;\n                }\n                right++;\n            }\n            if (flag != lenT) break;\n            int newStart = backwards(charS, charT, left, right-1);\n            left = Math.max(left, newStart);\n            if (right - left < minLen) {\n                minLen = right - left;\n                start = left;\n            }\n            left++;\n            right = left;\n        }\n        return start == -1 ? \"\" : S.substring(start, start + minLen);\n    }\n    \n    private int backwards(char[] charS, char[] charT, int begin, int end) {\n        int flagS = end;\n        int flagT = charT.length - 1;\n        while (true) {\n            if (charS[flagS] == charT[flagT]) {\n                if (flagT == 0) return flagS;\n                flagT--;\n            }\n            flagS--;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/MinimumWindowSubstring76.java",
    "content": "/**\n * Given a string S and a string T, find the minimum window in S which will\n * contain all the characters in T in complexity O(n).\n *\n * For example,\n * S = \"ADOBECODEBANC\"\n * T = \"ABC\"\n * Minimum window is \"BANC\".\n *\n * Note:\n * If there is no such window in S that covers all characters in T, return the\n * empty string \"\".\n *\n * If there are multiple such windows, you are guaranteed that there will always\n * be only one unique minimum window in S.\n */\n\n\npublic class MinimumWindowSubstring76 {\n    /**\n     * https://discuss.leetcode.com/topic/12492/share-my-neat-java-solution\n     */\n    public String minWindow(String S, String T) {\n        if(S==null||S.isEmpty()||T==null||T.isEmpty()) return \"\";\n        int i=0, j=0;\n        int[] Tmap=new int[256];\n        int[] Smap=new int[256];\n        for(int k=0; k< T.length(); k++){\n            Tmap[T.charAt(k)]++;\n        }\n        int found=0;\n        int length=Integer.MAX_VALUE;\n        String res=\"\";\n        while(j<S.length()){\n            if(found<T.length()){\n                if(Tmap[S.charAt(j)]>0){\n                    Smap[S.charAt(j)]++;\n                    if(Smap[S.charAt(j)]<=Tmap[S.charAt(j)]){\n                        found++;\n                    }\n                }\n                j++;\n            }\n            while(found==T.length()){\n                if(j-i<length){\n                    length=j-i; res=S.substring(i,j);\n                }\n                if(Tmap[S.charAt(i)]>0){\n                    Smap[S.charAt(i)]--;\n                    if(Smap[S.charAt(i)]<Tmap[S.charAt(i)]){\n                        found--;\n                    }\n                }\n                i++;\n            }\n        }\n        return res;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/30941/here-is-a-10-line-template-that-can-solve-most-substring-problems\n     */\n    public String minWindow2(String s, String t) {\n        int start = 0 , end = 0;\n        int map[] = new int[256];\n        for (int i = 0; i < t.length() ; i++) {\n            map[t.charAt(i)]++;\n        }\n        int min = Integer.MAX_VALUE;\n        int counter = 0;\n        int ts = 0, te = 0;\n        while (end < s.length()) {\n\n            if (map[s.charAt(end++)]-- >= 1)\n                counter++;\n\n            while (counter == t.length()) {\n                if (end - start < min) {\n                    min = end - start;\n                    ts = start; te = end;\n                }\n                if (map[s.charAt(start++)]++ >= 0)\n                    counter--;\n            }\n\n        }\n\n        return min == Integer.MAX_VALUE? \"\": s.substring(ts,te);\n    }\n\n\n    public String minWindow3(String s, String t) {\n        if (s == null || s.length() == 0 || t == null || t.length() == 0) return \"\";\n        \n        int lenS = s.length();\n        int lenT = t.length();\n        int start = 0;\n        int len = Integer.MAX_VALUE;\n        int l = 0;\n        int r = 0;\n        char[] charsInS = s.toCharArray();\n        int[] map = new int[256];\n        boolean[] contains = new boolean[256];\n        char[] charsInT = t.toCharArray();\n        for (char c: charsInT) {\n            map[c]++;\n            contains[c] = true;\n        }\n        int count = 0;\n        while (r < lenS) {\n            if (!contains[charsInS[r]]) {\n                r++;\n                continue;\n            }\n            map[charsInS[r]]--;\n            if (map[charsInS[r]] >= 0) {\n                count++;\n            }\n            r++;\n            \n            while (l <= r && count == lenT) {\n                if (r - l < len) {\n                    len = r - l;\n                    start = l;\n                }\n                \n                if (contains[charsInS[l]]) {\n                    map[charsInS[l]]++;\n                    if (map[charsInS[l]] > 0) {\n                        count--;\n                    }\n                }\n                l++;\n            }\n            \n        }\n        \n        return len == Integer.MAX_VALUE ? \"\" : s.substring(start, start + len);\n    }\n\n}\n"
  },
  {
    "path": "src/MissingNumber268.java",
    "content": "/**\n * Given an array containing n distinct numbers taken from 0, 1, 2, ..., n,\n * find the one that is missing from the array.\n * \n * Example 1:\n * Input: [3,0,1]\n * Output: 2\n * \n * Example 2:\n * Input: [9,6,4,2,3,5,7,0,1]\n * Output: 8\n * \n * Note:\n * Your algorithm should run in linear runtime complexity.\n * Could you implement it using only constant extra space complexity?\n */\n\n\npublic class MissingNumber268 {\n    public int missingNumber(int[] nums) {\n        int sum = 0;\n        int N = nums.length;\n        for (int n: nums) sum += n;\n        return N * (N + 1) / 2 - sum;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/missing-number/solution/\n     */\n    public int missingNumber2(int[] nums) {\n        int missing = nums.length;\n        for (int i = 0; i < nums.length; i++) {\n            missing ^= i ^ nums[i];\n        }\n        return missing;\n    }\n\n}\n"
  },
  {
    "path": "src/MissingRanges163.java",
    "content": "/**\n * Given a sorted integer array where the range of elements are in the\n * inclusive range [lower, upper], return its missing ranges.\n *\n * For example, given [0, 1, 3, 50, 75], lower = 0 and upper = 99, return\n * [\"2\", \"4->49\", \"51->74\", \"76->99\"].\n */\n\npublic class MissingRanges163 {\n    public List<String> findMissingRanges(int[] nums, int lower, int upper) {\n        List<String> res = new ArrayList<>();\n\n        long mark = (long) lower;\n        for (int i=0; i<nums.length; i++) {\n            if (i > 0 && nums[i] == nums[i-1]) continue;\n            long n = (long) nums[i];\n            if (n > mark) {\n                String s = String.valueOf(mark);\n                res.add((mark == n-1) ? s : s + \"->\" + String.valueOf(n-1));\n            }\n            mark = n+1;\n        }\n        if (mark == upper) res.add(String.valueOf(mark));\n        else if (mark < upper) res.add(String.valueOf(mark) + \"->\" + String.valueOf(upper));\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/MonotoneIncreasingDigits738.java",
    "content": "/**\n * Given a non-negative integer N, find the largest number that is less than or\n * equal to N with monotone increasing digits.\n * \n * (Recall that an integer has monotone increasing digits if and only if each\n * pair of adjacent digits x and y satisfy x <= y.)\n * \n * Example 1:\n * Input: N = 10\n * Output: 9\n * \n * Example 2:\n * Input: N = 1234\n * Output: 1234\n * \n * Example 3:\n * Input: N = 332\n * Output: 299\n * Note: N is an integer in the range [0, 10^9].\n */\n\npublic class MonotoneIncreasingDigits738 {\n    public int monotoneIncreasingDigits(int N) {\n        String ns = Integer.toString(N);\n        int i = 0;\n        char[] chars = ns.toCharArray();\n        while (i + 1 < chars.length && chars[i] <= chars[i+1]) {\n            i++;\n        }\n        while (i > 0 && chars[i-1] == chars[i]) {\n            i--;\n        }\n        if (i == chars.length - 1) return N;\n        chars[i] = (char) ((int) chars[i] - 1);\n        for (int j=i+1; j<chars.length; j++) {\n            chars[j] = '9';\n        }\n        return Integer.valueOf(new String(chars));\n    }\n\n\n    /**\n     * https://leetcode.com/problems/monotone-increasing-digits/solution/\n     */\n    public int monotoneIncreasingDigits2(int N) {\n        char[] S = String.valueOf(N).toCharArray();\n        int i = 1;\n        while (i < S.length && S[i-1] <= S[i]) i++;\n        while (0 < i && i < S.length && S[i-1] > S[i]) S[--i]--;\n        for (int j = i+1; j < S.length; ++j) S[j] = '9';\n\n        return Integer.parseInt(String.valueOf(S));\n    }\n\n\n    /**\n     * https://leetcode.com/problems/monotone-increasing-digits/discuss/144404/Simple-Java-from-back-to-front-no-extra-space-and-no-conversion-to-char\n     */\n    public int monotoneIncreasingDigits3(int N) {\n        int res = 0;\n        int pre = Integer.MAX_VALUE;\n        int offset = 1;\n        while(N != 0) {\n            int digit = N % 10;\n            if(digit > pre) {\n                res = digit * offset - 1;\n                pre = digit - 1;\n            }else {\n                res = res + digit * offset;\n                pre = digit;\n            }\n            offset *= 10;\n            N = N / 10;\n        }\n        return res;\n    }\n\n}\n\n"
  },
  {
    "path": "src/MonotonicArray896.java",
    "content": "/**\n * An array is monotonic if it is either monotone increasing or monotone decreasing.\n * \n * An array A is monotone increasing if for all i <= j, A[i] <= A[j].  An array A is\n * monotone decreasing if for all i <= j, A[i] >= A[j].\n * \n * Return true if and only if the given array A is monotonic.\n * \n * Example 1:\n * Input: [1,2,2,3]\n * Output: true\n * \n * Example 2:\n * Input: [6,5,4,4]\n * Output: true\n * \n * Example 3:\n * Input: [1,3,2]\n * Output: false\n * \n * Example 4:\n * Input: [1,2,4,5]\n * Output: true\n * \n * Example 5:\n * Input: [1,1,1]\n * Output: true\n * \n * Note:\n * 1 <= A.length <= 50000\n * -100000 <= A[i] <= 100000\n */\n\npublic class MonotonicArray896 {\n    public boolean isMonotonic(int[] A) {\n        if (A == null || A.length <= 2) return true;\n        int i = 1;\n        int len = A.length;\n        while (i < len && A[i] == A[i-1]) i++;\n        if (i == len) return true;\n        boolean flag = A[i] > A[i-1];\n        while (i < len) {\n            if (A[i] != A[i-1] && flag != A[i] > A[i-1]) return false;\n            i++;\n        }\n        return true;\n    }\n\n    /**\n     * https://leetcode.com/problems/monotonic-array/solution/\n     */\n    public boolean isMonotonic2(int[] A) {\n        int store = 0;\n        for (int i = 0; i < A.length - 1; ++i) {\n            int c = Integer.compare(A[i], A[i+1]);\n            if (c != 0) {\n                if (c != store && store != 0)\n                    return false;\n                store = c;\n            }\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/MostCommonWord819.java",
    "content": "/**\n * Given a paragraph and a list of banned words, return the most frequent word\n * that is not in the list of banned words.  It is guaranteed there is at least\n * one word that isn't banned, and that the answer is unique.\n * \n * Words in the list of banned words are given in lowercase, and free of\n * punctuation.  Words in the paragraph are not case sensitive.  The answer\n * is in lowercase.\n * \n * Example:\n * Input: \n * paragraph = \"Bob hit a ball, the hit BALL flew far after it was hit.\"\n * banned = [\"hit\"]\n * Output: \"ball\"\n * \n * Explanation: \n * \"hit\" occurs 3 times, but it is a banned word.\n * \"ball\" occurs twice (and no other word does), so it is the most frequent\n * non-banned word in the paragraph. \n * \n * Note that words in the paragraph are not case sensitive,\n * that punctuation is ignored (even if adjacent to words, such as \"ball,\"), \n * and that \"hit\" isn't the answer even though it occurs more because it is banned.\n * \n * Note:\n * \n * 1 <= paragraph.length <= 1000.\n * 1 <= banned.length <= 100.\n * 1 <= banned[i].length <= 10.\n * The answer is unique, and written in lowercase (even if its occurrences in\n * paragraph may have uppercase symbols, and even if it is a proper noun.)\n * paragraph only consists of letters, spaces, or the punctuation symbols !?',;.\n * Different words in paragraph are always separated by a space.\n * There are no hyphens or hyphenated words.\n * Words only consist of letters, never apostrophes or other punctuation symbols.\n */\n\n\npublic class MostCommonWord819 {\n    public String mostCommonWord(String paragraph, String[] banned) {\n        if (paragraph == null || paragraph.length() == 0) return \"\";\n        // update O(K)\n        Set<String> bannedSet = new HashSet<>();\n        for (String w: banned) bannedSet.add(w.toLowerCase());\n\n        // update O(N), N: number of chars\n        Map<String, Integer> freq = new HashMap<>();\n\n        String mcw = \"\";\n        int maxCount = -1;\n        int left = 0;\n        int right = 0;\n        while (right < paragraph.length()) {\n            while (left < paragraph.length() && !isLetter(paragraph.charAt(left))) left++;\n            if (left >= paragraph.length()) break;\n            right = left;\n            while (right < paragraph.length() && isLetter(paragraph.charAt(right))) right++;\n            String word  = paragraph.substring(left, right).toLowerCase();\n            if (!bannedSet.contains(word)) {\n                freq.put(word, freq.getOrDefault(word, 0) + 1);\n                if (freq.get(word) > maxCount) {\n                    maxCount = freq.get(word);\n                    mcw = word;\n                }\n            }\n            left = right;\n        }\n\n        return mcw;\n    }\n\n    private boolean isLetter(char c) {\n        return (c - 'a' >= 0 && c - 'z' <= 0) || (c - 'A' >= 0 && c - 'Z' <= 0);\n    }\n\n\n\n    public String mostCommonWord2(String paragraph, String[] banned) {\n        String[] splitArr = paragraph.replaceAll(\"[!?',;.]\",\"\").toLowerCase().split(\" \");\n        HashMap<String, Integer> map = new HashMap<>();\n        List<String> bannedList = Arrays.asList(banned);\n        int currentMax = 0;\n        String res = \"\";\n        for(String str: splitArr) {\n            if(!bannedList.contains(str)) {\n                map.put(str, map.getOrDefault(str, 0) + 1);\n                if (map.get(str) > currentMax) {\n                    res = str;\n                    currentMax = map.get(str);\n                }\n            }\n        }\n        return res;\n    }\n\n}\n\n"
  },
  {
    "path": "src/MostFrequentSubtreeSum508.java",
    "content": "/**\n * Given the root of a tree, you are asked to find the most frequent subtree\n * sum. The subtree sum of a node is defined as the sum of all the node values\n * formed by the subtree rooted at that node (including the node itself). So\n * what is the most frequent subtree sum value? If there is a tie, return all\n * the values with the highest frequency in any order.\n *\n * Examples 1\n * Input:\n *\n *   5\n *  /  \\\n * 2   -3\n * return [2, -3, 4], since all the values happen only once, return all of\n * them in any order.\n *\n * Examples 2\n * Input:\n *\n *   5\n *  /  \\\n * 2   -5\n * return [2], since 2 happens twice, however -5 only occur once.\n *\n * Note: You may assume the sum of values in any subtree is in the range of\n * 32-bit signed integer.\n *\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\n\npublic class MostFrequentSubtreeSum508 {\n    public int[] findFrequentTreeSum(TreeNode root) {\n        Map<Integer, Integer> sums = new HashMap<>();\n        if (root == null) return new int[0];\n\n        int[] cache = new int[1];\n        cache[0] = Integer.MIN_VALUE;\n        helper(root, sums, cache);\n\n        List<Integer> list = new ArrayList<>();\n        for (Map.Entry<Integer, Integer> e: sums.entrySet()) {\n            if (e.getValue().equals(cache[0])) {\n                list.add(e.getKey());\n            }\n        }\n        int[] res = new int[list.size()];\n        for (int i=0; i<list.size(); i++) res[i] = list.get(i);\n        return res;\n    }\n\n    private Integer helper(TreeNode n, Map<Integer, Integer> sums, int[] cache) {\n        if (n == null) return null;\n\n        Integer left = helper(n.left, sums, cache);\n        Integer right = helper(n.right, sums, cache);\n\n        int sum = ((left == null) ? 0 : left) + ((right == null) ? 0 : right) + n.val;\n        int t = sums.getOrDefault(sum, 0) + 1;\n        cache[0] = Math.max(cache[0], t);\n        sums.put(sum, t);\n\n        return sum;\n    }\n\n\n    public int[] findFrequentTreeSum2(TreeNode root) {\n        Map<Integer, Integer> map = new HashMap<>();\n        findFrequentTreeSum(root, map);\n        \n        int freq = 0;\n        Set<Integer> sums = new HashSet<>();\n        for (Map.Entry<Integer, Integer> entry: map.entrySet()) {\n            if (entry.getValue() == freq) {\n                sums.add(entry.getKey());\n            } else if (entry.getValue() > freq) {\n                freq = entry.getValue();\n                sums.clear();\n                sums.add(entry.getKey());\n            }\n        }\n        \n        int[] res = new int[sums.size()];\n        int i = 0;\n        for (int n: sums) {\n            res[i++] = n;\n        }\n        return res;\n    }\n\n    public int findFrequentTreeSum(TreeNode root, Map<Integer, Integer> map) {\n        if (root == null) return 0;\n        \n        int l = findFrequentTreeSum(root.left, map);\n        int r = findFrequentTreeSum(root.right, map);\n        int sum = l + r + root.val;\n        map.put(sum, map.getOrDefault(sum, 0) + 1);\n        return sum;\n    }\n\n}\n"
  },
  {
    "path": "src/MostProfitAssigningWork826.java",
    "content": "/**\n * We have jobs: difficulty[i] is the difficulty of the ith job, and profit[i]\n * is the profit of the ith job. \n * \n * Now we have some workers. worker[i] is the ability of the ith worker, which\n * means that this worker can only complete a job with difficulty at most\n * worker[i]. \n * \n * Every worker can be assigned at most one job, but one job can be completed\n * multiple times.\n * \n * For example, if 3 people attempt the same job that pays $1, then the total\n * profit will be $3.  If a worker cannot complete any job, his profit is $0.\n * \n * What is the most profit we can make?\n * \n * Example 1:\n * \n * Input: difficulty = [2,4,6,8,10], profit = [10,20,30,40,50], worker = [4,5,6,7]\n * Output: 100 \n * Explanation: Workers are assigned jobs of difficulty [4,4,6,6] and they get\n * profit of [20,20,30,30] seperately.\n * \n * Notes:\n * 1 <= difficulty.length = profit.length <= 10000\n * 1 <= worker.length <= 10000\n * difficulty[i], profit[i], worker[i]  are in range [1, 10^5]\n */\n\npublic class MostProfitAssigningWork826 {\n    public int maxProfitAssignment(int[] difficulty, int[] profit, int[] worker) {\n        int N = difficulty.length;\n        Job[] jobs = new Job[N];\n        for (int i=0; i<N; i++) jobs[i] = new Job(difficulty[i], profit[i]);\n        Arrays.sort(jobs, (j1, j2) -> Integer.compare(j1.difficulty, j2.difficulty));\n        Arrays.sort(worker);\n        int res = 0;\n        int max = 0;\n        int i = 0;\n        for (int cap: worker) {\n            while (i < N && jobs[i].difficulty <= cap) {\n                max = Math.max(max, jobs[i].profit);\n                i++;\n            }\n            res += max;\n        }\n        return res;\n    }\n    \n    class Job {\n        int difficulty;\n        int profit;\n        Job (int d, int p) {\n            difficulty = d;\n            profit = p;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/MoveZeroes283.java",
    "content": "/**\n * Given an array nums, write a function to move all 0's to the end of it while\n * maintaining the relative order of the non-zero elements.\n *\n * For example, given nums = [0, 1, 0, 3, 12], after calling your function,\n * nums should be [1, 3, 12, 0, 0].\n *\n * Note:\n * You must do this in-place without making a copy of the array.\n * Minimize the total number of operations.\n *\n */\n\npublic class MoveZeroes283 {\n    public void moveZeroes(int[] nums) {\n        int slow = 0;\n        int fast = 0;\n        while (fast < nums.length) {\n            if (nums[fast] != 0) {\n                nums[slow] = nums[fast];\n                slow++;\n            }\n            fast++;\n        }\n        while (slow < nums.length) {\n            nums[slow] = 0;\n            slow++;\n        }\n    }\n\n    public void moveZeroes2(int[] nums) {\n        int p = 0;\n        int zeros = -1;\n        for (int i=0; i<nums.length; i++) {\n            if (nums[i] == 0) {\n                zeros++;\n            } else {\n                nums[p] = nums[i];\n                p++;\n            }\n\n        }\n        while (zeros >=0) {\n            nums[nums.length-1-zeros] = 0;\n            zeros--;\n        }\n    }\n\n    public void moveZeroes3(int[] nums) {\n        for (int i = 0, p = 0; p < nums.length; p++) {\n            if (nums[p] != 0) {\n                swap(nums, i++, p);\n            }\n        }\n    }\n\n    private void swap(int[] arr, int a, int b) {\n        int temp = arr[a];\n        arr[a] = arr[b];\n        arr[b] = temp;\n    }\n\n}\n"
  },
  {
    "path": "src/MovingAverageFromDataStream346.java",
    "content": "/**\n * Given a stream of integers and a window size, calculate the moving average\n * of all integers in the sliding window.\n * \n * For example,\n * MovingAverage m = new MovingAverage(3);\n * m.next(1) = 1\n * m.next(10) = (1 + 10) / 2\n * m.next(3) = (1 + 10 + 3) / 3\n * m.next(5) = (10 + 3 + 5) / 3\n */\n\n\npublic class MovingAverageFromDataStream346 {\n    class MovingAverage {\n        private int size;\n        private Queue<Integer> cache;\n        private long sum;\n        \n        /** Initialize your data structure here. */\n        public MovingAverage(int size) {\n            this.size = size;\n            this.cache = new LinkedList<Integer>();\n            this.sum = 0L;\n        }\n      \n        public double next(int val) {\n            if (this.cache.size() >= this.size) {\n                this.sum -= this.cache.remove();\n            }\n            this.sum += val;\n            this.cache.add(val);\n            return this.sum * 1.0 / this.cache.size();\n        }\n    }\n\n\n    class MovingAverage2 {\n        private int[] window;\n        private int head = 0;\n        private int len = 0 ;\n        private int sum = 0;\n\n        /** Initialize your data structure here. */\n        public MovingAverage2(int size) {\n            this.window = new int[size + 1];\n        }\n\n        public double next(int val) {\n            int nextPos = (this.head + this.len + 1) % this.window.length;\n            this.window[nextPos] = val;\n            this.len++;\n            this.sum += val;\n            \n            if (this.len == this.window.length) {\n                this.head++;\n                this.head %= this.window.length;\n                this.len--;\n                this.sum -= this.window[this.head];\n            }\n            return this.sum * 1.0 / this.len;\n        }\n    }\n\n}\n\n/**\n* Your MovingAverage object will be instantiated and called as such:\n* MovingAverage obj = new MovingAverage(size);\n* double param_1 = obj.next(val);\n*/\n\n"
  },
  {
    "path": "src/MultiplyStrings43.java",
    "content": "/**\n * Given two non-negative integers num1 and num2 represented as strings, return\n * the product of num1 and num2, also represented as a string.\n * \n * Example 1:\n * Input: num1 = \"2\", num2 = \"3\"\n * Output: \"6\"\n * \n * Example 2:\n * Input: num1 = \"123\", num2 = \"456\"\n * Output: \"56088\"\n * \n * Note:\n * The length of both num1 and num2 is < 110.\n * Both num1 and num2 contain only digits 0-9.\n * Both num1 and num2 do not contain any leading zero, except the number 0 itself.\n * You must not use any built-in BigInteger library or convert the inputs to\n * integer directly.\n */\n\npublic class MultiplyStrings43 {\n    public String multiply(String num1, String num2) {\n        char[] chars1 = num1.toCharArray();\n        char[] chars2 = num2.toCharArray();\n        StringBuilder sb = new StringBuilder();\n        sb.append('0');\n        for (int j=chars2.length - 1; j>=0; j--) {\n            StringBuilder oneMul = multiplyForOne(chars1, chars2[j]);\n            for (int z=0; z<chars2.length - 1 - j; z++) {\n                oneMul.append('0');\n            }\n            sb = add(sb, oneMul);\n        }\n        while (sb.length() > 1 && sb.charAt(0) == '0') {\n            sb.deleteCharAt(0);\n        }\n        return sb.toString();\n    }\n\n    private StringBuilder multiplyForOne(char[] chars, char ch) {\n        StringBuilder sb = new StringBuilder();\n        int carry = 0;\n        int b = (int)(ch - '0');\n        for (int i = chars.length-1; i>=0; i--) {\n            int prod = (int)(chars[i] - '0') * b + carry;\n            carry = prod / 10;\n            sb.insert(0, Character.forDigit(prod % 10, 10));\n        }\n        if (carry != 0) sb.insert(0, Character.forDigit(carry, 10));\n        return sb;\n    }\n\n    private StringBuilder add(StringBuilder sb1, StringBuilder sb2) {\n        StringBuilder sb = new StringBuilder();\n        int i = sb1.length()-1;\n        int j = sb2.length()-1;\n        int carry = 0;\n        while (i >= 0 && j >= 0) {\n            int prod = (int)(sb1.charAt(i--) - '0') + (int)(sb2.charAt(j--) - '0') + carry;\n            carry = prod / 10;\n            sb.insert(0, Character.forDigit(prod % 10, 10));\n        }\n        while (i >= 0) {\n            int prod = (int)(sb1.charAt(i--) - '0')+ carry;\n            carry = prod / 10;\n            sb.insert(0, Character.forDigit(prod % 10, 10));\n        }\n        while (j >= 0) {\n            int prod = (int)(sb2.charAt(j--) - '0') + carry;\n            carry = prod / 10;\n            sb.insert(0, Character.forDigit(prod % 10, 10));\n        }\n        if (carry != 0) sb.insert(0, Character.forDigit(carry, 10));\n        return sb;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/multiply-strings/discuss/17605/Easiest-JAVA-Solution-with-Graph-Explanation\n     */\n    public String multiply2(String num1, String num2) {\n        int m = num1.length(), n = num2.length();\n        int[] pos = new int[m + n];\n      \n        for(int i = m - 1; i >= 0; i--) {\n            for(int j = n - 1; j >= 0; j--) {\n                int mul = (num1.charAt(i) - '0') * (num2.charAt(j) - '0'); \n                int p1 = i + j, p2 = i + j + 1;\n                int sum = mul + pos[p2];\n    \n                pos[p1] += sum / 10;\n                pos[p2] = (sum) % 10;\n            }\n        }  \n        \n        StringBuilder sb = new StringBuilder();\n        for(int p : pos) if(!(sb.length() == 0 && p == 0)) sb.append(p);\n        return sb.length() == 0 ? \"0\" : sb.toString();\n    }\n\n}\n"
  },
  {
    "path": "src/MyCalendarI729.java",
    "content": "/**\n * Implement a MyCalendar class to store your events. A new event can be added\n * if adding the event will not cause a double booking.\n * \n * Your class will have the method, book(int start, int end). Formally, this\n * represents a booking on the half open interval [start, end), the range of\n * real numbers x such that start <= x < end.\n * \n * A double booking happens when two events have some non-empty intersection\n * (ie., there is some time that is common to both events.)\n * \n * For each call to the method MyCalendar.book, return true if the event can\n * be added to the calendar successfully without causing a double booking.\n * Otherwise, return false and do not add the event to the calendar.\n * \n * Your class will be called like this:\n * MyCalendar cal = new MyCalendar(); MyCalendar.book(start, end)\n * \n * Example 1:\n * MyCalendar();\n * MyCalendar.book(10, 20); // returns true\n * MyCalendar.book(15, 25); // returns false\n * MyCalendar.book(20, 30); // returns true\n * \n * Explanation: \n * The first event can be booked.  The second can't because time 15 is already\n * booked by another event.\n * The third event can be booked, as the first event takes every time less\n * than 20, but not including 20.\n * \n * Note:\n * The number of calls to MyCalendar.book per test case will be at most 1000.\n * In calls to MyCalendar.book(start, end), start and end are integers in the\n * range [0, 10^9].\n */\n\n\npublic class MyCalendarI729 {\n    class MyCalendar {\n        private TreeSet<Interval> intervals = new TreeSet<>((i1, i2) -> Integer.compare(i1.start, i2.start));\n        \n        public MyCalendar() {\n        }\n        \n        public boolean book(int start, int end) {\n            Interval inv = new Interval(start, end);\n            Interval ceiling = intervals.ceiling(inv);\n            if (ceiling != null && ceiling.start < end) return false;\n            Interval floor = intervals.floor(inv);\n            if (floor != null && floor.end > start) return false;\n            intervals.add(inv);\n            return true;\n        }\n        \n        class Interval {\n            int start;\n            int end;\n            Interval(int s, int e) {\n                start = s;\n                end = e;\n            }\n        }\n    }\n  \n\n    class MyCalendar2 {\n        private TreeMap<Integer, Integer> intervals = new TreeMap<>();\n        \n        public MyCalendar() {\n        }\n        \n        public boolean book(int start, int end) {\n            Map.Entry<Integer, Integer> ceiling = intervals.ceilingEntry(start);\n            if (ceiling != null && ceiling.getKey() < end) return false;\n            Map.Entry<Integer, Integer> floor = intervals.floorEntry(start);\n            if (floor != null && floor.getValue() > start) return false;\n            intervals.put(start, end);\n            return true;\n        }\n        \n    }\n\n\n/**\n * Your MyCalendar object will be instantiated and called as such:\n * MyCalendar obj = new MyCalendar();\n * boolean param_1 = obj.book(start,end);\n */\n\n}\n"
  },
  {
    "path": "src/MyCalendarII731.java",
    "content": "/**\n * Implement a MyCalendarTwo class to store your events. A new event can be\n * added if adding the event will not cause a triple booking.\n * \n * Your class will have one method, book(int start, int end). Formally, this\n * represents a booking on the half open interval [start, end), the range of\n * real numbers x such that start <= x < end.\n * \n * A triple booking happens when three events have some non-empty intersection\n * (ie., there is some time that is common to all 3 events.)\n * \n * For each call to the method MyCalendar.book, return true if the event can be\n * added to the calendar successfully without causing a triple booking.\n * Otherwise, return false and do not add the event to the calendar.\n * \n * Your class will be called like this:\n * MyCalendar cal = new MyCalendar(); MyCalendar.book(start, end)\n * \n * Example 1:\n * MyCalendar();\n * MyCalendar.book(10, 20); // returns true\n * MyCalendar.book(50, 60); // returns true\n * MyCalendar.book(10, 40); // returns true\n * MyCalendar.book(5, 15); // returns false\n * MyCalendar.book(5, 10); // returns true\n * MyCalendar.book(25, 55); // returns true\n * \n * Explanation: \n * The first two events can be booked.  The third event can be double booked.\n * The fourth event (5, 15) can't be booked, because it would result in a\n * triple booking.\n * The fifth event (5, 10) can be booked, as it does not use time 10 which is\n * already double booked.\n * The sixth event (25, 55) can be booked, as the time in [25, 40) will be\n * double booked with the third event;\n * the time [40, 50) will be single booked, and the time [50, 55) will be\n * double booked with the second event.\n *\n * Note:\n * The number of calls to MyCalendar.book per test case will be at most 1000.\n * In calls to MyCalendar.book(start, end), start and end are integers in the\n * range [0, 10^9].\n */\n\npublic class MyCalendarII731 {\n    /**\n     * https://leetcode.com/problems/my-calendar-ii/discuss/109519/JavaC++-Clean-Code-with-Explanation\n     */\n    class MyCalendarTwo {\n        private List<int[]> books = new ArrayList<>();    \n        public boolean book(int s, int e) {\n            MyCalendar overlaps = new MyCalendar();\n            for (int[] b : books)\n                if (Math.max(b[0], s) < Math.min(b[1], e)) // overlap exist\n                    if (!overlaps.book(Math.max(b[0], s), Math.min(b[1], e))) return false; // overlaps overlapped\n            books.add(new int[]{ s, e });\n            return true;\n        }\n\n        private static class MyCalendar {\n            List<int[]> books = new ArrayList<>();\n            public boolean book(int start, int end) {\n                for (int[] b : books)\n                    if (Math.max(b[0], start) < Math.min(b[1], end)) return false;\n                books.add(new int[]{ start, end });\n                return true;\n            }\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/my-calendar-ii/solution/\n     */\n    class MyCalendarTwo2 {\n        List<int[]> calendar;\n        List<int[]> overlaps;\n    \n        MyCalendarTwo() {\n            calendar = new ArrayList();\n            overlaps = new ArrayList();\n        }\n    \n        public boolean book(int start, int end) {\n            for (int[] iv: overlaps) {\n                if (iv[0] < end && start < iv[1]) return false;\n            }\n            for (int[] iv: calendar) {\n                if (iv[0] < end && start < iv[1])\n                    overlaps.add(new int[]{Math.max(start, iv[0]), Math.min(end, iv[1])});\n            }\n            calendar.add(new int[]{start, end});\n            return true;\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/my-calendar-ii/solution/\n     */\n    class MyCalendarTwo3 {\n        TreeMap<Integer, Integer> delta;\n    \n        public MyCalendarTwo() {\n            delta = new TreeMap();\n        }\n    \n        public boolean book(int start, int end) {\n            delta.put(start, delta.getOrDefault(start, 0) + 1);\n            delta.put(end, delta.getOrDefault(end, 0) - 1);\n    \n            int active = 0;\n            for (int d: delta.values()) {\n                active += d;\n                if (active >= 3) {\n                    delta.put(start, delta.get(start) - 1);\n                    delta.put(end, delta.get(end) + 1);\n                    if (delta.get(start) == 0)\n                        delta.remove(start);\n                    return false;\n                }\n            }\n            return true;\n        }\n    }\n\n}\n\n"
  },
  {
    "path": "src/NQueens51.java",
    "content": "/**\n * The n-queens puzzle is the problem of placing n queens on an nxn chessboard\n * such that no two queens attack each other.\n *\n *\n *\n *\n * Given an integer n, return all distinct solutions to the n-queens puzzle.\n *\n * Each solution contains a distinct board configuration of the n-queens'\n * placement, where 'Q' and '.' both indicate a queen and an empty space\n * respectively.\n *\n * For example,\n *\n * There exist two distinct solutions to the 4-queens puzzle:\n *\n * [\n *  [\".Q..\",  // Solution 1\n *   \"...Q\",\n *   \"Q...\",\n *   \"..Q.\"],\n *\n *  [\"..Q.\",  // Solution 2\n *   \"Q...\",\n *   \"...Q\",\n *   \".Q..\"]\n * ]\n */\n\n\nimport java.util.Arrays;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.HashSet;\nimport java.util.Set;\n\n\npublic class NQueens51 {\n    // so slow\n    public List<List<String>> solveNQueens(int n) {\n        List<List<String>> result = new ArrayList<>();\n        if (n < 0) {\n            return result;\n        }\n\n        List<List<Integer>> trace = new ArrayList<>();\n\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                Integer[] now = new Integer[]{i, j};\n                if (attacked(trace, now)) {\n                    if (j == n - 1) {\n                        List<Integer> last = backtrack(trace, i, j, n);\n                        i = last.get(0);\n                        j = last.get(1);\n                        if (i == 0 && j == n - 1) {\n                            return result;\n                        }\n                        break;\n                    }\n                } else {\n                    trace.add(Arrays.asList(now));\n                    if (i == n - 1) {\n                        List<Integer> first = foundOneSolution(result, trace, n);\n                        i = first.get(0);\n                        j = first.get(1);\n                    }\n                    if (i == 0 && j > n - 1) {\n                        return result;\n                    }\n                    break;\n                }\n            }\n        }\n\n        return result;\n    }\n\n    private List<Integer> backtrack(List<List<Integer>> trace, int inputI, int inputJ, int n) {\n        int i = inputI;\n        int j = inputJ;\n\n        if (trace.size() == 0) {\n            return new ArrayList<Integer>(Arrays.asList(i, j));\n        }\n\n        List<Integer> last = trace.get(trace.size() - 1);\n        trace.remove(last);\n\n\n        if (last.get(1) < n - 1 && !attacked(trace, new Integer[]{last.get(0), last.get(1) + 1})) {\n            last.set(1, last.get(1) + 1);\n            trace.add(last);\n            i = i - 1;\n            j = 0;\n        } else if (last.get(1) < n - 1) {\n            int a = last.get(0);\n            int b = last.get(1) + 2;\n            while (b <= n - 1 && attacked(trace, new Integer[]{a, b})) {\n                b++;\n            }\n            if (b > n - 1) {\n                List<Integer> back = backtrack(trace, a, n - 1, n);\n                i = back.get(0);\n                j = back.get(1);\n            } else {\n                trace.add(Arrays.asList(a, b));\n                i = i - 1;\n                j = 0;\n            }\n        } else {\n            List<Integer> back = backtrack(trace, last.get(0), last.get(1), n);\n            i = back.get(0);\n            j = back.get(1);\n        }\n\n        return new ArrayList<Integer>(Arrays.asList(i, j));\n    }\n\n    private List<Integer> foundOneSolution(List<List<String>> result, List<List<Integer>> trace, int n) {\n        String[][] board = new String[n][n];\n        for(String[] row: board){\n            Arrays.fill(row, \".\");\n        }\n\n        for (List<Integer> queen: trace) {\n            board[queen.get(0)][queen.get(1)] = \"Q\";\n        }\n\n        List<String> solution = new ArrayList<>();\n        for(String[] row: board){\n            solution.add(String.join(\"\", row));\n        }\n        result.add(solution);\n\n\n        List<Integer> last = trace.get(trace.size() - 1);\n        trace.remove(last);\n\n        last.set(1, last.get(1) + 1);\n        trace.add(last);\n\n        return new ArrayList<Integer>(Arrays.asList(last.get(0) - 1, 0));\n    }\n\n    private boolean attacked(List<List<Integer>> trace, Integer[] point) {\n        Integer x = point[0];\n        Integer y = point[1];\n        for (List<Integer> qPoint: trace) {\n            Integer qx = qPoint.get(0);\n            Integer qy = qPoint.get(1);\n\n            if (x.equals(qx) || y.equals(qy) || Math.abs(x - qx) == Math.abs(y - qy)) {\n              return true;\n            }\n        }\n        return false;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/8592/comparably-concise-java-code\n     */\n    private void helper(int r, boolean[] cols, boolean[] d1, boolean[] d2, String[] board, List<List<String>> res) {\n        if (r == board.length) {\n            res.add(Arrays.asList(board.clone()));\n        } else {\n            for (int c = 0; c < board.length; c++) {\n                int id1 = r - c + board.length, id2 = 2*board.length - r - c - 1;\n                if (!cols[c] && !d1[id1] && !d2[id2]) {\n                    char[] row = new char[board.length];\n                    Arrays.fill(row, '.'); row[c] = 'Q';\n                    board[r] = new String(row);\n                    cols[c] = true; d1[id1] = true; d2[id2] = true;\n                    helper(r+1, cols, d1, d2, board, res);\n                    cols[c] = false; d1[id1] = false; d2[id2] = false;\n                }\n            }\n        }\n    }\n\n    public List<List<String>> solveNQueens2(int n) {\n        List<List<String>> res = new ArrayList<>();\n        helper(0, new boolean[n], new boolean[2*n], new boolean[2*n], new String[n], res);\n        return res;\n    }\n\n\n    public static void main(String[] args) {\n        NQueens51 nq = new NQueens51();\n\n        System.out.println(\"---- 1\");\n        System.out.println(nq.solveNQueens(1));\n        System.out.println(\"---- 4\");\n        System.out.println(nq.solveNQueens(4));\n        System.out.println(\"---- 2\");\n        System.out.println(nq.solveNQueens(2));\n        System.out.println(\"---- 3\");\n        System.out.println(nq.solveNQueens(3));\n        System.out.println(\"---- 5\");\n        System.out.println(nq.solveNQueens(5));\n        System.out.println(\"---- 6\");\n        System.out.println(nq.solveNQueens(6));\n    }\n}\n"
  },
  {
    "path": "src/NQueensII52.java",
    "content": "/**\n * Follow up for N-Queens problem.\n *\n * Now, instead outputting board configurations, return the total number of\n * distinct solutions.\n */\n\n\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.Map;\n\n\npublic class NQueensII52 {\n    private void helper(int r, boolean[] cols, boolean[] d1, boolean[] d2, int n, Map<String, Integer> res) {\n        if (r == n) {\n            res.put(\"num\", res.get(\"num\") + 1);\n        } else {\n            for (int c = 0; c < n; c++) {\n                int id1 = r - c + n, id2 = 2*n - r - c - 1;\n                if (!cols[c] && !d1[id1] && !d2[id2]) {\n                    cols[c] = true; d1[id1] = true; d2[id2] = true;\n                    helper(r+1, cols, d1, d2, n, res);\n                    cols[c] = false; d1[id1] = false; d2[id2] = false;\n                }\n            }\n        }\n    }\n\n    public int totalNQueens(int n) {\n        Map<String, Integer> res = new HashMap<>();\n        res.put(\"num\", 0);\n        helper(0, new boolean[n], new boolean[2*n], new boolean[2*n], n, res);\n        return res.get(\"num\");\n    }\n\n\n    public static void main(String[] args) {\n        NQueensII52 nq = new NQueensII52();\n\n        System.out.println(\"---- 1\");\n        System.out.println(nq.totalNQueens(1));\n        System.out.println(\"---- 4\");\n        System.out.println(nq.totalNQueens(4));\n        System.out.println(\"---- 2\");\n        System.out.println(nq.totalNQueens(2));\n        System.out.println(\"---- 3\");\n        System.out.println(nq.totalNQueens(3));\n        System.out.println(\"---- 5\");\n        System.out.println(nq.totalNQueens(5));\n        System.out.println(\"---- 6\");\n        System.out.println(nq.totalNQueens(6));\n    }\n}\n"
  },
  {
    "path": "src/NaryTreeLevelOrderTraversal429.java",
    "content": "/**\n * Given an n-ary tree, return the level order traversal of its nodes' values.\n * (ie, from left to right, level by level).\n * \n * For example, given a 3-ary tree:\n * https://leetcode.com/static/images/problemset/NaryTreeExample.png\n * \n * We should return its level order traversal:\n * \n * [\n *      [1],\n *      [3,2,4],\n *      [5,6]\n * ]\n * \n * Note:\n * The depth of the tree is at most 1000.\n * The total number of nodes is at most 5000.\n */\n\n/*\n// Definition for a Node.\nclass Node {\n    public int val;\n    public List<Node> children;\n\n    public Node() {}\n\n    public Node(int _val,List<Node> _children) {\n        val = _val;\n        children = _children;\n    }\n};\n*/\n\npublic class NaryTreeLevelOrderTraversal429 {\n    public List<List<Integer>> levelOrder(Node root) {\n        List<List<Integer>> res = new ArrayList<>();\n        if (root == null) return res;\n        Queue<Node> q = new LinkedList<>();\n        q.add(root);\n        while (!q.isEmpty()) {\n            int size = q.size();\n            List<Integer> level = new ArrayList<>();\n            for (int i=0; i<size; i++) {\n                Node curr = q.poll();\n                level.add(curr.val);\n                for (Node n: curr.children) {\n                    q.add(n);\n                }\n            }\n            res.add(level);\n        }\n        \n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/NaryTreePostorderTraversal590.java",
    "content": "/**\n * Given an n-ary tree, return the postorder traversal of its nodes' values.\n * \n * For example, given a 3-ary tree:\n * https://leetcode.com/static/images/problemset/NaryTreeExample.png\n * \n * Return its postorder traversal as: [5,6,3,2,4,1].\n * \n * Note: Recursive solution is trivial, could you do it iteratively?\n */\n\n/*\n// Definition for a Node.\nclass Node {\n    public int val;\n    public List<Node> children;\n\n    public Node() {}\n\n    public Node(int _val,List<Node> _children) {\n        val = _val;\n        children = _children;\n    }\n};\n*/\n\npublic class NaryTreePostorderTraversal590 {\n    public List<Integer> postorder(Node root) {\n        List<Integer> res = new ArrayList<>();\n        helper(root, res);\n        return res;\n    }\n\n    private void helper(Node root, List<Integer> res) {\n        if (root == null) return;\n        for (Node child: root.children) {\n            helper(child, res);\n        }\n        res.add(root.val);\n    }\n\n\n    public List<Integer> postorder2(Node root) {\n        LinkedList<Integer> res = new LinkedList<>();\n        if (root == null) return res;\n        Stack<Node> stack = new Stack<>();\n        stack.push(root);\n        while (!stack.isEmpty()) {\n            Node curr = stack.pop();\n            res.addFirst(curr.val);\n            for (Node child: curr.children) {\n                stack.add(child);\n            }\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/NestedIterator.java",
    "content": "/**\n * Given a nested list of integers, implement an iterator to flatten it.\n *\n * Each element is either an integer, or a list -- whose elements may also be\n * integers or other lists.\n *\n * Example 1:\n * Given the list [[1,1],2,[1,1]],\n *\n * By calling next repeatedly until hasNext returns false, the order of elements\n * returned by next should be: [1,1,2,1,1].\n *\n * Example 2:\n * Given the list [1,[4,[6]]],\n *\n * By calling next repeatedly until hasNext returns false, the order of elements\n * returned by next should be: [1,4,6].\n *\n */\n\n/**\n * // This is the interface that allows for creating nested lists.\n * // You should not implement it, or speculate about its implementation\n * public interface NestedInteger {\n *\n *     // @return true if this NestedInteger holds a single integer, rather than a nested list.\n *     public boolean isInteger();\n *\n *     // @return the single integer that this NestedInteger holds, if it holds a single integer\n *     // Return null if this NestedInteger holds a nested list\n *     public Integer getInteger();\n *\n *     // @return the nested list that this NestedInteger holds, if it holds a nested list\n *     // Return null if this NestedInteger holds a single integer\n *     public List<NestedInteger> getList();\n * }\n */\npublic class NestedIterator implements Iterator<Integer> {\n    Queue<Integer> q = new LinkedList<>();\n\n    public NestedIterator(List<NestedInteger> nestedList) {\n        flattenNestedList(nestedList);\n    }\n\n    private void flattenNestedList(List<NestedInteger> nestedList) {\n        for (NestedInteger ni: nestedList) {\n            if (ni.isInteger()) {\n                q.add(ni.getInteger());\n            } else {\n                flattenNestedList(ni.getList());\n            }\n        }\n    }\n\n    @Override\n    public Integer next() {\n        return q.remove();\n    }\n\n    @Override\n    public boolean hasNext() {\n        return !q.isEmpty();\n    }\n}\n\n/*\npublic class NestedIterator implements Iterator<Integer> {\n    Stack<NestedInteger> stack = new Stack<>();\n    public NestedIterator(List<NestedInteger> nestedList) {\n        for(int i = nestedList.size() - 1; i >= 0; i--) {\n            stack.push(nestedList.get(i));\n        }\n    }\n\n    @Override\n    public Integer next() {\n        return stack.pop().getInteger();\n    }\n\n    @Override\n    public boolean hasNext() {\n        while(!stack.isEmpty()) {\n            NestedInteger curr = stack.peek();\n            if(curr.isInteger()) {\n                return true;\n            }\n            stack.pop();\n            for(int i = curr.getList().size() - 1; i >= 0; i--) {\n                stack.push(curr.getList().get(i));\n            }\n        }\n        return false;\n    }\n}\n*/\n\n/**\n * Your NestedIterator object will be instantiated and called as such:\n * NestedIterator i = new NestedIterator(nestedList);\n * while (i.hasNext()) v[f()] = i.next();\n */\n"
  },
  {
    "path": "src/NestedListWeightSum339.java",
    "content": "/**\n * Given a nested list of integers, return the sum of all integers in the list\n * weighted by their depth.\n * \n * Each element is either an integer, or a list -- whose elements may also be\n * integers or other lists.\n * \n * Example 1:\n * Input: [[1,1],2,[1,1]]\n * Output: 10 \n * Explanation: Four 1's at depth 2, one 2 at depth 1.\n * \n * Example 2:\n * Input: [1,[4,[6]]]\n * Output: 27 \n * Explanation: One 1 at depth 1, one 4 at depth 2, and one 6 at depth 3;\n * 1 + 4*2 + 6*3 = 27.\n */\n\n/**\n * // This is the interface that allows for creating nested lists.\n * // You should not implement it, or speculate about its implementation\n * public interface NestedInteger {\n *     // Constructor initializes an empty nested list.\n *     public NestedInteger();\n *\n *     // Constructor initializes a single integer.\n *     public NestedInteger(int value);\n *\n *     // @return true if this NestedInteger holds a single integer, rather than a nested list.\n *     public boolean isInteger();\n *\n *     // @return the single integer that this NestedInteger holds, if it holds a single integer\n *     // Return null if this NestedInteger holds a nested list\n *     public Integer getInteger();\n *\n *     // Set this NestedInteger to hold a single integer.\n *     public void setInteger(int value);\n *\n *     // Set this NestedInteger to hold a nested list and adds a nested integer to it.\n *     public void add(NestedInteger ni);\n *\n *     // @return the nested list that this NestedInteger holds, if it holds a nested list\n *     // Return null if this NestedInteger holds a single integer\n *     public List<NestedInteger> getList();\n * }\n */\n\npublic class NestedListWeightSum339 {\n    public int depthSum(List<NestedInteger> nestedList) {\n        return depthSum(nestedList, 1);\n    }\n\n    private int depthSum(List<NestedInteger> nestedList, int level) {\n        int res = 0;\n        for (NestedInteger ni: nestedList) {\n            if (ni.isInteger()) {\n                res += ni.getInteger() * level;\n            } else {\n                res += depthSum(ni.getList(), level + 1);\n            }\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/NextClosestTime681.java",
    "content": "/**\n * Given a time represented in the format \"HH:MM\", form the next closest time\n * by reusing the current digits. There is no limit on how many times a digit\n * can be reused.\n * \n * You may assume the given input string is always valid. For example, \"01:34\",\n * \"12:09\" are all valid. \"1:34\", \"12:9\" are all invalid.\n * \n * Example 1:\n * \n * Input: \"19:34\"\n * Output: \"19:39\"\n * Explanation: The next closest time choosing from digits 1, 9, 3, 4, is 19:39,\n * which occurs 5 minutes later.  It is not 19:33, because this occurs 23 hours\n * and 59 minutes later.\n * \n * Example 2:\n * \n * Input: \"23:59\"\n * Output: \"22:22\"\n * Explanation: The next closest time choosing from digits 2, 3, 5, 9, is 22:22.\n * It may be assumed that the returned time is next day's time since it is\n * smaller than the input time numerically.\n */\n\n\npublic class NextClosestTime681 {\n    public String nextClosestTime(String time) {\n        int hours = Integer.valueOf(time.substring(0, 2));\n        int mins = Integer.valueOf(time.substring(3, 5));\n        int allmins = hours * 60 + mins;\n        boolean[] set = new boolean[10];\n        for (char c: time.toCharArray()) {\n            if (c != ':') {\n                set[c - '0'] = true;\n            }\n        }\n        \n        while (true) {\n            allmins = (allmins + 1) % (24 * 60);\n            int currHours = allmins / 60;\n            int a = currHours / 10;\n            if (!set[a]) continue;\n            int b = currHours % 10;\n            if (!set[b]) continue;\n            int currMins = allmins % 60;\n            int c = currMins / 10;\n            if (!set[c]) continue;\n            int d = currMins % 10;\n            if (!set[d]) continue;\n            return String.format(\"%d%d:%d%d\", a, b, c, d);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/next-closest-time/solution/\n     */\n    public String nextClosestTime2(String time) {\n        int start = 60 * Integer.parseInt(time.substring(0, 2));\n        start += Integer.parseInt(time.substring(3));\n        int ans = start;\n        int elapsed = 24 * 60;\n        Set<Integer> allowed = new HashSet();\n        for (char c: time.toCharArray()) if (c != ':') {\n            allowed.add(c - '0');\n        }\n\n        for (int h1: allowed) for (int h2: allowed) if (h1 * 10 + h2 < 24) {\n            for (int m1: allowed) for (int m2: allowed) if (m1 * 10 + m2 < 60) {\n                int cur = 60 * (h1 * 10 + h2) + (m1 * 10 + m2);\n                int candElapsed = Math.floorMod(cur - start, 24 * 60);\n                if (0 < candElapsed && candElapsed < elapsed) {\n                    ans = cur;\n                    elapsed = candElapsed;\n                }\n            }\n        }\n\n        return String.format(\"%02d:%02d\", ans / 60, ans % 60);\n    }\n\n\n}\n"
  },
  {
    "path": "src/NextGreaterElementI496.java",
    "content": "/**\n * You are given two arrays (without duplicates) nums1 and nums2 where nums1’s\n * elements are subset of nums2. Find all the next greater numbers for nums1's\n * elements in the corresponding places of nums2.\n * \n * The Next Greater Number of a number x in nums1 is the first greater number\n * to its right in nums2. If it does not exist, output -1 for this number.\n * \n * Example 1:\n * Input: nums1 = [4,1,2], nums2 = [1,3,4,2].\n * Output: [-1,3,-1]\n * Explanation:\n *     For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1.\n *     For number 1 in the first array, the next greater number for it in the second array is 3.\n *     For number 2 in the first array, there is no next greater number for it in the second array, so output -1.\n * \n * Example 2:\n * Input: nums1 = [2,4], nums2 = [1,2,3,4].\n * Output: [3,-1]\n * Explanation:\n *     For number 2 in the first array, the next greater number for it in the second array is 3.\n *     For number 4 in the first array, there is no next greater number for it in the second array, so output -1.\n * \n * Note:\n * All elements in nums1 and nums2 are unique.\n * The length of both nums1 and nums2 would not exceed 1000.\n */\n\npublic class NextGreaterElementI496 {\n    public int[] nextGreaterElement(int[] nums1, int[] nums2) {\n        if (nums1 == null || nums1.length == 0) return new int[0];\n        int[] res = new int[nums1.length];\n        Map<Integer, Integer> map = new HashMap<>();\n        Stack<Integer> stack = new Stack<>();\n        for (int i=0; i<nums2.length; i++) {\n            if (stack.isEmpty() || stack.peek() >= nums2[i]) {\n                stack.push(nums2[i]);\n                continue;\n            }\n            \n            while (!stack.isEmpty() && stack.peek() < nums2[i]) {\n                map.put(stack.pop(), nums2[i]);\n            }\n            stack.push(nums2[i]);\n        }\n        \n        for (int i=0; i<nums1.length; i++) {\n            res[i] = map.getOrDefault(nums1[i], -1);\n        } \n        return res;\n    }\n}\n"
  },
  {
    "path": "src/NextGreaterElementII503.java",
    "content": "/**\n * Given a circular array (the next element of the last element is the first\n * element of the array), print the Next Greater Number for every element. The\n * Next Greater Number of a number x is the first greater number to its\n * traversing-order next in the array, which means you could search circularly\n * to find its next greater number. If it doesn't exist, output -1 for this\n * number.\n * \n * Example 1:\n * Input: [1,2,1]\n * Output: [2,-1,2]\n * \n * Explanation: The first 1's next greater number is 2; \n * The number 2 can't find next greater number; \n * The second 1's next greater number needs to search circularly, which is also 2.\n * \n * Note: The length of given array won't exceed 10000.\n */\n\npublic class NextGreaterElementII503 {\n    // brute force\n    public int[] nextGreaterElements(int[] nums) {\n        if (nums == null || nums.length == 0) return nums;\n        if (nums.length == 1) return new int[]{-1};\n        int len = nums.length;\n        \n        int[] res = new int[len];\n        \n        int i = 0;        \n        while (i < len) {\n            int j = (i+1)%len;\n            boolean found = false;\n            while (j != i) {\n                if (nums[j] > nums[i]) {\n                    res[i] = nums[j];\n                    found = true;\n                    break;\n                }\n                j = (j+1)%len;\n            }\n            if (!found) {\n                res[i] = -1;\n            }\n            i++;\n        }\n        \n        return res;\n    }\n\n    public int[] nextGreaterElements2(int[] nums) {\n        if (nums == null || nums.length == 0) return nums;\n        if (nums.length == 1) return new int[]{-1};\n        int len = nums.length;\n        \n        int[] res = new int[len];\n        Arrays.fill(res, -1);\n        Stack<Integer> st = new Stack<>();\n        for (int i=0; i<len; i++) {\n            while (!st.empty() && nums[i] > nums[st.peek()]) {\n                res[st.pop()] = nums[i];\n            }\n            st.push(i);\n        }\n        \n        for (int i=0; i<len; i++) {\n            while (!st.empty() && nums[i] > nums[st.peek()]) {\n                int idx = st.pop();\n                if (res[idx] == -1) {\n                    res[idx] = nums[i];\n                }\n            }\n            st.push(i);\n        }\n\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/next-greater-element-ii/solution/\n     */\n    public int[] nextGreaterElements3(int[] nums) {\n        int[] res = new int[nums.length];\n        Stack<Integer> stack = new Stack<>();\n        for (int i = 2 * nums.length - 1; i >= 0; --i) {\n            while (!stack.empty() && nums[stack.peek()] <= nums[i % nums.length]) {\n                stack.pop();\n            }\n            res[i % nums.length] = stack.empty() ? -1 : nums[stack.peek()];\n            stack.push(i % nums.length);\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/next-greater-element-ii/discuss/130338/Why-need-to-use-a-stack-for-index\n     */\n    public int[] nextGreaterElements4(int[] nums) {\n        Stack<Integer> st = new Stack<>();\n        for (int e = nums.length -1; e >= 0; e --) {\n            st.push(nums[e]);\n        }\n        int[] r = new int[nums.length];\n        for (int i = nums.length -1; i >= 0; i--) {\n            while (!st.isEmpty() && st.peek() <= nums[i]) st.pop();\n            r[i] = st.isEmpty() ? -1 : st.peek();\n            st.push(nums[i]);\n        }\n        return r;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/next-greater-element-ii/discuss/98276/21ms-Java-Solution-beats-99.84-with-comments-and-explanations\n     */\n    public int[] nextGreaterElements5(int[] nums) {\n        if (nums==null||nums.length==0) return new int[0];\n        int maxIndex = 0;\n        for (int i = 0; i < nums.length; i++) {\n            if (nums[i] > nums[maxIndex]) {\n                maxIndex = i;  //find the largest element\n            }\n        }  \n        int[] index = new int[nums.length]; //declare an array that holds the index of next greater element\n        index[maxIndex] = -1; //set the max element's value to -1\n        for (int i = (maxIndex - 1 + nums.length) % nums.length; i != maxIndex; i = (i - 1 + nums.length) % nums.length) { //the array is circular. pay attention to 'i'\n            if (nums[i] < nums[(i + 1) % nums.length]) {\n                index[i] = (i + 1) % nums.length; //set index[i] = (i+1)%nums.length if index[(i+1)%nums.length]>index[i]\n            } else {\n                int res = index[(i + 1 + nums.length) % nums.length]; //res = index of the cloest element whose value greater than nums[(i+1)%nums.length]\n                while (res != -1 && index[res] != -1 && nums[i] >= nums[res]) {  //find the closet index makes nums[index] > nums[i]\n                    res = index[res]; //if nums[i] >= nums[res], try nums[index[res]], index[res] is the index of the closest element whose value is greater than nums[res]. repeat the process until we find such an element. \n                }\n                if (res != -1 && nums[res] == nums[i]) { //res==-1 or index[res]==-1 means current element is another largest element, just set index[i] = -1.\n                    res = -1;\n                }\n                index[i] = res;\n            }\n        }\n        int[] result = new int[nums.length]; // retrieve value with index recorded previously\n        for (int i = 0; i < result.length; i++) {\n            int temp = index[i] != -1 ? nums[index[i]] : -1;\n            result[i] = temp;\n        }\n        return result;\n    }\n\n\n    public int[] nextGreaterElements6(int[] nums) {\n        if (nums == null || nums.length == 0) return new int[]{};\n\n        int len = nums.length;\n        int[] idx = new int[len];\n        Arrays.fill(idx, -1);\n        for (int i=2*len-1; i>=0; i--) {\n            int nextIdx = (i + 1) % len;\n            while (idx[nextIdx] != -1 && nums[nextIdx] <= nums[i % len]) {\n                nextIdx = idx[nextIdx];\n            }\n            if (nums[nextIdx] > nums[i % len]) {\n                idx[i % len] = nextIdx;\n            }\n        }\n        \n        int[] res = new int[len];\n        for (int i=0; i<len; i++) {\n            if (idx[i] == -1) {\n                res[i] = -1;\n            } else {\n                res[i] = nums[idx[i]];\n            }\n        }\n        return res;\n    }\n\n}"
  },
  {
    "path": "src/NextGreaterElementIII556.java",
    "content": "/**\n * Given a positive 32-bit integer n, you need to find the smallest 32-bit\n * integer which has exactly the same digits existing in the integer n and is\n * greater in value than n. If no such positive 32-bit integer exists, you need\n * to return -1.\n * \n * Example 1:\n * Input: 12\n * Output: 21\n *\n * Example 2:\n * Input: 21\n * Output: -1 \n */\n\npublic class NextGreaterElementIII556 {\n    public int nextGreaterElement(int n) {\n        int len = String.valueOf(n).length();\n        int[] digits = new int[len];\n        int p = n;\n        int i = len-1;\n        int pre = p % 10;\n        int mark = -1;\n        while (p != 0) {\n            int now = p % 10;\n            digits[i] = now;\n            if (mark == -1 && now < pre) {\n                int j = i+1;\n                while (j < len && digits[j] > now) j++;\n                swap(digits, i, j-1);\n                mark = i;\n            }\n            pre = now;\n            p = p / 10;\n            i--;\n        }\n        if (mark == -1) return -1;\n        Arrays.sort(digits, mark+1, len);\n        \n        long res = 0;\n        long tens = 1;\n        for (int j=len-1; j>=0; j--) {\n            res += digits[j] * tens;\n            tens = tens * 10;\n        }\n\n        return res > Integer.MAX_VALUE ? -1 : (int) res;\n    }\n\n    private void swap(int[] digits, int i, int j) {\n        int temp = digits[i];\n        digits[i] = digits[j];\n        digits[j] = temp;\n    }\n\n    public int nextGreaterElement2(int n) {\n        int[] digits = new int[10];\n        int k = n;\n        int i = 9;\n        while (k != 0) {\n            digits[i--] = k % 10;\n            k /= 10;\n        }\n        if (i == 8) return -1;\n\n        int j = 8;\n        while (j > i) {\n            if (digits[j] < digits[j+1]) break;\n            j--;\n        }\n        if (j == i) return -1;\n        \n        int p = 9;\n        while (p > j) {\n            if (digits[p] > digits[j]) break;\n            p--;\n        }\n        swap(digits, j, p);\n        Arrays.sort(digits, j+1, 10);\n        \n        long res = 0;\n        long level = 1;\n        for (int q=9; q>=0; q--) {\n            res += digits[q] * level;\n            level *= 10;\n        }\n        return res > Integer.MAX_VALUE ? -1 : (int) res;\n    }\n\n}\n"
  },
  {
    "path": "src/NextPermutation31.java",
    "content": "\n/**\n * Implement next permutation, which rearranges numbers into the\n * lexicographically next greater permutation of numbers.\n *\n * If such arrangement is not possible, it must rearrange it as the lowest\n * possible order (ie, sorted in ascending order).\n *\n * The replacement must be in-place, do not allocate extra memory.\n *\n * Here are some examples. Inputs are in the left-hand column and its\n * corresponding outputs are in the right-hand column.\n *\n * 1,2,3 → 1,3,2\n * 3,2,1 → 1,2,3\n * 1,1,5 → 1,5,1\n *\n */\n\n\npublic class NextPermutation31 {\n    public void nextPermutation(int[] nums) {\n        int n = nums.length - 1;\n        while (n > 0) {\n            if (nums[n-1] < nums[n]) break;\n            n--;\n        }\n        if (n == 0) {\n            Arrays.sort(nums);\n            return;\n        }\n\n        int p = nums.length - 1;\n        int minIdx = nums.length - 1;\n        int minVal = Integer.MAX_VALUE;\n        while (p >= n) {\n            if (nums[p] > nums[n-1]) break;\n            p--;\n        }\n        swap(nums, n-1, p);\n\n        int l = n;\n        int r = nums.length - 1;\n        while (l < r) {\n            swap(nums, l, r);\n            l++;\n            r--;\n        }\n    }\n\n    private void swap(int[] nums, int i, int j) {\n        int temp = nums[i];\n        nums[i] = nums[j];\n        nums[j] = temp;\n    }\n\n}\n"
  },
  {
    "path": "src/NonDecreasingArray665.java",
    "content": "/**\n * Given an array with n integers, your task is to check if it could become\n * non-decreasing by modifying at most 1 element.\n * \n * We define an array is non-decreasing if array[i] <= array[i + 1] holds for\n * every i (1 <= i < n).\n * \n * Example 1:\n * Input: [4,2,3]\n * Output: True\n * Explanation: You could modify the first 4 to 1 to get a non-decreasing array.\n * \n * Example 2:\n * Input: [4,2,1]\n * Output: False\n * Explanation: You can't get a non-decreasing array by modify at most one element.\n * \n * Note: The n belongs to [1, 10,000].\n */\n\npublic class NonDecreasingArray665 {\n    public boolean checkPossibility(int[] nums) {\n        if (nums == null || nums.length <= 2) return true;\n        int min = nums[nums.length-1];\n        int n1 = 0;\n        for (int i=nums.length-2; i>=0; i--) {\n            if (min < nums[i]) {\n                n1++;\n                if (n1 == 2) break;\n            } else {\n                min = nums[i];\n            }\n        }\n        if (n1 < 2) return true;\n        \n        int max = nums[0];\n        int n2 = 0;\n        for (int i=1; i<nums.length; i++) {\n            if (max > nums[i]) {\n                n2++;\n                if (n2 == 2) return false;\n            } else {\n                max = nums[i];\n            }\n        }\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/non-decreasing-array/discuss/106849/C++-Java-Clean-Code-6-liner-Without-Modifying-Input\n     */\n    public boolean checkPossibility2(int[] a) {\n        int modified = 0;\n        for (int i = 1, prev = a[0]; i < a.length; i++) {\n            if (a[i] < prev) {\n                if (modified++ > 0) return false;\n                if (i - 2 >= 0 && a[i - 2] > a[i]) continue;\n            }\n            prev = a[i];\n        }\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/non-decreasing-array/solution/\n     */\n    public boolean checkPossibility3(int[] a) {\n        int p = -1;\n        for (int i = 0; i<a.length-1; i++) {\n            if (a[i] > a[i+1]) {\n                if (p != -1) return false;\n                p = i;\n            }\n        }\n        return (p == -1 || p == 0 || p == a.length-2 || a[p-1] <= a[p+1] || a[p] <= a[p+2]);\n    }\n\n}\n"
  },
  {
    "path": "src/NonOverlappingIntervals435.java",
    "content": "/**\n * Given a collection of intervals, find the minimum number of intervals you\n * need to remove to make the rest of the intervals non-overlapping.\n * \n * Note:\n * You may assume the interval's end point is always bigger than its start point.\n * Intervals like [1,2] and [2,3] have borders \"touching\" but they don't\n * overlap each other.\n * \n * Example 1:\n * Input: [ [1,2], [2,3], [3,4], [1,3] ]\n * Output: 1\n * Explanation: [1,3] can be removed and the rest of intervals are\n * non-overlapping.\n * \n * Example 2:\n * Input: [ [1,2], [1,2], [1,2] ]\n * Output: 2\n * Explanation: You need to remove two [1,2] to make the rest of intervals\n * non-overlapping.\n * \n * Example 3:\n * Input: [ [1,2], [2,3] ]\n * Output: 0\n * Explanation: You don't need to remove any of the intervals since they're\n * already non-overlapping.\n */\n\npublic class NonOverlappingIntervals435 {\n\n    private static Comparator<Interval> comp = new Comparator<Interval>() {\n        @Override\n        public int compare(Interval i1, Interval i2) {\n            int diff = Integer.compare(i1.start, i2.start);\n            if (diff != 0) return diff;\n            return Integer.compare(i2.end-i2.start, i1.end-i1.start);\n        }\n    };\n\n    public int eraseOverlapIntervals(Interval[] intervals) {\n        if (intervals == null || intervals.length == 0) return 0;\n        Arrays.sort(intervals, comp);\n        Interval inv = intervals[0];\n        int res = 0;\n        for (int i=1; i<intervals.length; i++) {\n            Interval curr = intervals[i];\n            if (curr.start == inv.start) {\n                inv = curr;\n                res++;\n            } else if (curr.start < inv.end) {\n                if (curr.end < inv.end) {\n                    inv = curr;\n                }\n                res++;\n            } else {\n                inv = curr;\n            }\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/NumberOfConnectedComponentsInAnUndirectedGraph323.java",
    "content": "/**\n * Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each\n * edge is a pair of nodes), write a function to find the number of connected\n * components in an undirected graph.\n * \n * Example 1:\n * Input: n = 5 and edges = [[0, 1], [1, 2], [3, 4]]\n *      0          3\n *      |          |\n *      1 --- 2    4 \n * Output: 2\n * \n * Example 2:\n * Input: n = 5 and edges = [[0, 1], [1, 2], [2, 3], [3, 4]]\n *      0           4\n *      |           |\n *      1 --- 2 --- 3\n * Output:  1\n * \n * Note:\n * You can assume that no duplicate edges will appear in edges. Since all\n * edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear\n * together in edges.\n */\n\npublic class NumberOfConnectedComponentsInAnUndirectedGraph323 {\n    public int countComponents(int n, int[][] edges) {\n        if (n <= 0) return 0;\n        if (edges == null || edges.length == 0) return n;\n        UnionFind uf = new UnionFind(n);\n        int res = n;\n        for (int[] e: edges) {\n            int pa = uf.find(e[0]);\n            int pb = uf.find(e[1]);\n            if (pa != pb) res--;\n            uf.union(e[0], e[1]);\n        }\n        return res;\n    }\n\n    class UnionFind {\n        int[] parent;\n        int[] rank;\n\n        UnionFind(int n) {\n            this.parent = new int[n];\n            for (int i=0; i<n; i++) this.parent[i] = i;\n            this.rank = new int[n];\n        }\n\n        int find(int x) {\n            if (this.parent[x] != x) {\n                this.parent[x] = find(this.parent[x]);\n            }\n            return this.parent[x];\n        }\n\n        void union(int x, int y) {\n            int px = find(x);\n            int py = find(y);\n            if (px == py) return;\n            \n            if (this.rank[px] < this.rank[py]) {\n                this.parent[px] = py;\n            } else if (this.rank[px] > this.rank[py]) {\n                this.parent[py] = px;\n            } else {\n                this.parent[py] = px;\n                this.rank[px]++;\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/NumberOfCornerRectangles750.java",
    "content": "/**\n * Given a grid where each entry is only 0 or 1, find the number of corner\n * rectangles.\n * \n * A corner rectangle is 4 distinct 1s on the grid that form an axis-aligned\n * rectangle. Note that only the corners need to have the value 1. Also, all\n * four 1s used must be distinct.\n * \n * Example 1:\n * Input: grid = \n * [[1, 0, 0, 1, 0],\n *  [0, 0, 1, 0, 1],\n *  [0, 0, 0, 1, 0],\n *  [1, 0, 1, 0, 1]]\n * Output: 1\n * Explanation: There is only one corner rectangle, with corners\n * grid[1][2], grid[1][4], grid[3][2], grid[3][4].\n * \n * Example 2:\n * Input: grid = \n * [[1, 1, 1],\n *  [1, 1, 1],\n *  [1, 1, 1]]\n * Output: 9\n * Explanation: There are four 2x2 rectangles, four 2x3 and 3x2 rectangles,\n * and one 3x3 rectangle.\n * \n * Example 3:\n * Input: grid = \n * [[1, 1, 1, 1]]\n * Output: 0\n * Explanation: Rectangles must have four distinct corners.\n * \n * Note:\n * The number of rows and columns of grid will each be in the range [1, 200].\n * Each grid[i][j] will be either 0 or 1.\n * The number of 1s in the grid will be at most 6000.\n */\n\npublic class NumberOfCornerRectangles750 {\n    public int countCornerRectangles(int[][] grid) {\n        int M = grid.length;\n        int N = grid[0].length;\n        int res = 0;\n        for (int i=0; i<M-1; i++) {\n            for (int j=0; j<N-1; j++) {\n                if (grid[i][j] == 0) continue;\n                for (int p=i+1; p<M; p++) {\n                    if (grid[p][j] == 0) continue;\n                    for (int q=j+1; q<N; q++) {\n                        if (grid[i][q] == 0) continue;\n                        if (grid[p][q] == 1) res++;\n                    }\n                }\n            }\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/number-of-corner-rectangles/solution/\n     */\n    public int countCornerRectangles2(int[][] grid) {\n        Map<Integer, Integer> count = new HashMap();\n        int ans = 0;\n        for (int[] row: grid) {\n            for (int c1 = 0; c1 < row.length; ++c1) if (row[c1] == 1) {\n                for (int c2 = c1+1; c2 < row.length; ++c2) if (row[c2] == 1) {\n                    int pos = c1 * 200 + c2;\n                    int c = count.getOrDefault(pos, 0);\n                    ans += c;\n                    count.put(pos, c+1);\n                }\n            }\n        }\n        return ans;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/number-of-corner-rectangles/discuss/110196/short-JAVA-AC-solution-(O(m2-*-n))-with-explanation.\n     */\n    public int countCornerRectangles3(int[][] grid) {\n        int ans = 0;\n        for (int i = 0; i < grid.length - 1; i++) {\n            for (int j = i + 1; j < grid.length; j++) {\n                int counter = 0;\n                for (int k = 0; k < grid[0].length; k++) {\n                    if (grid[i][k] == 1 && grid[j][k] == 1) counter++;\n                }\n                if (counter > 0) ans += counter * (counter - 1) / 2;\n            }\n        }\n        return ans;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/number-of-corner-rectangles/discuss/110200/Summary-of-three-solutions-based-on-three-different-ideas\n     */\n    public int countCornerRectangles4(int[][] grid) {\n        int m = grid.length, n = grid[0].length, res = 0;\n        \n        int[][] dp = new int[n][n];\n        \n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < n; j++) {\n                if (grid[i][j] == 0) continue;\n                \n                for (int q = j + 1; q < n; q++) {\n                    if (grid[i][q] == 0) continue;\n                    res += dp[j][q]++;\n                }\n            }\n        }\n        \n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/NumberOfDigitOne233.java",
    "content": "/**\n * Given an integer n, count the total number of digit 1 appearing in all\n * non-negative integers less than or equal to n.\n *\n * For example:\n * Given n = 13,\n * Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.\n */\n\npublic class NumberOfDigitOne233 {\n    public int countDigitOne(int n) {\n        if (n < 1) return 0;\n        int result = 0;\n        int i = 1;\n        int preK = 0;\n        int k = n%10;\n        int num = n/10;\n        while (num != 0) {\n            result += currentOne(n, k, preK, num, i);\n\n            i = i*10;\n            preK = k;\n            k = num%10;\n            num = num/10;\n        }\n\n        // do last once!!!\n        result += currentOne(n, k, preK, num, i);\n\n        return result;\n    }\n\n\n    private int currentOne(int n, int k, int preK, int num, int i) {\n        if (k < 1) return num*i;\n        if (k > 1) return (num+1)*i;\n        return num*i + n%i + 1;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/18054/4-lines-o-log-n-c-java-python\n     */\n    public int countDigitOne2(int n) {\n        int ones = 0;\n        for (long m = 1; m <= n; m *= 10)\n            ones += (n/m + 8) / 10 * m + (n/m % 10 == 1 ? n%m + 1 : 0);\n        return ones;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/18054/4-lines-o-log-n-c-java-python\n     */\n    public int countDigitOne3(int n) {\n        int ones = 0, m = 1, r = 1;\n        while (n > 0) {\n            ones += (n + 8) / 10 * m + (n % 10 == 1 ? r : 0);\n            r += n % 10 * m;\n            m *= 10;\n            n /= 10;\n        }\n        return ones;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/22441/0-ms-recursive-solution\n     */\n    public int countDigitOne4(int n) {\n        if(n<1) return 0;\n        if(n>=1 && n<10) return 1;\n        // x: first digit\n        int y=1, x=n;\n        while(!(x<10)){\n            x/=10;\n            y*=10;\n        }\n        if(x==1)\n            return n-y+1+countDigitOne4(y-1)+countDigitOne4(n%y);\n        else\n            return y+x*countDigitOne4(y-1)+countDigitOne4(n%y);\n    }\n\n}\n"
  },
  {
    "path": "src/NumberOfIslands200.java",
    "content": "/**\n * Given a 2d grid map of '1's (land) and '0's (water), count the number of\n * islands. An island is surrounded by water and is formed by connecting\n * adjacent lands horizontally or vertically. You may assume all four edges\n * of the grid are all surrounded by water.\n *\n * Example 1:\n *\n * 11110\n * 11010\n * 11000\n * 00000\n *\n * Answer: 1\n *\n * Example 2:\n *\n * 11000\n * 11000\n * 00100\n * 00011\n *\n * Answer: 3\n */\n\n\npublic class NumberOfIslands200 {\n    public int numIslands(char[][] grid) {\n        if (grid == null) return 0;\n        int n = grid.length;\n        if (n == 0) return 0;\n        int m = grid[0].length;\n        boolean[][] visited = new boolean[n][m];\n        int res = 0;\n        for (int i=0; i<n; i++) {\n            for (int j=0; j<m; j++) {\n                if (grid[i][j] == '1' && !visited[i][j]) {\n                    numIslands(grid, visited, i, j, n, m);\n                    res++;\n                }\n            }\n        }\n        return res;\n    }\n\n    private void numIslands(char[][] grid, boolean[][] visited, int i, int j, int n, int m) {\n        if (i < 0 || i >= n || j < 0 || j >= m || grid[i][j] == '0' || visited[i][j]) return;\n        visited[i][j] = true;\n        numIslands(grid, visited, i-1, j, n, m);\n        numIslands(grid, visited, i, j+1, n, m);\n        numIslands(grid, visited, i+1, j, n, m);\n        numIslands(grid, visited, i, j-1, n, m);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/number-of-islands/solution/\n     */\n    public int numIslands2(char[][] grid) {\n        if (grid == null || grid.length == 0) {\n            return 0;\n        }\n\n        int nr = grid.length;\n        int nc = grid[0].length;\n        int num_islands = 0;\n        for (int r = 0; r < nr; ++r) {\n            for (int c = 0; c < nc; ++c) {\n                if (grid[r][c] == '1') {\n                    ++num_islands;\n                    dfs(grid, r, c);\n                }\n            }\n        }\n\n        return num_islands;\n    }\n\n    void dfs(char[][] grid, int r, int c) {\n        int nr = grid.length;\n        int nc = grid[0].length;\n\n        if (r < 0 || c < 0 || r >= nr || c >= nc || grid[r][c] == '0') {\n            return;\n        }\n\n        grid[r][c] = '0';\n        dfs(grid, r - 1, c);\n        dfs(grid, r + 1, c);\n        dfs(grid, r, c - 1);\n        dfs(grid, r, c + 1);\n    }\n\n\n\n    public int numIslands3(char[][] grid) {\n        if (grid == null) return 0;\n        int n = grid.length;\n        if (n == 0) return 0;\n        int m = grid[0].length;\n\n        boolean[][] visited = new boolean[n][m];\n\n        int res = 0;\n        for (int i=0; i<n; i++) {\n            for (int j=0; j<m; j++) {\n                if (grid[i][j] == '1' && !visited[i][j]) {\n                    bfs(grid, visited, i, j, n, m);\n                    res++;\n                }\n            }\n        }\n\n        return res;\n    }\n\n    private void bfs(char[][] grid, boolean[][] visited, int i, int j, int n, int m) {\n        Queue<Integer> q = new LinkedList<>();\n        q.add(i * m + j);\n        visited[i][j] = true;\n        while (!q.isEmpty()) {\n            int v = q.remove();\n            int ii = v / m;\n            int jj = v % m;\n            if (ii-1 >= 0 && grid[ii-1][jj] == '1' && !visited[ii-1][jj]) {\n                visited[ii-1][jj] = true;\n                q.add(v-m);\n            }\n            if (jj+1 < m && grid[ii][jj+1] == '1' && !visited[ii][jj+1]) {\n                visited[ii][jj+1] = true;\n                q.add(v+1);\n            }\n            if (ii+1 < n && grid[ii+1][jj] == '1' && !visited[ii+1][jj]) {\n                visited[ii+1][jj] = true;\n                q.add(v+m);\n            }\n            if (jj-1 >= 0 && grid[ii][jj-1] == '1' && !visited[ii][jj-1]) {\n                visited[ii][jj-1] = true;\n                q.add(v-1);\n            }\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/number-of-islands/solution/\n     */\n    class UnionFind {\n      int count; // # of connected components\n      int[] parent;\n      int[] rank;\n\n      public UnionFind(char[][] grid) { // for problem 200\n        count = 0;\n        int m = grid.length;\n        int n = grid[0].length;\n        parent = new int[m * n];\n        rank = new int[m * n];\n        for (int i = 0; i < m; ++i) {\n          for (int j = 0; j < n; ++j) {\n            int val = i * n + j;\n            if (grid[i][j] == '1') {\n              parent[val] = val;\n              ++count;\n            }\n            rank[val] = 0;\n          }\n        }\n      }\n\n      public int find(int i) { // path compression\n        if (parent[i] != i) parent[i] = find(parent[i]);\n        return parent[i];\n      }\n\n      public void union(int x, int y) { // union with rank\n        int rootx = find(x);\n        int rooty = find(y);\n        if (rootx != rooty) {\n          if (rank[rootx] > rank[rooty]) {\n            parent[rooty] = rootx;\n          } else if (rank[rootx] < rank[rooty]) {\n            parent[rootx] = rooty;\n          } else {\n            parent[rooty] = rootx;\n            rank[rootx] += 1;\n          }\n          --count;\n        }\n      }\n\n      public int getCount() {\n        return count;\n      }\n    }\n\n    public int numIslands4(char[][] grid) {\n      if (grid == null || grid.length == 0) {\n        return 0;\n      }\n\n      int nr = grid.length;\n      int nc = grid[0].length;\n      int num_islands = 0;\n      UnionFind uf = new UnionFind(grid);\n      for (int r = 0; r < nr; ++r) {\n        for (int c = 0; c < nc; ++c) {\n          if (grid[r][c] == '1') {\n            int val = r * nc + c;\n            grid[r][c] = '0';\n            if (r - 1 >= 0 && grid[r-1][c] == '1') {\n              uf.union(val, val - nc);\n            }\n            if (r + 1 < nr && grid[r+1][c] == '1') {\n              uf.union(val, val + nc);\n            }\n            if (c - 1 >= 0 && grid[r][c-1] == '1') {\n              uf.union(val, val - 1);\n            }\n            if (c + 1 < nc && grid[r][c+1] == '1') {\n              uf.union(val, val + 1);\n            }\n          }\n        }\n      }\n\n      return uf.getCount();\n    }\n\n}\n"
  },
  {
    "path": "src/NumberOfIslandsII305.java",
    "content": "/**\n * A 2d grid map of m rows and n columns is initially filled with water. We may\n * perform an addLand operation which turns the water at position (row, col)\n * into a land. Given a list of positions to operate, count the number of\n * islands after each addLand operation. An island is surrounded by water and\n * is formed by connecting adjacent lands horizontally or vertically. You may\n * assume all four edges of the grid are all surrounded by water.\n * \n * Example:\n * Input: m = 3, n = 3, positions = [[0,0], [0,1], [1,2], [2,1]]\n * Output: [1,1,2,3]\n * \n * Explanation:\n * Initially, the 2d grid grid is filled with water. (Assume 0 represents water\n * and 1 represents land).\n * \n * 0 0 0\n * 0 0 0\n * 0 0 0\n * Operation #1: addLand(0, 0) turns the water at grid[0][0] into a land.\n * \n * 1 0 0\n * 0 0 0   Number of islands = 1\n * 0 0 0\n * Operation #2: addLand(0, 1) turns the water at grid[0][1] into a land.\n * \n * 1 1 0\n * 0 0 0   Number of islands = 1\n * 0 0 0\n * Operation #3: addLand(1, 2) turns the water at grid[1][2] into a land.\n * \n * 1 1 0\n * 0 0 1   Number of islands = 2\n * 0 0 0\n * Operation #4: addLand(2, 1) turns the water at grid[2][1] into a land.\n * \n * 1 1 0\n * 0 0 1   Number of islands = 3\n * 0 1 0\n * \n * Follow up:\n * Can you do it in time complexity O(k log mn), where k is the length of the\n * positions?\n */\n\n\npublic class NumberOfIslandsII305 {\n    private int[][] dirs = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n    // time complexity too high\n    public List<Integer> numIslands2(int m, int n, int[][] positions) {\n        int[][] grid = new int[m][n];\n        List<Integer> res = new ArrayList<>();\n        \n        int num = 0;\n        for (int[] pos: positions) {\n            num += addNumIslands(grid, pos[0], pos[1], m, n);\n            res.add(num);\n            grid[pos[0]][pos[1]] = 1;\n        }\n        \n        return res;\n    }\n\n    private int addNumIslands(int[][] grid, int i, int j, int m, int n) {\n        int neighbors = 0;\n        boolean[][] visited = new boolean[m][n];\n        for (int[] d: dirs) {\n            if (isNeighbor(grid, i+d[0], j+d[1], visited, m, n)) neighbors++;\n        }\n        return neighbors == 0 ? 1 : 1 - neighbors;\n    }\n    \n    private boolean isNeighbor(int[][] grid, int i, int j, boolean[][] visited, int m, int n) {\n        if (i < 0 || j < 0 || i >= m || j >= n || grid[i][j] == 0 || visited[i][j]) return false;\n        travese(grid, i, j, visited, m, n);\n        return true;\n    }\n    \n    private void travese(int[][] grid, int i, int j, boolean[][] visited, int m, int n) {\n        if (i < 0 || j < 0 || i >= m || j >= n || grid[i][j] == 0 || visited[i][j]) return;\n        visited[i][j] = true;\n        for (int[] d: dirs) {\n            travese(grid, i+d[0], j+d[1], visited, m, n);\n        }\n    }\n\n\n    // Disjoint Set (Union-Find)\n    public List<Integer> numIslands22(int m, int n, int[][] positions) {\n        int[][] grid = new int[m][n];\n        DisjointSet ds = new DisjointSet(m * n);\n        List<Integer> res = new ArrayList<>();\n\n        int num = 0;\n        for (int[] pos: positions) {\n            \n            Set<Integer> set = new HashSet<>();\n            for (int[] d: dirs) {\n                int i = pos[0] + d[0];\n                int j = pos[1] + d[1];\n                if (i < 0 || j < 0 || i >= m || j >= n || grid[i][j] == 0) continue;\n                int idx = posToIndex(i, j, n);\n                set.add(ds.find(idx));\n            }\n            int neighbors = set.size();\n            int numDiff = neighbors == 0 ? 1 : 1 - neighbors;\n            num += numDiff;\n            res.add(num);\n            grid[pos[0]][pos[1]] = 1;\n            int curr = posToIndex(pos[0], pos[1], n);\n            for (int nb: set) {\n                ds.union(curr, nb);\n            }\n        }\n        \n        return res;\n    }\n\n    private int posToIndex(int i, int j, int n) {\n        return i * n + j;\n    }\n\n    class DisjointSet {\n        private int[] parent;\n        public DisjointSet(int n) {\n            parent = new int[n];\n            for (int i=0; i<n; i++) parent[i] = i;\n        } \n\n        public int find(int x) {\n            if (parent[x] != x) parent[x] = find(parent[x]);\n            return parent[x];\n        }\n\n        public void union(int x, int y) {\n            int xx = find(x);\n            int yy = find(y);\n            parent[xx] = yy;\n        }\n    }\n\n    class DisjointSetWithRank {\n        private int[] parent;\n        private int[] rank;\n        public DisjointSetWithRank(int n) {\n            parent = new int[n];\n            for (int i=0; i<n; i++) parent[i] = i;\n            rank = new int[n];\n        } \n\n        public int find(int x) {\n            if (parent[x] != x) parent[x] = find(parent[x]);\n            return parent[x];\n        }\n\n        public void union(int x, int y) {\n            int xx = find(x);\n            int yy = find(y);\n\n            if (rank[xx] < rank[yy]) {\n                parent[xx] = yy;\n            } else if (rank[xx] > rank[yy]) {\n                parent[yy] = xx;\n            } else {\n                parent[xx] = yy;\n                rank[yy]++;\n            }\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/number-of-islands-ii/discuss/75470/Easiest-Java-Solution-with-Explanations\n     */\n    public List<Integer> numIslands23(int m, int n, int[][] positions) {\n        List<Integer> result = new ArrayList<>();\n        if(m <= 0 || n <= 0) return result;\n    \n        int count = 0;                      // number of islands\n        int[] roots = new int[m * n];       // one island = one tree\n        Arrays.fill(roots, -1);            \n    \n        for(int[] p : positions) {\n            int root = n * p[0] + p[1];     // assume new point is isolated island\n            roots[root] = root;             // add new island\n            count++;\n    \n            for(int[] dir : dirs) {\n                int x = p[0] + dir[0]; \n                int y = p[1] + dir[1];\n                int nb = n * x + y;\n                if(x < 0 || x >= m || y < 0 || y >= n || roots[nb] == -1) continue;\n                \n                int rootNb = findIsland(roots, nb);\n                if(root != rootNb) {        // if neighbor is in another island\n                    roots[root] = rootNb;   // union two islands \n                    root = rootNb;          // current tree root = joined tree root\n                    count--;               \n                }\n            }\n    \n            result.add(count);\n        }\n        return result;\n    }\n    \n    public int findIsland(int[] roots, int id) {\n        while(id != roots[id]) {\n            roots[id] = roots[roots[id]];   // only one line added\n            id = roots[id];\n        }\n        return id;\n    }\n\n}\n"
  },
  {
    "path": "src/NumberOfLongestIncreasingSubsequence673.java",
    "content": "/**\n * Given an unsorted array of integers, find the number of longest increasing\n * subsequence.\n * \n * Example 1:\n * Input: [1,3,5,4,7]\n * Output: 2\n * Explanation: The two longest increasing subsequence are\n * [1, 3, 4, 7] and [1, 3, 5, 7].\n * \n * Example 2:\n * Input: [2,2,2,2,2]\n * Output: 5\n * Explanation: The length of longest continuous increasing subsequence is 1,\n * and there are 5 subsequences' length is 1, so output 5.\n * \n * Note: Length of the given array will be not exceed 2000 and the answer is\n * guaranteed to be fit in 32-bit signed int.\n */\n\npublic class NumberOfLongestIncreasingSubsequence673 {\n    public int findNumberOfLIS(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        int N = nums.length;\n        int[] dp = new int[N];\n        int[] count = new int[N];\n        int res = 0;\n        int maxLen = 1;\n        for (int i=0; i<N; i++) {\n            int curr = nums[i];\n            int localRes = 1;\n            int localCount = 1;\n            for (int j=0; j<i; j++) {\n                if (curr > nums[j]) {\n                    if (dp[j] + 1 > localRes) {\n                        localRes = dp[j] + 1;\n                        localCount = count[j];\n                    } else if (dp[j] + 1 == localRes) {\n                        localCount += count[j];\n                    }\n                }\n            }\n            if (localRes > maxLen) {\n                maxLen = localRes;\n                res = localCount;\n            } else if (localRes == maxLen) {\n                res += localCount;\n            }\n            count[i] = localCount;\n            dp[i] = localRes;\n        }\n        return res;\n    }\n}\n"
  },
  {
    "path": "src/NumberOfMatchingSubsequences792.java",
    "content": "/**\n * Given string S and a dictionary of words words, find the number of words[i]\n * that is a subsequence of S.\n * \n * Example :\n * Input: \n * S = \"abcde\"\n * words = [\"a\", \"bb\", \"acd\", \"ace\"]\n * Output: 3\n * Explanation: There are three words in words that are a subsequence of\n * S: \"a\", \"acd\", \"ace\".\n * \n * Note:\n * All words in words and S will only consists of lowercase letters.\n * The length of S will be in the range of [1, 50000].\n * The length of words will be in the range of [1, 5000].\n * The length of words[i] will be in the range of [1, 50].\n */\n\npublic class NumberOfMatchingSubsequences792 {\n\n    public int numMatchingSubseq(String S, String[] words) {\n        int res = 0;\n        for (String w: words) {\n            if (isSubsequence(w, S)) res++;\n        }\n        return res;\n    }\n\n    private boolean isSubsequence(String s, String t) {\n        int i = 0;\n        int j = 0;\n        char[] chars = s.toCharArray();\n        char[] chart = t.toCharArray();\n        while (i < chars.length && j < chart.length) {\n            if (chars[i] == chart[j]) {\n                i++;\n                j++;\n            } else {\n                j++;\n            }\n        }\n        return i == chars.length;\n    }\n\n\n    public int numMatchingSubseq2(String S, String[] words) {\n        LinkedList<Mover>[] map = new LinkedList[26];\n        for (char c = 'a'; c <= 'z'; c++) {\n            map[c-'a'] = new LinkedList<Mover>();\n        }\n        for (String word : words) {\n            map[word.charAt(0)-'a'].addLast(new Mover(word));\n        }\n\n        int count = 0;\n        for (char c : S.toCharArray()) {\n            LinkedList<Mover> ll = map[c-'a'];\n            int size = ll.size();\n            for (int i = 0; i < size; i++) {\n                Mover m = ll.removeFirst();\n                m.move();\n                if (m.hasEnded()) {\n                    count++;\n                } else {\n                    map[m.currChar()-'a'].addLast(m);\n                }\n            }\n        }\n        return count;\n    }\n    \n    class Mover {\n        char[] word;\n        int pos = 0;\n        Mover (String w) {\n            this.word = w.toCharArray();\n        }\n        char currChar() {\n            return this.word[pos];\n        }\n        void move() {\n            this.pos++;\n        }\n        boolean hasEnded() {\n            return this.word.length == pos;\n        }\n    }\n\n\n    public int numMatchingSubseq3(String S, String[] words) {\n        Trie trie = constructTrie(words);\n        int count = 0;\n        for (char c : S.toCharArray()) {\n            Trie curr = trie.children[c-'a'];\n            trie.children[c-'a'] = null;\n            while (curr != null) {\n                count += curr.count;\n                for (int nc=0; nc<26; nc++) {\n                    if (curr.children[nc] == null) continue;\n                    trie.children[nc] = add(curr.children[nc], trie.children[nc]);\n                }\n                curr = curr.next;\n            }\n        }\n        return count;\n    }\n    \n    private Trie add(Trie a, Trie b) {\n        a.next = b;\n        return a;\n    }\n    \n    private Trie constructTrie(String[] words) {\n        Trie trie = new Trie();\n        for (String word: words) {\n            trie.add(word);\n        }\n        return trie;\n    }\n\n    class Trie {\n        Trie[] children = new Trie[26];\n        Trie next;\n        int count = 0;\n        \n        void add(String word) {\n            add(word.toCharArray(), 0);\n        }\n        \n        void add(char[] word, int i) {\n            if (word.length == i) {\n                this.count++;\n                return;\n            }\n            int idx = word[i] - 'a';\n            if (this.children[idx] == null) {\n                this.children[idx] = new Trie();\n            }\n            this.children[idx].add(word, i+1);\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/OddEvenLinkedList328.java",
    "content": "/**\n * Given a singly linked list, group all odd nodes together followed by the\n * even nodes. Please note here we are talking about the node number and not\n * the value in the nodes.\n *\n * You should try to do it in place. The program should run in O(1) space\n * complexity and O(nodes) time complexity.\n *\n * Example:\n * Given 1->2->3->4->5->NULL,\n * return 1->3->5->2->4->NULL.\n *\n * Note:\n * The relative order inside both the even and odd groups should remain as it was in the input.\n * The first node is considered odd, the second node even and so on ...\n *\n */\n\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\n\npublic class OddEvenLinkedList328 {\n    public ListNode oddEvenList(ListNode head) {\n        if (head == null) return null;\n        ListNode dummy = new ListNode(0);\n        dummy.next = head;\n        ListNode evens = new ListNode(0);\n        ListNode e = evens;\n\n        ListNode p = dummy;\n        while (p.next != null) {\n            p = p.next;\n            if (p.next == null) break;\n            e.next = new ListNode(p.next.val);\n            e = e.next;\n            p.next = p.next.next;\n        }\n        p.next = evens.next;\n        return dummy.next;\n    }\n\n\n    public ListNode oddEvenList2(ListNode head) {\n        if (head == null) return null;\n        ListNode dummy = new ListNode(0);\n        dummy.next = head;\n        ListNode evens = new ListNode(0);\n        ListNode e = evens;\n\n        ListNode p = dummy;\n        while (p.next != null) {\n            p = p.next;\n            if (p.next == null) break;\n            e.next = p.next;\n            e = e.next;\n            p.next = p.next.next;\n            e.next = null;\n        }\n        p.next = evens.next;\n        return dummy.next;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/odd-even-linked-list/solution/\n     */\n    public ListNode oddEvenList3(ListNode head) {\n        if (head == null) return null;\n        ListNode odd = head, even = head.next, evenHead = even;\n        while (even != null && even.next != null) {\n            odd.next = even.next;\n            odd = odd.next;\n            even.next = odd.next;\n            even = even.next;\n        }\n        odd.next = evenHead;\n        return head;\n    }\n\n}\n"
  },
  {
    "path": "src/OneEditDistance.java",
    "content": "/**\n * \n */\n\npublic class OneEditDistance {\n    public boolean oneEditDistance(String str, String[] wordDict) {\n        Trie trie = constructTrie(wordDict, str.length());\n        return helper(str.toCharArray(), 0, trie, 0);\n    }\n\n    private boolean helper(char[] str, int i, Trie trie, int edit) {\n        if (edit > 1) return false;\n        if (str.length == i) {\n            if (edit == 1) {\n                return trie.isWord;\n            } else {\n                for (char ch='a'; ch<='z'; ch++) {\n                    if (trie.children[ch-'a'] != null && trie.children[ch-'a'].isWord) return true;\n                }\n                return false;\n            }\n        }\n\n        char curr = str[i];\n        for (char ch='a'; ch<='z'; ch++) {\n            int idx = ch-'a';\n            if (trie.children[idx] == null) continue;\n            if (helper(str, i+1, trie.children[idx], edit + ch == curr ? 0 : 1) ||\n                helper(str, i, trie.children[idx], edit + 1) ||\n                helper(str, i+1, trie, edit + 1)) return true;\n        }\n        return false;\n    }\n\n    private Trie constructTrie(String[] wordDict, int len) {\n        Trie trie = new Trie();\n        for (String word: wordDict) {\n            if (Math.abs(word.length() - len) <= 1) {\n                trie.add(word);\n            }\n        }\n        return trie;\n    }\n\n    // assume the string only contains a ~ z\n    class Trie {\n        Trie[] children = new Trie[26];\n        boolean isWord;\n\n        void add(String word) {\n            add(word.toCharArray(), 0);\n        }\n\n        void add(char[] word, int i) {\n            if (i == word.length) {\n                this.isWord = true;\n                return;\n            }\n            int idx = word[i] - 'a';\n            if (this.children[idx] == null) {\n                this.children[idx] = new Trie();\n            }\n            this.children[idx].add(word, i+1);\n        }\n    }\n\n\n    public boolean oneEditDistance2(String str, String[] wordDict) {\n        for (String word: wordDict) {\n            if (Math.abs(str.length() - word.length()) <= 1 && isOneEditDistance(s, word)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    private boolean isOneEditDistance(String s, String w) {\n        return isOneEditDistance(s.toCharArray(), 0, w.toCharArray(), 0, 0);\n    }\n\n    private boolean isOneEditDistance(char[] charsS, int i, char[] charsW, int j, int edit) {\n        if (edit > 1) return false;\n        if (i == charsS.length || j == charsW.length) {\n            return (Math.abs(charsS.length - charsW.length) + edit) == 1;\n        }\n        char chs = charsS[i];\n        char chw = charsW[j];\n        return isOneEditDistance(charsS, i+1, charsW, j+1, edit + chs == chw ? 0 : 1) ||\n                isOneEditDistance(charsS, i, charsW, j+1, edit + 1) ||\n                isOneEditDistance(charsS, i+1, charsW, j, edit + 1);\n    }\n\n\n    public boolean oneEditDistance3(String str, String[] wordDict) {\n        Set<String> dictSet = new HashSet<>();\n        for (String word: wordDict) {\n            char[] chars = wrod.toCharArray();\n            for (int i=0; i<chars.length; i++) {\n                char tmp = chars[i];\n                chars[i] = '*';\n                dictSet.add(new String(chars));\n                chars[i] = tmp;\n            }\n        }\n\n        char[] strChars = wrod.toCharArray();\n        // Set<String> strSet = new HashSet<>();\n        for (int i=0; i<strChars.length; i++) {\n            char tmp = strChars[i];\n            strChars[i] = '*';\n            if (dictSet.contains(new String(strChars))) return true;\n            strChars[i] = tmp;\n        }\n\n        return false;\n    }\n\n\n    public static void main(String[] args) {\n        OneEditDistance oed = new OneEditDistance();\n        System.out.println(oed.oneEditDistance(\"abc\", new String[]{\"abc\", \"abd\"})); // true\n        System.out.println(oed.oneEditDistance(\"abc\", new String[]{\"abc\"})); // false\n        System.out.println(oed.oneEditDistance(\"\", new String[]{\"a\"})); // true\n        System.out.println(oed.oneEditDistance(\"\", new String[]{\"\"})); // false\n        System.out.println(oed.oneEditDistance(\"a\", new String[]{\"\"})); // false\n        System.out.println(oed.oneEditDistance(\"a\", new String[]{\"b\", \"c\"})); // true\n        System.out.println(oed.oneEditDistance(\"a\", new String[]{\"a\", \"c\"})); // true\n        System.out.println(oed.oneEditDistance(\"a\", new String[]{\"a\"})); // false\n        System.out.println(oed.oneEditDistance(\"abcdef\", new String[]{\"abcdef\", \"abdef\"})); // true\n        System.out.println(oed.oneEditDistance(\"abcdef\", new String[]{\"abdef\"})); // true\n        System.out.println(oed.oneEditDistance(\"abcdef\", new String[]{\"abef\"})); // false\n        System.out.println(oed.oneEditDistance(\"abcef\", new String[]{\"abcdef\"})); // true\n    }\n\n}\n"
  },
  {
    "path": "src/OneEditDistance161.java",
    "content": "/**\n * Given two strings s and t, determine if they are both one edit distance apart.\n * \n * Note: \n * \n * There are 3 possiblities to satisify one edit distance apart:\n * \n * Insert a character into s to get t\n * Delete a character from s to get t\n * Replace a character of s to get t\n * \n * Example 1:\n * Input: s = \"ab\", t = \"acb\"\n * Output: true\n * Explanation: We can insert 'c' into s to get t.\n * \n * Example 2:\n * Input: s = \"cab\", t = \"ad\"\n * Output: false\n * Explanation: We cannot get t from s by only one step.\n * \n * Example 3:\n * Input: s = \"1203\", t = \"1213\"\n * Output: true\n * Explanation: We can replace '0' with '1' to get t.\n */\n\n\npublic class OneEditDistance161 {\n    public boolean isOneEditDistance(String s, String t) {\n        int lens = s.length();\n        int lent = t.length();\n        if (Math.abs(lens - lent) > 1) return false;\n        if (lens > lent) {\n            return isOneDelete(s, t);\n        } else if (lent > lens) {\n            return isOneDelete(t, s);\n        } else {\n            return isOneReplace(s, t);\n        }\n    }\n\n    private boolean isOneReplace(String s, String t) {\n        int diff = 0;\n        char[] charss = s.toCharArray();\n        char[] charst = t.toCharArray();\n        \n        for (int i=0; i<charss.length; i++) {\n            if (charss[i] != charst[i]) {\n                diff++;\n                if (diff > 1) return false;\n            }\n        }\n        \n        return diff == 1;\n    }\n    \n    private boolean isOneDelete(String longStr, String shortStr) {\n        char[] charsl = longStr.toCharArray();\n        char[] charss = shortStr.toCharArray();\n        \n        int l = 0;\n        int s = 0;\n        int diff = 0;\n        while (s < charss.length && l < charsl.length) {\n            if (charss[s] != charsl[l]) {\n                diff++;\n                if (diff > 1) return false;\n                l++;\n            } else {\n                s++;\n                l++;\n            }\n        }\n        \n        return ((l - s) == 1 && diff == 1) || (s == l && diff == 0);\n    }\n\n\n    public boolean isOneEditDistance2(String s, String t) {\n        if (s == null || t == null || Math.abs(s.length() - t.length()) >= 2) return false;\n        \n        char[] cs = s.toCharArray();\n        int lenS = s.length();\n        char[] ct = t.toCharArray();\n        int lenT = t.length();\n\n        int i = 0;\n        int j = 0;\n        while (i < lenS && j < lenT) {\n            if (cs[i] == ct[j]) {\n                i++;\n                j++;\n                continue;\n            }\n            return isSame(cs, i+1, lenS, ct, j+1, lenT) || isSame(cs, i+1, lenS, ct, j, lenT) || isSame(cs, i, lenS, ct, j+1, lenT);\n        }\n        \n        return Math.abs(lenS - lenT) == 1;\n    }\n    \n    private boolean isSame(char[] cs, int i, int lenS, char[] ct, int j, int lenT) {\n        if (i == lenS && j == lenT) return true;\n        if (i == lenS || j == lenT) return false;\n        \n        while (i < lenS && j < lenT) {\n            if (cs[i++] != ct[j++]) return false;\n        }\n        return i == lenS && j == lenT;\n    }\n\n}\n"
  },
  {
    "path": "src/OnesAndZeroes474.java",
    "content": "/**\n * In the computer world, use restricted resource you have to generate maximum\n * benefit is what we always want to pursue.\n * \n * For now, suppose you are a dominator of m 0s and n 1s respectively. On the\n * other hand, there is an array with strings consisting of only 0s and 1s.\n * \n * Now your task is to find the maximum number of strings that you can form\n * with given m 0s and n 1s. Each 0 and 1 can be used at most once.\n * \n * Note:\n * The given numbers of 0s and 1s will both not exceed 100\n * The size of given string array won't exceed 600.\n * \n * Example 1:\n * Input: Array = {\"10\", \"0001\", \"111001\", \"1\", \"0\"}, m = 5, n = 3\n * Output: 4\n * Explanation: This are totally 4 strings can be formed by the using of 5 0s and 3 1s, which are “10,”0001”,”1”,”0”\n * \n * Example 2:\n * Input: Array = {\"10\", \"0\", \"1\"}, m = 1, n = 1\n * Output: 2\n * Explanation: You could form \"10\", but then you'd have nothing left. Better form \"0\" and \"1\".\n */\n\npublic class OnesAndZeroes474 {\n    /**\n     * https://leetcode.com/problems/ones-and-zeroes/solution/\n     */\n    public int findMaxForm(String[] strs, int m, int n) {\n        int[][][] memo = new int[strs.length][m + 1][n + 1];\n        return calculate(strs, 0, m, n, memo);\n    }\n    public int calculate(String[] strs, int i, int zeroes, int ones, int[][][] memo) {\n        if (i == strs.length)\n            return 0;\n        if (memo[i][zeroes][ones] != 0)\n            return memo[i][zeroes][ones];\n        int[] count = countzeroesones(strs[i]);\n        int taken = -1;\n        if (zeroes - count[0] >= 0 && ones - count[1] >= 0)\n            taken = calculate(strs, i + 1, zeroes - count[0], ones - count[1], memo) + 1;\n        int not_taken = calculate(strs, i + 1, zeroes, ones, memo);\n        memo[i][zeroes][ones] = Math.max(taken, not_taken);\n        return memo[i][zeroes][ones];\n    }\n    public int[] countzeroesones(String s) {\n        int[] c = new int[2];\n        for (int i = 0; i < s.length(); i++) {\n            c[s.charAt(i)-'0']++;\n        }\n        return c;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/ones-and-zeroes/solution/\n     */\n    public int findMaxForm2(String[] strs, int m, int n) {\n        int[][] dp = new int[m + 1][n + 1];\n        for (String s: strs) {\n            int[] count = countzeroesones(s);\n            for (int zeroes = m; zeroes >= count[0]; zeroes--)\n                for (int ones = n; ones >= count[1]; ones--)\n                    dp[zeroes][ones] = Math.max(1 + dp[zeroes - count[0]][ones - count[1]], dp[zeroes][ones]);\n        }\n        return dp[m][n];\n    }\n\n}\n\n\n"
  },
  {
    "path": "src/OpenTheLock752.java",
    "content": "/**\n * You have a lock in front of you with 4 circular wheels. Each wheel has 10\n * slots: '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'. The wheels can\n * rotate freely and wrap around: for example we can turn '9' to be '0', or\n * '0' to be '9'. Each move consists of turning one wheel one slot.\n * \n * The lock initially starts at '0000', a string representing the state of the\n * 4 wheels.\n * \n * You are given a list of deadends dead ends, meaning if the lock displays\n * any of these codes, the wheels of the lock will stop turning and you will\n * be unable to open it.\n * \n * Given a target representing the value of the wheels that will unlock the\n * lock, return the minimum total number of turns required to open the lock,\n * or -1 if it is impossible.\n * \n * Example 1:\n * Input: deadends = [\"0201\",\"0101\",\"0102\",\"1212\",\"2002\"], target = \"0202\"\n * Output: 6\n * Explanation:\n * A sequence of valid moves would be\n * \"0000\" -> \"1000\" -> \"1100\" -> \"1200\" -> \"1201\" -> \"1202\" -> \"0202\".\n * Note that a sequence like \"0000\" -> \"0001\" -> \"0002\" -> \"0102\" -> \"0202\"\n * would be invalid, because the wheels of the lock become stuck after the\n * display becomes the dead end \"0102\".\n * \n * Example 2:\n * Input: deadends = [\"8888\"], target = \"0009\"\n * Output: 1\n * Explanation:\n * We can turn the last wheel in reverse to move from \"0000\" -> \"0009\".\n * \n * Example 3:\n * Input: deadends = [\"8887\",\"8889\",\"8878\",\"8898\",\"8788\",\"8988\",\"7888\",\"9888\"],\n * target = \"8888\"\n * Output: -1\n * Explanation:\n * We can't reach the target without getting stuck.\n * \n * Example 4:\n * Input: deadends = [\"0000\"], target = \"8888\"\n * Output: -1\n * \n * Note:\n * The length of deadends will be in the range [1, 500].\n * target will not be in the list deadends.\n * Every string in deadends and the string target will be a string of 4 digits\n * from the 10,000 possibilities '0000' to '9999'.\n */\n\npublic class OpenTheLock752 {\n    private char[] digits = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};\n    public int openLock(String[] deadends, String target) {\n        Set<String> set = new HashSet<>();\n        for (String end: deadends) set.add(end);\n        String start = \"0000\";\n        if (set.contains(start)) return -1;\n        Queue<String> q = new LinkedList<>();\n        q.add(start);\n        int level = 0;\n        Set<String> visited = new HashSet<>();\n        while (!q.isEmpty()) {\n            int size = q.size();\n            for (int i=0; i<size; i++) {\n                String currStr = q.poll();\n                if (target.equals(currStr)) return level;\n                char[] curr = currStr.toCharArray();\n                for (int j=0; j<4; j++) {\n                    char ch = curr[j];\n                    int d = Character.getNumericValue(ch);\n                    curr[j] = digits[next(d)];\n                    String nextStr = new String(curr);\n                    if (target.equals(nextStr)) return level+1;\n                    if (!set.contains(nextStr) && !visited.contains(nextStr)) {\n                        q.add(nextStr);\n                        visited.add(nextStr);\n                    }\n                    curr[j] = digits[prev(d)];\n                    String prevStr = new String(curr);\n                    if (target.equals(prevStr)) return level+1;\n                    if (!set.contains(prevStr) && !visited.contains(prevStr)) {\n                        q.add(prevStr);\n                        visited.add(prevStr);\n                    }\n                    curr[j] = ch;\n                }\n            }\n            level++;\n        }\n        return -1;\n    }\n\n    private int next(int i) {\n        return (i + 1) % 10;\n    }\n\n    private int prev(int i) {\n        return (i + 10 - 1) % 10;\n    }\n\n}\n"
  },
  {
    "path": "src/OptimalAccountBalancing465.java",
    "content": "/**\n * A group of friends went on holiday and sometimes lent each other money. For\n * example, Alice paid for Bill's lunch for $10. Then later Chris gave Alice $5\n * for a taxi ride. We can model each transaction as a tuple (x, y, z) which\n * means person x gave person y $z. Assuming Alice, Bill, and Chris are person\n * 0, 1, and 2 respectively (0, 1, 2 are the person's ID), the transactions can\n * be represented as [[0, 1, 10], [2, 0, 5]].\n * \n * Given a list of transactions between a group of people, return the minimum\n * number of transactions required to settle the debt.\n * \n * Note:\n * A transaction will be given as a tuple (x, y, z). Note that x ≠ y and z > 0.\n * Person's IDs may not be linear, e.g. we could have the persons 0, 1, 2 or\n * we could also have the persons 0, 2, 6.\n * \n * Example 1:\n * Input:\n * [[0,1,10], [2,0,5]]\n * Output:\n * 2\n * \n * Explanation:\n * Person #0 gave person #1 $10.\n * Person #2 gave person #0 $5.\n * Two transactions are needed. One way to settle the debt is person #1 pays\n * person #0 and #2 $5 each.\n * \n * Example 2:\n * Input:\n * [[0,1,10], [1,0,1], [1,2,5], [2,0,5]]\n * Output:\n * 1\n * \n * Explanation:\n * Person #0 gave person #1 $10.\n * Person #1 gave person #0 $1.\n * Person #1 gave person #2 $5.\n * Person #2 gave person #0 $5.\n *  Therefore, person #1 only need to give person #0 $4, and all debt is settled.\n */\n\npublic class OptimalAccountBalancing465 {\n    public int minTransfers(int[][] transactions) {\n        Map<Integer, Integer> balances = getBalances(transactions);\n        int[] posNeg = new int[balances.size()];\n        int i =0;\n        for (int b: balances.values()) {\n            posNeg[i++] = b;\n        }\n        return dfs(posNeg, 0);\n    }\n\n    private int dfs(int[] posNeg, int start) {\n        int L = posNeg.length;\n        while (start < L && posNeg[start] == 0) start++;\n        if (start == L) return 0;\n        int res = Integer.MAX_VALUE;\n\n        for (int i=start+1; i<L; i++) {\n            if (posNeg[start] * posNeg[i] >= 0) continue;\n            int pre = posNeg[i];\n            posNeg[i] += posNeg[start];\n            res = Math.min(res, dfs(posNeg, start+1) + 1);\n            posNeg[i] = pre;\n        }\n        return res;\n    }\n\n    private Map<Integer, Integer> getBalances(int[][] transactions) {\n        Map<Integer, Integer> balances = new HashMap<>();\n        for (int[] tx: transactions) {\n            balances.put(tx[0], balances.getOrDefault(tx[0], 0) - tx[2]);\n            balances.put(tx[1], balances.getOrDefault(tx[1], 0) + tx[2]);\n        }\n        return balances;\n    }\n\n}\n"
  },
  {
    "path": "src/OutputContestMatches544.java",
    "content": "/**\n * During the NBA playoffs, we always arrange the rather strong team to play\n * with the rather weak team, like make the rank 1 team play with the rank nth\n * team, which is a good strategy to make the contest more interesting. Now,\n * you're given n teams, you need to output their final contest matches in the\n * form of a string.\n * \n * The n teams are given in the form of positive integers from 1 to n, which\n * represents their initial rank. (Rank 1 is the strongest team and Rank n is\n * the weakest team.) We'll use parentheses('(', ')') and commas(',') to\n * represent the contest team pairing - parentheses('(' , ')') for pairing and\n * commas(',') for partition. During the pairing process in each round, you\n * always need to follow the strategy of making the rather strong one pair with\n * the rather weak one.\n * \n * Example 1:\n * Input: 2\n * Output: (1,2)\n * Explanation: \n * Initially, we have the team 1 and the team 2, placed like: 1,2.\n * Then we pair the team (1,2) together with '(', ')' and ',', which is the\n * final answer.\n * \n * Example 2:\n * Input: 4\n * Output: ((1,4),(2,3))\n * Explanation: \n * In the first round, we pair the team 1 and 4, the team 2 and 3 together, as\n * we need to make the strong team and weak team together.\n * And we got (1,4),(2,3).\n * In the second round, the winners of (1,4) and (2,3) need to play again to\n * generate the final winner, so you need to add the paratheses outside them.\n * And we got the final answer ((1,4),(2,3)).\n * \n * Example 3:\n * Input: 8\n * Output: (((1,8),(4,5)),((2,7),(3,6)))\n * Explanation: \n * First round: (1,8),(2,7),(3,6),(4,5)\n * Second round: ((1,8),(4,5)),((2,7),(3,6))\n * Third round: (((1,8),(4,5)),((2,7),(3,6)))\n * Since the third round will generate the final winner, you need to output the\n * answer (((1,8),(4,5)),((2,7),(3,6))).\n *\n * Note:\n * The n is in range [2, 212].\n * We ensure that the input n can be converted into the form 2k, where k is a\n * positive integer.\n */\n\nclass OutputContestMatches544 {\n    // O(NlogN). Each of O(logN) rounds performs O(N) work.\n    public String findContestMatch(int n) {\n        String[] arr = new String[n];\n        for (int i=1; i<=n; i++) arr[i-1] = String.valueOf(i);\n\n        while (n/2 >= 1) {\n            int h = n/2;\n\n            for (int i=1; i<=h; i++) {\n                arr[i-1] = combine(arr[i-1], arr[n-i]);\n            }\n\n            n /= 2;\n        }\n        return arr[0];\n    }\n\n    private String combine(String l, String r) {\n        return \"(\" + l + \",\" + r + \")\";\n    }\n\n\n    /**\n     * https://leetcode.com/problems/output-contest-matches/solution/\n     */\n    // O(N). We print each of O(N) characters in order.\n    int[] team;\n    int t;\n    StringBuilder ans;\n    public String findContestMatch2(int n) {\n        team = new int[n];\n        t = 0;\n        ans = new StringBuilder();\n        write(n, Integer.numberOfTrailingZeros(n));\n        return ans.toString();\n    }\n\n    public void write(int n, int round) {\n        if (round == 0) {\n            int w = Integer.lowestOneBit(t);\n            team[t] = w > 0 ? n / w + 1 - team[t - w] : 1;\n            ans.append(\"\" + team[t++]);\n        } else {\n            ans.append(\"(\");\n            write(n, round - 1);\n            ans.append(\",\");\n            write(n, round - 1);\n            ans.append(\")\");\n        }\n    }\n\n    \n    /**\n     * https://leetcode.com/problems/output-contest-matches/discuss/101228/3-ms-Java-Recursive-clean-code\n     */\n    public String findContestMatch3(int n) {\n        StringBuilder sb = new StringBuilder();\n        helper(sb, 3, n, 1);\n        return sb.toString();\n    }\n\n    void helper(StringBuilder sb, int sum, int n, int val) {\n        if (sum > n + 1) {\n            sb.append(val);\n            return;\n        }\n        sb.append('(');\n        helper(sb, (sum << 1) - 1, n, val);\n        sb.append(',');\n        helper(sb, (sum << 1) - 1, n, sum - val);\n        sb.append(')');        \n    }\n\n}"
  },
  {
    "path": "src/PacificAtlanticWaterFlow417.java",
    "content": "/**\n * Given an m x n matrix of non-negative integers representing the height of\n * each unit cell in a continent, the \"Pacific ocean\" touches the left and top\n * edges of the matrix and the \"Atlantic ocean\" touches the right and bottom\n * edges.\n * \n * Water can only flow in four directions (up, down, left, or right) from a\n * cell to another one with height equal or lower.\n * \n * Find the list of grid coordinates where water can flow to both the Pacific\n * and Atlantic ocean.\n * \n * Note:\n * The order of returned grid coordinates does not matter.\n * Both m and n are less than 150.\n * \n * Example:\n * \n * Given the following 5x5 matrix:\n * \n *   Pacific ~   ~   ~   ~   ~ \n *        ~  1   2   2   3  (5) *\n *        ~  3   2   3  (4) (4) *\n *        ~  2   4  (5)  3   1  *\n *        ~ (6) (7)  1   4   5  *\n *        ~ (5)  1   1   2   4  *\n *           *   *   *   *   * Atlantic\n * \n * Return:\n * \n * [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (positions with\n * parentheses in above matrix).\n */\n\n\npublic class PacificAtlanticWaterFlow417 {\n    private int[][] dirs = new int[][]{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};\n    \n    public List<int[]> pacificAtlantic(int[][] matrix) {\n        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return new ArrayList<>();\n        int M = matrix.length;\n        int N = matrix[0].length;\n        boolean[][] pacific = new boolean[M][N];\n        boolean[][] visited = new boolean[M][N];\n        Queue<int[]> q = new LinkedList<>();\n        for (int j=0; j<N; j++) {\n            q.add(new int[]{0, j});\n            pacific[0][j] = true;\n            visited[0][j] = true;\n        }\n        for (int i=1; i<M; i++) {\n            q.add(new int[]{i, 0});\n            pacific[i][0] = true;\n            visited[i][0] = true;\n        }\n        while (!q.isEmpty()) {\n            int[] now = q.poll();\n            for (int[] d: dirs) {\n                int x = now[0] + d[0];\n                int y = now[1] + d[1];\n                if (x >= 0 && y >= 0 && x < M && y < N && !visited[x][y] && matrix[x][y] >= matrix[now[0]][now[1]]) {\n                    q.add(new int[]{x, y});\n                    pacific[x][y] = true;\n                    visited[x][y] = true;\n                }\n            }\n        }\n\n        boolean[][] atlantic = new boolean[M][N];\n        visited = new boolean[M][N];\n        q = new LinkedList<>();\n        for (int j=0; j<N; j++) {\n            q.add(new int[]{M-1, j});\n            atlantic[M-1][j] = true;\n            visited[M-1][j] = true;\n        }\n        for (int i=0; i<M-1; i++) {\n            q.add(new int[]{i, N-1});\n            atlantic[i][N-1] = true;\n            visited[i][N-1] = true;\n        }\n        while (!q.isEmpty()) {\n            int[] now = q.poll();\n            for (int[] d: dirs) {\n                int x = now[0] + d[0];\n                int y = now[1] + d[1];\n                if (x >= 0 && y >= 0 && x < M && y < N && !visited[x][y] && matrix[x][y] >= matrix[now[0]][now[1]]) {\n                    q.add(new int[]{x, y});\n                    atlantic[x][y] = true;\n                    visited[x][y] = true;\n                }\n            }\n        }\n\n        List<int[]> res = new ArrayList<>();\n        for (int i=0; i<M; i++) {\n            for (int j=0; j<N; j++) {\n                if (atlantic[i][j] && pacific[i][j]) {\n                    // System.out.println(i + \", \" + j);\n                    res.add(new int[]{i, j});\n                }\n            }\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/PaintFence276.java",
    "content": "/**\n * There is a fence with n posts, each post can be painted with one of the k\n * colors.\n * \n * You have to paint all the posts such that no more than two adjacent fence\n * posts have the same color.\n * \n * Return the total number of ways you can paint the fence.\n * \n * Note:\n * n and k are non-negative integers.\n * \n * Example:\n * \n * Input: n = 3, k = 2\n * Output: 6\n * Explanation: Take c1 as color 1, c2 as color 2. All possible ways are:\n * \n *             post1  post2  post3      \n *  -----      -----  -----  -----       \n *    1         c1     c1     c2 \n *    2         c1     c2     c1 \n *    3         c1     c2     c2 \n *    4         c2     c1     c1  \n *    5         c2     c1     c2\n *    6         c2     c2     c1\n */\n\npublic class PaintFence276 {\n    public int numWays(int n, int k) {\n        if (k == 0 || n == 0) return 0;\n        int[][] dp = new int[n][2];\n        dp[0][0] = k;\n        dp[0][1] = 0;\n        for (int i=1; i<n; i++) {\n            dp[i][0] = (dp[i-1][0] + dp[i-1][1]) * (k - 1);\n            dp[i][1] = dp[i-1][0];\n        }\n        return dp[n-1][0] + dp[n-1][1];\n    }\n  \n    public int numWays2(int n, int k) {\n        if (k == 0 || n == 0) return 0;\n        int diff = k;\n        int same = 0;\n        for (int i=1; i<n; i++) {\n            int s = same;\n            int d = diff;\n            diff = (s + d) * (k - 1);\n            same = d;\n        }\n        return same + diff;\n    }\n\n}\n"
  },
  {
    "path": "src/PaintHouse256.java",
    "content": "/**\n * There are a row of n houses, each house can be painted with one of the three\n * colors: red, blue or green. The cost of painting each house with a certain\n * color is different. You have to paint all the houses such that no two\n * adjacent houses have the same color.\n * \n * The cost of painting each house with a certain color is represented by a\n * n x 3 cost matrix. For example, costs[0][0] is the cost of painting house\n * 0 with color red; costs[1][2] is the cost of painting house 1 with\n * color green, and so on... Find the minimum cost to paint all houses.\n * \n * Note:\n * All costs are positive integers.\n * \n * Example:\n * Input: [[17,2,17],[16,16,5],[14,3,19]]\n * Output: 10\n * Explanation: Paint house 0 into blue, paint house 1 into green, paint\n * house 2 into blue. Minimum cost: 2 + 5 + 3 = 10.\n */\n\npublic class PaintHouse256 {\n    public int minCost(int[][] costs) {\n        if (costs == null || costs.length == 0) return 0;\n        int N = costs.length;\n        int[][] dp = new int[N + 1][3];\n        for (int i=1; i<=N; i++) {\n            dp[i][0] = Math.min(dp[i-1][1], dp[i-1][2]) + costs[i-1][0];\n            dp[i][1] = Math.min(dp[i-1][0], dp[i-1][2]) + costs[i-1][1];\n            dp[i][2] = Math.min(dp[i-1][0], dp[i-1][1]) + costs[i-1][2];\n        }\n        return Math.min(dp[N][0], Math.min(dp[N][1], dp[N][2]));\n    }\n\n\n    public int minCost2(int[][] costs) {\n        if (costs == null || costs.length == 0) return 0;\n        int N = costs.length;\n        int red = 0;\n        int blue = 0;\n        int green = 0;\n        for (int i=1; i<=N; i++) {\n            int r = red;\n            int b = blue;\n            int g = green;\n            red = Math.min(b, g) + costs[i-1][0];\n            blue = Math.min(r, g) + costs[i-1][1];\n            green = Math.min(r, b) + costs[i-1][2];\n        }\n        return Math.min(red, Math.min(blue, green));\n    }\n\n}\n"
  },
  {
    "path": "src/PaintHouseII265.java",
    "content": "/**\n * There are a row of n houses, each house can be painted with one of the k\n * colors. The cost of painting each house with a certain color is different.\n * You have to paint all the houses such that no two adjacent houses have the\n * same color.\n * \n * The cost of painting each house with a certain color is represented by a\n * n x k cost matrix. For example, costs[0][0] is the cost of painting house\n * 0 with color 0; costs[1][2] is the cost of painting house 1 with color 2,\n * and so on... Find the minimum cost to paint all houses.\n * \n * Note:\n * All costs are positive integers.\n * \n * Example:\n * Input: [[1,5,3],[2,9,4]]\n * Output: 5\n * Explanation: Paint house 0 into color 0, paint house 1 into color 2. Minimum cost: 1 + 4 = 5; \n *           Or paint house 0 into color 2, paint house 1 into color 0. Minimum cost: 3 + 2 = 5. \n * \n * Follow up:\n * Could you solve it in O(nk) runtime?\n */\n\npublic class PaintHouseII265 {\n    public int minCostII(int[][] costs) {\n        if (costs == null || costs.length == 0 || costs[0].length == 0) return 0;\n        int N = costs.length;\n        int K = costs[0].length;\n        int[][] dp = new int[N + 1][K];\n        \n        for (int i=1; i<=N; i++) {\n            int[] mins = minIndex(dp, i-1, K);\n            for (int k=0; k<K; k++) {\n                dp[i][k] = mins[k] + costs[i-1][k];\n            }\n        }\n        \n        int res = Integer.MAX_VALUE;\n        for (int c: dp[N]) {\n            if (c < res) res = c;\n        }\n        return res == Integer.MAX_VALUE ? 0 : res;\n    }\n    \n    private int[] minIndex(int[][] dp, int i, int K) {\n        int[] mins = new int[K];\n        int min1 = Integer.MAX_VALUE;\n        int min2 = Integer.MAX_VALUE;\n        for (int k=0; k<K; k++) {\n            if (dp[i][k] <= min1) {\n                min2 = min1;\n                min1 = dp[i][k];\n            } else if (dp[i][k] > min1 && dp[i][k] < min2) {\n                min2 = dp[i][k];\n            }\n        }\n        if (min2 == Integer.MAX_VALUE) min2 = min1;\n        for (int k=0; k<K; k++) {\n            if (dp[i][k] == min1) {\n                mins[k] = min2;\n            } else {\n                mins[k] = min1;\n            }\n        }\n        return mins;\n    }\n  \n\n    public int minCostII2(int[][] costs) {\n        if (costs == null || costs.length == 0 || costs[0].length == 0) return 0;\n        int N = costs.length;\n        int K = costs[0].length;\n        int[] dp = new int[K];\n        \n        for (int i=1; i<=N; i++) {\n            minIndex(dp, K);\n            for (int k=0; k<K; k++) {\n                dp[k] = dp[k] + costs[i-1][k];\n            }\n        }\n        \n        int res = Integer.MAX_VALUE;\n        for (int c: dp) {\n            if (c < res) res = c;\n        }\n        return res == Integer.MAX_VALUE ? 0 : res;\n    }\n\n    private void minIndex(int[] dp, int K) {\n        int min1 = Integer.MAX_VALUE;\n        int min2 = Integer.MAX_VALUE;\n        for (int k=0; k<K; k++) {\n            if (dp[k] <= min1) {\n                min2 = min1;\n                min1 = dp[k];\n            } else if (dp[k] > min1 && dp[k] < min2) {\n                min2 = dp[k];\n            }\n        }\n        if (min2 == Integer.MAX_VALUE) min2 = min1;\n        for (int k=0; k<K; k++) {\n            if (dp[k] == min1) {\n                dp[k] = min2;\n            } else {\n                dp[k] = min1;\n            }\n        }\n    }\n\n\n    public int minCostII3(int[][] costs) {\n        if (costs == null || costs.length == 0 || costs[0].length == 0) return 0;\n        int N = costs.length;\n        int K = costs[0].length;\n        int[] dp = new int[K];\n        int min1 = 0;\n        int min2 = 0;\n        for (int i=0; i<N; i++) {\n            int pre1 = min1;\n            int pre2 = min2;\n            min1 = Integer.MAX_VALUE;\n            min2 = Integer.MAX_VALUE;\n            for (int k=0; k<K; k++) {\n                dp[k] = (dp[k] == pre1 ? pre2 : pre1) + costs[i][k];\n                if (dp[k] <= min1) {\n                    min2 = min1;\n                    min1 = dp[k];\n                } else if (dp[k] > min1 && dp[k] < min2) {\n                    min2 = dp[k];\n                }\n            }\n        }\n        \n        int res = Integer.MAX_VALUE;\n        for (int c: dp) {\n            if (c < res) res = c;\n        }\n        return res == Integer.MAX_VALUE ? 0 : res;\n    }\n\n\n    public int minCostII4(int[][] costs) {\n        if (costs == null || costs.length == 0 || costs[0].length == 0) return 0;\n        int N = costs.length;\n        int K = costs[0].length;\n        int[] dp = new int[K];\n        int min1 = 0;\n        int min2 = 0;\n        for (int i=0; i<N; i++) {\n            int pre1 = min1;\n            int pre2 = min2;\n            min1 = Integer.MAX_VALUE;\n            min2 = Integer.MAX_VALUE;\n            for (int k=0; k<K; k++) {\n                dp[k] = (dp[k] == pre1 ? pre2 : pre1) + costs[i][k];\n                if (dp[k] <= min1) {\n                    min2 = min1;\n                    min1 = dp[k];\n                } else if (dp[k] > min1 && dp[k] < min2) {\n                    min2 = dp[k];\n                }\n            }\n        }\n        return min1;\n    }\n\n\n    public int minCostII5(int[][] costs) {\n        if (costs == null || costs.length == 0 || costs[0].length == 0) return 0;\n        int N = costs.length;\n        int K = costs[0].length;\n        int min1 = 0;\n        int minIdx = -1;\n        int min2 = 0;\n        for (int i=0; i<N; i++) {\n            int pre1 = min1;\n            int pre2 = min2;\n            int preIdx = minIdx;\n            min1 = Integer.MAX_VALUE;\n            min2 = Integer.MAX_VALUE;\n            int tmp = 0;\n            for (int k=0; k<K; k++) {\n                tmp = (preIdx == k ? pre2 : pre1) + costs[i][k];\n                if (tmp <= min1) {\n                    min2 = min1;\n                    min1 = tmp;\n                    minIdx = k;\n                } else if (tmp > min1 && tmp < min2) {\n                    min2 = tmp;\n                }\n            }\n        }\n        return min1;\n    }\n\n}\n"
  },
  {
    "path": "src/PalindromeLinkedList234.java",
    "content": "/**\n * Given a singly linked list, determine if it is a palindrome.\n *\n * Follow up:\n * Could you do it in O(n) time and O(1) space?\n */\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\npublic class PalindromeLinkedList234 {\n    public boolean isPalindrome(ListNode head) {\n        ListNode dummy = new ListNode(0);\n\n        ListNode f = head;\n        ListNode s = head;\n        while (s != null && f != null && f.next != null) {\n            ListNode t = s;\n            s = s.next;\n            f = f.next.next;\n            t.next = dummy.next;\n            dummy.next = t;\n        }\n\n        if (f != null) {\n            s = s.next;\n        }\n        dummy = dummy.next;\n        while (s != null && dummy != null) {\n            if (dummy.val != s.val) return false;\n            s = s.next;\n            dummy = dummy.next;\n        }\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/palindrome-linked-list/discuss/64501/Java-easy-to-understand\n     */\n    public boolean isPalindrome2(ListNode head) {\n        ListNode fast = head, slow = head;\n        while (fast != null && fast.next != null) {\n            fast = fast.next.next;\n            slow = slow.next;\n        }\n        if (fast != null) { // odd nodes: let right half smaller\n            slow = slow.next;\n        }\n        slow = reverse(slow);\n        fast = head;\n\n        while (slow != null) {\n            if (fast.val != slow.val) {\n                return false;\n            }\n            fast = fast.next;\n            slow = slow.next;\n        }\n        return true;\n    }\n\n    public ListNode reverse(ListNode head) {\n        ListNode prev = null;\n        while (head != null) {\n            ListNode next = head.next;\n            head.next = prev;\n            prev = head;\n            head = next;\n        }\n        return prev;\n    }\n\n}\n"
  },
  {
    "path": "src/PalindromeNumber9.java",
    "content": "/**\n * Determine whether an integer is a palindrome. An integer is a palindrome\n * when it reads the same backward as forward.\n * \n * Example 1:\n * Input: 121\n * Output: true\n * \n * Example 2:\n * Input: -121\n * Output: false\n * Explanation: From left to right, it reads -121. From right to left,\n * it becomes 121-. Therefore it is not a palindrome.\n * \n * Example 3:\n * Input: 10\n * Output: false\n * Explanation: Reads 01 from right to left. Therefore it is not a palindrome.\n * \n * Follow up:\n * Coud you solve it without converting the integer to a string?\n */\n\npublic class PalindromeNumber9 {\n    public boolean isPalindrome(int x) {\n        if (x < 0) return false;\n        if (x == 0) return true;\n        return x == reverse(x);\n    }\n    \n    private int reverse(int x) {\n        int res = 0;\n        while (x != 0) {\n            res *= 10;\n            res += x % 10;\n            x /= 10;\n        }\n        return res;\n    }\n\n\n    public int numberOfDigits(int x) {\n        int res = 0;\n        while (x != 0) {\n            res++;\n            x /= 10;\n        }\n        return res;\n    }\n\n    private int getDigit(int x, int pos) {\n        return (x / (int) Math.pow(10, pos-1)) % 10;\n    }\n\n    public boolean isPalindrome2(int x) {\n        if (x < 0) return false;\n        if (x == 0) return true;\n        int N = numberOfDigits(x);\n        int hi = N;\n        int lo = 1;\n        while (lo < hi) {\n            if (getDigit(x, lo++) != getDigit(x, hi--)) return false;\n        }\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/palindrome-number/discuss/5127/9-line-accepted-Java-code-without-the-need-of-handling-overflow\n     */\n    public boolean isPalindrome3(int x) {\n        if (x<0 || (x!=0 && x%10==0)) return false;\n        int rev = 0;\n        while (x>rev){\n          rev = rev*10 + x%10;\n          x = x/10;\n        }\n        return (x==rev || x==rev/10);\n    }\n\n}\n"
  },
  {
    "path": "src/PalindromePairs336.java",
    "content": "/**\n * Given a list of unique words, find all pairs of distinct indices (i, j) in\n * the given list, so that the concatenation of the two words, i.e.\n * words[i] + words[j] is a palindrome.\n *\n * Example 1:\n * Given words = [\"bat\", \"tab\", \"cat\"]\n * Return [[0, 1], [1, 0]]\n * The palindromes are [\"battab\", \"tabbat\"]\n *\n * Example 2:\n * Given words = [\"abcd\", \"dcba\", \"lls\", \"s\", \"sssll\"]\n * Return [[0, 1], [1, 0], [3, 2], [2, 4]]\n * The palindromes are [\"dcbaabcd\", \"abcddcba\", \"slls\", \"llssssll\"]\n *\n */\n\n\npublic class PalindromePairs336 {\n    public List<List<Integer>> palindromePairs(String[] words) {\n        List<List<Integer>> res = new ArrayList<>();\n\n        for (int i=0; i<words.length; i++) {\n            for (int j=i+1; j<words.length; j++) {\n                String s1 = words[i];\n                String s2 = words[j];\n\n                if (isPalindrome(s1, s2)) {\n                    List<Integer> pair = new ArrayList<>(2);\n                    pair.add(i);\n                    pair.add(j);\n                    res.add(pair);\n                }\n\n                if (isPalindrome(s2, s1)) {\n                    List<Integer> pair = new ArrayList<>(2);\n                    pair.add(j);\n                    pair.add(i);\n                    res.add(pair);\n                }\n            }\n        }\n\n        return res;\n    }\n\n    private boolean isPalindrome(String s1, String s2) {\n        int i = 0;\n        int j = s2.length() - 1;\n\n        while (i < s1.length() && j >= 0) {\n            if (s1.charAt(i) != s2.charAt(j)) return false;\n            i++;\n            j--;\n        }\n\n        if (i < s1.length()) {\n            return isPalindrome(s1, i, s1.length()-1);\n        }\n\n        if (j >= 0) {\n            return isPalindrome(s2, 0, j);\n        }\n\n        return true;\n    }\n\n    private boolean isPalindrome(String str, int i, int j) {\n        if (str == null || str.length() <= 1) return true;\n        if ((j - i + 1) <= 0) return true;\n\n        while (i < j) {\n            if (str.charAt(i) != str.charAt(j)) return false;\n            i++;\n            j--;\n        }\n\n        return true;\n    }\n\n\n\n    private boolean isPalindrome(String str) {\n        if (str == null || str.length() <= 1) return true;\n\n        int i = 0;\n        int j = str.length() - 1;\n        while (i < j) {\n            if (str.charAt(i) != str.charAt(j)) return false;\n            i++;\n            j--;\n        }\n\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/palindrome-pairs/discuss/79199/150-ms-45-lines-JAVA-solution\n     */\n    public List<List<Integer>> palindromePairs2(String[] words) {\n        List<List<Integer>> ret = new ArrayList<>();\n        if (words == null || words.length < 2) return ret;\n        Map<String, Integer> map = new HashMap<String, Integer>();\n        for (int i=0; i<words.length; i++) map.put(words[i], i);\n        for (int i=0; i<words.length; i++) {\n            for (int j=0; j<=words[i].length(); j++) {\n                String str1 = words[i].substring(0, j);\n                String str2 = words[i].substring(j);\n                if (isPalindrome(str1)) {\n                    String str2rvs = new StringBuilder(str2).reverse().toString();\n                    if (map.containsKey(str2rvs) && map.get(str2rvs) != i) {\n                        List<Integer> list = new ArrayList<Integer>();\n                        list.add(map.get(str2rvs));\n                        list.add(i);\n                        ret.add(list);\n                    }\n                }\n                if (isPalindrome(str2)) {\n                    String str1rvs = new StringBuilder(str1).reverse().toString();\n                    if (map.containsKey(str1rvs) && map.get(str1rvs) != i && str2.length()!=0) {\n                        List<Integer> list = new ArrayList<Integer>();\n                        list.add(i);\n                        list.add(map.get(str1rvs));\n                        ret.add(list);\n                    }\n                }\n            }\n        }\n        return ret;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/palindrome-pairs/discuss/79195/O(n*k2)-java-solution-with-Trie-structure-(n:-total-number-of-words-k:-average-length-of-each-word)\n     */\n    private static class TrieNode {\n        TrieNode[] next;\n        int index;\n        List<Integer> list;\n\n        TrieNode() {\n          \tnext = new TrieNode[26];\n          \tindex = -1;\n          \tlist = new ArrayList<>();\n        }\n    }\n\n    public List<List<Integer>> palindromePairs3(String[] words) {\n        List<List<Integer>> res = new ArrayList<>();\n\n        TrieNode root = new TrieNode();\n        for (int i = 0; i < words.length; i++) addWord(root, words[i], i);\n        for (int i = 0; i < words.length; i++) search(words, i, root, res);\n\n        return res;\n    }\n\n    private void addWord(TrieNode root, String word, int index) {\n        for (int i = word.length() - 1; i >= 0; i--) {\n            int j = word.charAt(i) - 'a';\n          \tif (root.next[j] == null) root.next[j] = new TrieNode();\n          \tif (isPalindrome(word, 0, i)) root.list.add(index);\n          \troot = root.next[j];\n        }\n\n        root.list.add(index);\n        root.index = index;\n    }\n\n    private void search(String[] words, int i, TrieNode root, List<List<Integer>> res) {\n        for (int j = 0; j < words[i].length(); j++) {\n          \tif (root.index >= 0 && root.index != i && isPalindrome(words[i], j, words[i].length() - 1)) {\n          \t    res.add(Arrays.asList(i, root.index));\n          \t}\n\n          \troot = root.next[words[i].charAt(j) - 'a'];\n          \tif (root == null) return;\n        }\n\n        for (int j : root.list) {\n          \tif (i == j) continue;\n          \tres.add(Arrays.asList(i, j));\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "src/PalindromePartitioning131.java",
    "content": "/**\n * Given a string s, partition s such that every substring of the partition is\n * a palindrome.\n *\n * Return all possible palindrome partitioning of s.\n * \n * Example:\n * \n * Input: \"aab\"\n * Output:\n * [\n *   [\"aa\",\"b\"],\n *   [\"a\",\"a\",\"b\"]\n * ]\n */\n\n\npublic class PalindromePartitioning131 {\n    public List<List<String>> partition(String s) {\n        List<List<String>> res = new ArrayList<>();\n        helper(s.toCharArray(), 0, new ArrayList<>(), res);\n        return res;\n    }\n\n    private void helper(char[] chars, int start, List<String> path, List<List<String>> res) {\n        if (start == chars.length) {\n            res.add(new ArrayList<>(path));\n            return;\n        }\n\n        for (int j=start; j<chars.length; j++) {\n            if (isPalindrome(chars, start, j)) {\n                path.add(new String(Arrays.copyOfRange(chars, start, j+1)));\n                helper(chars, j+1, path, res);\n                path.remove(path.size()-1);\n            }\n        }\n    }\n    \n    private boolean isPalindrome(char[] chars, int i, int j) {\n        if (i > j) return true;\n        if (i == j) return true;\n        for (int k=0; k<=(j-i)/2; k++) {\n            if (chars[i+k] != chars[j-k]) return false;\n        }\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/palindrome-partitioning/discuss/41982/Java-DP-+-DFS-solution\n     */\n    public List<List<String>> partition2(String s) {\n        List<List<String>> res = new ArrayList<>();\n        boolean[][] dp = new boolean[s.length()][s.length()];\n        for(int i = 0; i < s.length(); i++) {\n            for(int j = 0; j <= i; j++) {\n                if(s.charAt(i) == s.charAt(j) && (i - j <= 2 || dp[j+1][i-1])) {\n                    dp[j][i] = true;\n                }\n            }\n        }\n        helper(res, new ArrayList<>(), dp, s, 0);\n        return res;\n    }\n    \n    private void helper(List<List<String>> res, List<String> path, boolean[][] dp, String s, int pos) {\n        if(pos == s.length()) {\n            res.add(new ArrayList<>(path));\n            return;\n        }\n        \n        for(int i = pos; i < s.length(); i++) {\n            if(dp[pos][i]) {\n                path.add(s.substring(pos,i+1));\n                helper(res, path, dp, s, i+1);\n                path.remove(path.size()-1);\n            }\n        }\n    }\n\n\n}\n\n"
  },
  {
    "path": "src/PalindromePermutationII267.java",
    "content": "/**\n * Given a string s, return all the palindromic permutations\n * (without duplicates) of it. Return an empty list if no palindromic\n * permutation could be form.\n * \n * Example 1:\n * Input: \"aabb\"\n * Output: [\"abba\", \"baab\"]\n * \n * Example 2:\n * Input: \"abc\"\n * Output: []\n */\n\n\npublic class PalindromePermutationII267 {\n    public List<String> generatePalindromes(String s) {\n        List<String> res = new ArrayList<>();\n        int[] map = new int[256];\n        int N = 0;\n        for (char ch: s.toCharArray()) {\n            map[ch]++;\n            N++;\n        }\n        StringBuilder sb = new StringBuilder();\n        int odd = -1;\n        for (int i=0; i<256; i++) {\n            if (map[i] % 2 != 0) {\n                if (odd != -1) return res;\n                odd = i;\n                sb.append((char) i);\n                map[i]--;\n            }\n        }\n        helper(map, 0, sb, res, N);\n        return res;\n    }\n\n    private void helper(int[] map, int curr, StringBuilder sb, List<String> res, int N) {\n        if (sb.length() == N) {\n            res.add(sb.toString());\n            return;\n        }\n        for (int i=0; i<256; i++) {\n            if (map[i] == 0) continue;\n            map[i] -= 2;\n            add(sb, (char) i);\n            helper(map, curr+1, sb, res, N);\n            remove(sb);\n            map[i] += 2;\n        }\n    }\n\n    private void add(StringBuilder sb, char ch) {\n        sb.append(ch);\n        sb.insert(0, ch);\n    }\n    \n    private void remove(StringBuilder sb) {\n        sb.deleteCharAt(0);\n        sb.deleteCharAt(sb.length()-1);\n    }\n\n}\n"
  },
  {
    "path": "src/PalindromicSubstrings647.java",
    "content": "/**\n * Given a string, your task is to count how many palindromic substrings in this string.\n *\n * The substrings with different start indexes or end indexes are counted as\n * different substrings even they consist of same characters.\n *\n * Example 1:\n * Input: \"abc\"\n * Output: 3\n * Explanation: Three palindromic strings: \"a\", \"b\", \"c\".\n *\n * Example 2:\n * Input: \"aaa\"\n * Output: 6\n * Explanation: Six palindromic strings: \"a\", \"a\", \"a\", \"aa\", \"aa\", \"aaa\".\n *\n * Note:\n * The input string length won't exceed 1000.\n *\n */\n\n\npublic class PalindromicSubstrings647 {\n    public int countSubstrings(String s) {\n        boolean[][] dp = new boolean[s.length()][s.length()];\n        int res = 0;\n        for (int l=0; l<s.length(); l++) {\n            dp[l][l] = true;\n            res++;\n        }\n\n        for (int j=1; j<s.length(); j++) {\n            for (int i=0; i<j; i++) {\n                boolean sameSide = s.charAt(i) == s.charAt(j);\n                boolean curr = (j == i+1) ? (sameSide) : (sameSide && dp[i+1][j-1]);\n                if (curr) res++;\n                dp[i][j] = curr;\n            }\n        }\n\n        return res;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/96884/very-simple-java-solution-with-detail-explanation/4\n     */\n    int count =1;\n    public int countSubstrings2(String s) {\n        if(s.length()==0)\n            return 0;\n        for(int i=0; i<s.length()-1; i++){\n            checkPalindrome(s,i,i);     //To check the palindrome of odd length palindromic sub-string\n            checkPalindrome(s,i,i+1);   //To check the palindrome of even length palindromic sub-string\n        }\n        return count;\n    }\n\n    private void checkPalindrome(String s, int i, int j) {\n        while(i>=0 && j<s.length() && s.charAt(i)==s.charAt(j)){    //Check for the palindrome string\n            count++;    //Increment the count if palindromin substring found\n            i--;    //To trace string in left direction\n            j++;    //To trace string in right direction\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/PartitionEqualSubsetSum416.java",
    "content": "/**\n * Given a non-empty array containing only positive integers, find if the array\n * can be partitioned into two subsets such that the sum of elements in both\n * subsets is equal.\n *\n * Note:\n * Each of the array element will not exceed 100.\n * The array size will not exceed 200.\n *\n * Example 1:\n *\n * Input: [1, 5, 11, 5]\n * Output: true\n * Explanation: The array can be partitioned as [1, 5, 5] and [11].\n *\n * Example 2:\n *\n * Input: [1, 2, 3, 5]\n * Output: false\n * Explanation: The array cannot be partitioned into equal sum subsets.\n *\n */\n\n\npublic class PartitionEqualSubsetSum416 {\n    public boolean canPartition(int[] nums) {\n        if (nums.length == 1) return nums[0] == 0;\n        int sum = 0;\n\n        for (int num : nums) {\n            sum += num;\n        }\n        if ((sum % 2) != 0) return false;\n\n        int half = sum / 2;\n        Queue<Integer> q = new LinkedList<>();\n        q.offer(0);\n        int i = 1;\n        int acc = nums[0];\n        while (!q.isEmpty() && i < nums.length) {\n            int curr = nums[i];\n            if (acc == half) {\n                return true;\n            } else if (acc < half) {\n                q.offer(i);\n                acc += curr;\n                i++;\n            } else {\n                i = q.poll();\n                acc -= nums[i];\n                i++;\n                if (i >= nums.length) {\n                    i = q.poll();\n                    acc -= nums[i];\n                    i++;\n                }\n            }\n        }\n\n        return false;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/62987/java-dynamic-programming-solution-21ms-with-explanation\n     */\n    public boolean canPartition2(int[] nums) {\n    \tint total = 0;\n    \tfor(int i : nums) total+=i; // compute the total sum of the input array\n    \tif(total%2 != 0) return false; // if the array sum is not even, we cannot partition it into 2 equal subsets\n    \tint max = total/2; // the maximum for a subset is total/2\n    \tint[][] results = new int[nums.length][max]; // integer matrix to store the results, so we don't have to compute it more than one time\n    \treturn isPartitionable(max,0,0,nums,results);\n    }\n\n    public boolean isPartitionable(int max,int curr, int index, int[] nums, int[][] results) {\n    \tif(curr>max || index>nums.length-1) return false; // if we passed the max, or we reached the end of the array, return false\n    \tif(curr==max) return true; // if we reached the goal (total/2) we found a possible partition\n    \tif(results[index][curr]==1) return true; // if we already computed teh result for the index i with the sum current, we retrieve this result (1 for true)\n    \tif(results[index][curr]==2) return false; // if we already computed teh result for the index i with the sum current, we retrieve this result (2 for false)\n    \tboolean res = isPartitionable(max, curr+nums[index], index+1, nums, results) || isPartitionable(max, curr, index+1, nums, results); // else try to find the equal partiion, taking this element, or not taking it\n    \tresults[index][curr] = res ? 1 : 2; // store the result for this index and this current sum, to use it in dynamic programming\n    \treturn res;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/67539/0-1-knapsack-detailed-explanation\n     */\n    public boolean canPartition3(int[] nums) {\n        int sum = 0;\n\n        for (int num : nums) {\n            sum += num;\n        }\n\n        if ((sum & 1) == 1) {\n            return false;\n        }\n        sum /= 2;\n\n        int n = nums.length;\n        boolean[][] dp = new boolean[n+1][sum+1];\n        for (int i = 0; i < dp.length; i++) {\n            Arrays.fill(dp[i], false);\n        }\n\n        dp[0][0] = true;\n\n        for (int i = 1; i < n+1; i++) {\n            dp[i][0] = true;\n        }\n        for (int j = 1; j < sum+1; j++) {\n            dp[0][j] = false;\n        }\n\n        for (int i = 1; i < n+1; i++) {\n            for (int j = 1; j < sum+1; j++) {\n                dp[i][j] = dp[i-1][j];\n                if (j >= nums[i-1]) {\n                    dp[i][j] = (dp[i][j] || dp[i-1][j-nums[i-1]]);\n                }\n            }\n        }\n\n        return dp[n][sum];\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/62312/java-solution-similar-to-backpack-problem-easy-to-understand\n     */\n    public boolean canPartition4(int[] nums) {\n        // check edge case\n        if (nums == null || nums.length == 0) {\n            return true;\n        }\n        // preprocess\n        int volumn = 0;\n        for (int num : nums) {\n            volumn += num;\n        }\n        if (volumn % 2 != 0) {\n            return false;\n        }\n        volumn /= 2;\n        // dp def\n        boolean[] dp = new boolean[volumn + 1];\n        // dp init\n        dp[0] = true;\n        // dp transition\n        for (int i = 1; i <= nums.length; i++) {\n            for (int j = volumn; j >= nums[i-1]; j--) {\n                dp[j] = dp[j] || dp[j - nums[i-1]];\n            }\n        }\n        return dp[volumn];\n    }\n\n\n}\n"
  },
  {
    "path": "src/PartitionLabels763.java",
    "content": "/**\n * A string S of lowercase letters is given. We want to partition this string\n * into as many parts as possible so that each letter appears in at most one\n * part, and return a list of integers representing the size of these parts.\n * \n * Example 1:\n * Input: S = \"ababcbacadefegdehijhklij\"\n * Output: [9,7,8]\n * Explanation:\n * The partition is \"ababcbaca\", \"defegde\", \"hijhklij\".\n * This is a partition so that each letter appears in at most one part.\n * A partition like \"ababcbacadefegde\", \"hijhklij\" is incorrect, because it\n * splits S into less parts.\n * \n * Note:\n * S will have length in range [1, 500].\n * S will consist of lowercase letters ('a' to 'z') only.\n */\n\npublic class PartitionLabels763 {\n    public List<Integer> partitionLabels(String S) {\n        char[] chars = S.toCharArray();\n        List<int[]> intervals = new ArrayList<>();\n        Map<Character, Integer> map = new HashMap<>();\n        int ii = 0;\n        int i = 0;\n        for (char c: chars) {\n            if (map.containsKey(c)) {\n                intervals.get(map.get(c))[1] = i;\n            } else {\n                map.put(c, ii++);\n                intervals.add(new int[]{i, i});\n            }\n            i++;\n        }\n        \n        List<Integer> res = new ArrayList<>();\n        int l = 0;\n        int r = 0;\n        for (int[] curr: intervals) {\n            if (curr[0] <= r) {\n                r = Math.max(curr[1], r);\n            } else {\n                res.add(r - l + 1);\n                l = curr[0];\n                r = curr[1];\n            }\n            \n        }\n        res.add(r - l + 1);\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/partition-labels/solution/\n     */\n    public List<Integer> partitionLabels2(String S) {\n        int[] last = new int[26];\n        for (int i = 0; i < S.length(); ++i)\n            last[S.charAt(i) - 'a'] = i;\n        \n        int j = 0, anchor = 0;\n        List<Integer> ans = new ArrayList();\n        for (int i = 0; i < S.length(); ++i) {\n            j = Math.max(j, last[S.charAt(i) - 'a']);\n            if (i == j) {\n                ans.add(i - anchor + 1);\n                anchor = i + 1;\n            }\n        }\n        return ans;\n    }\n\n\n}\n"
  },
  {
    "path": "src/PartitionList86.java",
    "content": "/**\n * Given a linked list and a value x, partition it such that all nodes less\n * than x come before nodes greater than or equal to x.\n *\n * You should preserve the original relative order of the nodes in each of the two partitions.\n *\n * For example,\n * Given 1->4->3->2->5->2 and x = 3,\n * return 1->2->2->4->3->5.\n */\n\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\n\npublic class PartitionList86 {\n    public ListNode partition(ListNode head, int x) {\n        if (head == null) {\n            return null;\n        }\n        ListNode left = null;\n        ListNode leftEnd = null;\n        ListNode right = null;\n        ListNode rightEnd = null;\n\n        while (head != null) {\n            if (head.val < x) {\n                if (left == null) {\n                    left = new ListNode(head.val);\n                } else if (leftEnd == null) {\n                    leftEnd = new ListNode(head.val);\n                    left.next = leftEnd;\n                } else {\n                    leftEnd.next = new ListNode(head.val);\n                    leftEnd = leftEnd.next;\n                }\n            } else {\n                if (right == null) {\n                    right = new ListNode(head.val);\n                } else if (rightEnd == null) {\n                    rightEnd = new ListNode(head.val);\n                    right.next = rightEnd;\n                } else {\n                    rightEnd.next = new ListNode(head.val);\n                    rightEnd = rightEnd.next;\n                }\n            }\n            head = head.next;\n        }\n\n        if (leftEnd != null){\n            leftEnd.next = right;\n            return left;\n        } else if (left != null) {\n            left.next = right;\n            return left;\n        } else {\n            return right;\n        }\n\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/23951/java-solution-pick-out-larger-nodes-and-append-to-the-end\n     */\n    public ListNode partition(ListNode head, int x) {\n        if(head==null || head.next==null) return head;\n\n        ListNode l1 = new ListNode(0);\n        ListNode l2 = new ListNode(0);\n        ListNode p1=l1, p2=l2;\n\n        p1.next = head;\n        while(p1.next!=null) {\n            // keep moving larger node to list 2;\n\n            if(p1.next.val>=x) {\n                ListNode tmp = p1.next;\n                p1.next = tmp.next;\n\n                p2.next = tmp;\n                p2 = p2.next;\n            }\n            else {\n                p1 = p1.next;\n            }\n        }\n\n        // conbine lists 1 and 2;\n        p2.next = null;\n        p1.next = l2.next;\n        return l1.next;\n    }\n\n\n}\n"
  },
  {
    "path": "src/PartitionToKEqualSumSubsets698.java",
    "content": "/**\n * Given an array of integers nums and a positive integer k, find whether it's\n * possible to divide this array into k non-empty subsets whose sums are all\n * equal.\n * \n * Example 1:\n * Input: nums = [4, 3, 2, 3, 5, 2, 1], k = 4\n * Output: True\n * Explanation: It's possible to divide it into 4 subsets\n * (5), (1, 4), (2,3), (2,3) with equal sums.\n * \n * Note:\n * 1 <= k <= len(nums) <= 16.\n * 0 < nums[i] < 10000.\n */\n\npublic class PartitionToKEqualSumSubsets698 {\n    public boolean canPartitionKSubsets(int[] nums, int k) {\n        int sum = 0;\n        int N = nums.length;\n        for (int i=0; i<N; i++) {\n            sum += nums[i];\n        }\n        if (sum % k != 0) return false;\n        int target = sum / k;\n        boolean[] visited = new boolean[N];\n        return valid(nums, visited, 0, 0, target, k, N);\n    }\n\n    private boolean valid(int[] nums, boolean[] visited, int start, int curr, int target, int k, int N) {\n        if (k == 1) return true;\n        if (curr == target) return valid(nums, visited, 0, 0, target, k-1, N);\n        for (int i=start; i<N; i++) {\n            if (visited[i]) continue;\n            visited[i] = true;\n            if (valid(nums, visited, i, curr + nums[i], target, k, N)) return true;\n            visited[i] = false;\n        }\n        return false;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/partition-to-k-equal-sum-subsets/solution/\n     */\n    public boolean canPartitionKSubsets2(int[] nums, int k) {\n        int N = nums.length;\n        Arrays.sort(nums);\n        int sum = Arrays.stream(nums).sum();\n        int target = sum / k;\n        if (sum % k > 0 || nums[N - 1] > target) return false;\n\n        boolean[] dp = new boolean[1 << N];\n        dp[0] = true;\n        int[] total = new int[1 << N];\n\n        for (int state = 0; state < (1 << N); state++) {\n            if (!dp[state]) continue;\n            for (int i = 0; i < N; i++) {\n                int future = state | (1 << i);\n                if (state != future && !dp[future]) {\n                    if (nums[i] <= target - (total[state] % target)) {\n                        dp[future] = true;\n                        total[future] = total[state] + nums[i];\n                    } else {\n                        break;\n                    }\n                }\n            }\n        }\n        return dp[(1 << N) - 1];\n    }\n\n\n    /**\n     * https://leetcode.com/problems/partition-to-k-equal-sum-subsets/solution/\n     */\n    public boolean search(int[] groups, int row, int[] nums, int target) {\n        if (row < 0) return true;\n        int v = nums[row--];\n        for (int i = 0; i < groups.length; i++) {\n            if (groups[i] + v <= target) {\n                groups[i] += v;\n                if (search(groups, row, nums, target)) return true;\n                groups[i] -= v;\n            }\n            if (groups[i] == 0) break;\n        }\n        return false;\n    }\n\n    public boolean canPartitionKSubsets3(int[] nums, int k) {\n        int sum = Arrays.stream(nums).sum();\n        if (sum % k > 0) return false;\n        int target = sum / k;\n\n        Arrays.sort(nums);\n        int row = nums.length - 1;\n        if (nums[row] > target) return false;\n        while (row >= 0 && nums[row] == target) {\n            row--;\n            k--;\n        }\n        return search(new int[k], row, nums, target);\n    }\n\n}\n"
  },
  {
    "path": "src/PascalsTriangleII119.java",
    "content": "/**\n * Given a non-negative index k where k ≤ 33, return the kth index row of the\n * Pascal's triangle.\n * \n * Note that the row index starts from 0.\n * https://upload.wikimedia.org/wikipedia/commons/0/0d/PascalTriangleAnimated2.gif\n * \n * In Pascal's triangle, each number is the sum of the two numbers directly above it.\n * \n * Example:\n * Input: 3\n * Output: [1,3,3,1]\n * \n * Follow up:\n * Could you optimize your algorithm to use only O(k) extra space?\n */\n\npublic class PascalsTriangleII119 {\n    public List<Integer> getRow(int rowIndex) {\n        LinkedList<Integer> res = new LinkedList<>();\n        res.add(1);\n        if (rowIndex == 0) return res;\n        res.add(1);\n        if (rowIndex == 1) return res;\n\n        int i = 2;\n        while (i <= rowIndex) {\n            int size = res.size();\n            res.add(1);\n            int pre = res.removeFirst();\n            for (int j=0; j<size-1; j++) {\n                int now = res.removeFirst();\n                res.add(pre + now);\n                pre = now;\n            }\n            res.add(1);\n            i++;\n        }\n\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/pascals-triangle-ii/discuss/38420/Here-is-my-brief-O(k)-solution\n     */\n    public List<Integer> getRow2(int rowIndex) {\n        long nCk = 1;\n        List<Integer> result = new ArrayList<Integer>();\n        for(int i=0;i<=rowIndex;i++){\n            result.add((int)nCk);\n            nCk = nCk *(rowIndex-i)/(i+1);\n        }\n        return result;\n    }\n\n}\n"
  },
  {
    "path": "src/PatchingArray330.java",
    "content": "/**\n * Given a sorted positive integer array nums and an integer n, add/patch\n * elements to the array such that any number in range [1, n] inclusive can\n * be formed by the sum of some elements in the array. Return the minimum\n * number of patches required.\n * \n * Example 1:\n * Input: nums = [1,3], n = 6\n * Output: 1 \n * Explanation:\n * Combinations of nums are [1], [3], [1,3], which form possible sums of: 1, 3, 4.\n * Now if we add/patch 2 to nums, the combinations are: [1], [2], [3], [1,3], [2,3], [1,2,3].\n * Possible sums are 1, 2, 3, 4, 5, 6, which now covers the range [1, 6].\n * So we only need 1 patch.\n * \n * Example 2:\n * Input: nums = [1,5,10], n = 20\n * Output: 2\n * Explanation: The two patches can be [2, 4].\n * \n * Example 3:\n * Input: nums = [1,2,2], n = 5\n * Output: 0\n */\n\n/**\n * https://leetcode.com/problems/patching-array/discuss/280183/Detailed-Explanation-with-Example\n */\npublic class PatchingArray330 {\n    public int minPatches(int[] nums, int n) {\n        long patch = 0;\n        int count = 0;\n        int index = 0;\n        while (patch < n) {\n            if (index < nums.length && patch + 1 >= nums[index]) {\n                patch += nums[index];\n                index++;\n            } else {\n                patch += (patch + 1);\n                count++;\n            }\n        }\n        return count;\n    }\n}\n"
  },
  {
    "path": "src/PathSum112.java",
    "content": "/**\n * Given a binary tree and a sum, determine if the tree has a root-to-leaf path\n * such that adding up all the values along the path equals the given sum.\n *\n * For example:\n * Given the below binary tree and sum = 22,\n *               5\n *              / \\\n *             4   8\n *            /   / \\\n *           11  13  4\n *          /  \\      \\\n *         7    2      1\n * return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.\n */\n\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\n\n\n\npublic class PathSum112 {\n    public boolean hasPathSum(TreeNode root, int sum) {\n        return sum(root, sum, 0);\n    }\n\n    private boolean sum(TreeNode root, int sum, int sumForNow) {\n        if (root == null) {\n            return false;\n        }\n\n        sumForNow += root.val;\n\n        if (sumForNow == sum && root.left == null && root.right == null) {\n            return true;\n        }\n\n        if (sum(root.left, sum, sumForNow)) {\n            return true;\n        }\n\n        return sum(root.right, sum, sumForNow);\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/3149/accepted-my-recursive-solution-in-java\n     */\n     public boolean hasPathSum2(TreeNode root, int sum) {\n         if(root == null) return false;\n\n         if(root.left == null && root.right == null && sum - root.val == 0) return true;\n\n         return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);\n     }\n\n}\n"
  },
  {
    "path": "src/PathSumII113.java",
    "content": "/**\n * Given a binary tree and a sum, find all root-to-leaf paths where each path's\n * sum equals the given sum.\n * \n * Note: A leaf is a node with no children.\n * \n * Example:\n * \n * Given the below binary tree and sum = 22,\n * \n *       5\n *      / \\\n *     4   8\n *    /   / \\\n *   11  13  4\n *  /  \\    / \\\n * 7    2  5   1\n * Return:\n * \n * [\n *    [5,4,11,2],\n *    [5,8,4,5]\n * ]\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class PathSumII113 {\n    public List<List<Integer>> pathSum(TreeNode root, int sum) {\n        List<List<Integer>> res = new ArrayList<>();\n        pathSum(root, 0, sum, new ArrayList<>(), res);\n        return res;\n    }\n\n    private void pathSum(TreeNode root, int sumSoFar, int target, List<Integer> path, List<List<Integer>> res) {\n        if (root == null) return;\n        int newSum = sumSoFar + root.val;\n        path.add(root.val);\n        if (root.left == null && root.right == null) {\n            if (newSum == target) res.add(new ArrayList<>(path));\n            path.remove(path.size() - 1);\n            return;\n        }\n        pathSum(root.left, newSum, target, path, res);\n        pathSum(root.right, newSum, target, path, res);\n        path.remove(path.size() - 1);\n    }\n\n}\n"
  },
  {
    "path": "src/PathSumIII437.java",
    "content": "/**\n * You are given a binary tree in which each node contains an integer value.\n * \n * Find the number of paths that sum to a given value.\n * \n * The path does not need to start or end at the root or a leaf, but it must go\n * downwards (traveling only from parent nodes to child nodes).\n * \n * The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.\n * \n * Example:\n *  * \n * root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8\n * \n *       10\n *      /  \\\n *     5   -3\n *    / \\    \\\n *   3   2   11\n *  / \\   \\\n * 3  -2   1\n * \n * Return 3. The paths that sum to 8 are:\n * \n * 1.  5 -> 3\n * 2.  5 -> 2 -> 1\n * 3. -3 -> 11\n * \n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class PathSumIII437 {\n    public int pathSum(TreeNode root, int sum) {\n        int[] res = new int[1];\n        pathSum(root, sum, res, new ArrayList<>());\n        return res[0];\n    }\n\n    private void pathSum(TreeNode root, int target, int[] res, List<Integer> path) {\n        if (root == null) return;\n        int last = path.isEmpty() ? root.val : path.get(path.size() - 1) + root.val;\n        if (last == target) res[0]++;\n        for (int s: path) {\n            if (last - s == target) {\n                res[0]++;\n            }\n        }\n        path.add(last);\n        pathSum(root.left, target, res, path);\n        pathSum(root.right, target, res, path);\n        path.remove(path.size() - 1);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/path-sum-iii/discuss/91878/17-ms-O(n)-java-Prefix-sum-method\n     */\n    public int pathSum2(TreeNode root, int sum) {\n        HashMap<Integer, Integer> preSum = new HashMap();\n        preSum.put(0,1);\n        return helper(root, 0, sum, preSum);\n    }\n\n    public int helper(TreeNode root, int currSum, int target, HashMap<Integer, Integer> preSum) {\n        if (root == null) {\n            return 0;\n        }\n        \n        currSum += root.val;\n        int res = preSum.getOrDefault(currSum - target, 0);\n        preSum.put(currSum, preSum.getOrDefault(currSum, 0) + 1);\n        res += helper(root.left, currSum, target, preSum) + helper(root.right, currSum, target, preSum);\n        preSum.put(currSum, preSum.get(currSum) - 1);\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/PeekingIterator284.java",
    "content": "/**\n * Given an Iterator class interface with methods: next() and hasNext(), design\n * and implement a PeekingIterator that support the peek() operation -- it\n * essentially peek() at the element that will be returned by the next call to\n * next().\n * \n * Example:\n * Assume that the iterator is initialized to the beginning of the list: [1,2,3].\n * \n * Call next() gets you 1, the first element in the list.\n * Now you call peek() and it returns 2, the next element. Calling next() after\n * that still return 2. \n * You call next() the final time and it returns 3, the last element. \n * Calling hasNext() after that should return false.\n * \n * Follow up: How would you extend your design to be generic and work with all\n * types, not just integer?\n */\n\n\npublic class PeekingIterator284 {\n    // Java Iterator interface reference:\n    // https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html\n    class PeekingIterator implements Iterator<Integer> {\n        private Integer next;\n        private Iterator<Integer> iterator;\n        \n        public PeekingIterator(Iterator<Integer> iterator) {\n            // initialize any member here.\n            this.iterator = iterator;\n            if (this.iterator.hasNext()) {\n                this.next = this.iterator.next();\n            }\n        }\n\n          // Returns the next element in the iteration without advancing the iterator.\n        public Integer peek() {\n              return next;\n        }\n\n        // hasNext() and next() should behave the same as in the Iterator interface.\n        // Override them if needed.\n        @Override\n        public Integer next() {\n            Integer returned = next;\n            if (iterator.hasNext()) {\n                next = iterator.next();\n            } else {\n                next = null;\n            }\n            return returned;\n        }\n\n        @Override\n        public boolean hasNext() {\n            return next != null;\n        }\n    }\n\n}\n\n\n"
  },
  {
    "path": "src/PerfectSquares279.java",
    "content": "/**\n * Given a positive integer n, find the least number of perfect square numbers\n * (for example, 1, 4, 9, 16, ...) which sum to n.\n *\n * For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13,\n * return 2 because 13 = 4 + 9.\n *\n */\n\n\npublic class PerfectSquares279 {\n    public int numSquares(int n) {\n        int[] dp = new int[n+1];\n        dp[0] = 0;\n        dp[1] = 1;\n        for (int i=2; i<=n; i++) {\n            int sq = (int) Math.sqrt(i);\n            int curr = Integer.MAX_VALUE;\n            for (int j=sq; j>=1; j--) {\n                curr = Math.min(curr, dp[i-j*j]+1);\n            }\n            dp[i] = curr;\n        }\n        return dp[n];\n    }\n\n\n    public static void main(String[] args) {\n        PerfectSquares279 ps = new PerfectSquares279();\n        System.out.println(ps.numSquares(12));\n        System.out.println(ps.numSquares(13));\n\n    }\n\n}\n"
  },
  {
    "path": "src/PermutationInString567.java",
    "content": "/**\n * Given two strings s1 and s2, write a function to return true if s2 contains\n * the permutation of s1. In other words, one of the first string's\n * permutations is the substring of the second string.\n * \n * Example 1:\n * Input:s1 = \"ab\" s2 = \"eidbaooo\"\n * Output:True\n * Explanation: s2 contains one permutation of s1 (\"ba\").\n * \n * Example 2:\n * Input:s1= \"ab\" s2 = \"eidboaoo\"\n * Output: False\n * \n * Note:\n * The input strings only contain lower case letters.\n * The length of both given strings is in range [1, 10,000].\n */\n\npublic class PermutationInString567 {\n    public boolean checkInclusion(String s1, String s2) {\n        if (s1 == null || s2 == null || s1.length() > s2.length()) return false;\n        int[] map = new int[26];\n        int M = 0;\n        for (char c: s1.toCharArray()) {\n            if (map[c - 'a'] == 0) M++;\n            map[c - 'a']++;\n        }\n        char[] chars2 =  s2.toCharArray();\n        int N2 = s2.length();\n        int N1 = s1.length();\n        int left = 0;\n        int right = 0;\n        while (right < N2) {\n            char rc = chars2[right++];\n            map[rc - 'a']--;\n            if (map[rc - 'a'] == 0) M--;\n            if (M == 0) return true;\n            if (right - left == N1) {\n                char lc = chars2[left++];\n                if (map[lc - 'a'] == 0) M++;\n                map[lc - 'a']++;\n            }\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "src/PermutationSequence60.java",
    "content": "/**\n * The set [1,2,3,...,n] contains a total of n! unique permutations.\n * \n * By listing and labeling all of the permutations in order, we get the\n * following sequence for n = 3:\n * \n * \"123\"\n * \"132\"\n * \"213\"\n * \"231\"\n * \"312\"\n * \"321\"\n * \n * Given n and k, return the kth permutation sequence.\n * \n * Note:\n * Given n will be between 1 and 9 inclusive.\n * Given k will be between 1 and n! inclusive.\n * \n * Example 1:\n * Input: n = 3, k = 3\n * Output: \"213\"\n * \n * Example 2:\n * Input: n = 4, k = 9\n * Output: \"2314\"\n */\n\npublic class PermutationSequence60 {\n    public String getPermutation(int n, int k) {\n        StringBuilder sb = new StringBuilder();\n        int[] count = new int[1];\n        boolean[] used = new boolean[n];\n        helper(sb, n, k, count, used);\n        return sb.toString();\n    }\n\n    private boolean helper(StringBuilder sb, int n, int k, int[] count, boolean[] used) {\n        if (sb.length() == n) {\n            count[0]++;\n            return count[0] == k;\n        }\n        for (int i=0; i<n; i++) {\n            if (used[i]) continue;\n            sb.append((char) (i + '1'));\n            used[i] = true;\n            if (helper(sb, n, k, count, used)) return true;\n            sb.deleteCharAt(sb.length() - 1);\n            used[i] = false;\n        }\n        return count[0] == k;\n    }\n\n\n    public String getPermutation2(int n, int k) {\n        int[] factors = new int[n];\n        List<Integer> list = new ArrayList<>();\n        for (int i=0; i<n; i++) {\n            if (i == 0) {\n                factors[0] = 1;\n            } else {\n                factors[i] = factors[i-1] * i;\n            }\n            list.add(i+1);\n        }\n        StringBuilder sb = new StringBuilder();\n        k--;\n        for (int i=n; i>0; i--) {\n            int idx = k / factors[i - 1];\n            k = k % factors[i - 1];\n            int val = list.get(idx);\n            list.remove(idx);\n            sb.append(val);\n        }\n        return sb.toString();\n    }\n\n}\n"
  },
  {
    "path": "src/Permutations46.java",
    "content": "/**\n * Given a collection of distinct numbers, return all possible permutations.\n *\n * For example,\n * [1,2,3] have the following permutations:\n * [\n *   [1,2,3],\n *   [1,3,2],\n *   [2,1,3],\n *   [2,3,1],\n *   [3,1,2],\n *   [3,2,1]\n * ]\n */\n\n\nimport java.util.Arrays;\nimport java.util.ArrayList;\nimport java.util.List;\n\n\npublic class Permutations46 {\n    public List<List<Integer>> permute(int[] nums) {\n        List<List<Integer>> results = new ArrayList<>();\n        List<Integer> result = new ArrayList<>();\n        boolean[] selected = new boolean[nums.length];\n\n        helper(results, result, nums, nums.length, selected);\n\n        return results;\n    }\n\n    private void helper(List<List<Integer>> results, List<Integer> result, int[] nums, int length, boolean[] selected) {\n        if (result.size() == length) {\n            results.add(new ArrayList<>(result));\n            return;\n        }\n        for (int i = 0; i < length; i++) {\n            if (!selected[i]) {\n                result.add(nums[i]);\n                selected[i] = true;\n                helper(results, result, nums, length, selected);\n                result.remove(result.size() - 1);\n                selected[i] = false;\n            }\n        }\n    }\n\n\n    /**\n     * In this way, we are not using selected, saved space, but increased time!\n     * result.contains(nums[i]) is with time O(n); but selected[i] = true is O(1)\n     */\n    public List<List<Integer>> permute2(int[] nums) {\n        List<List<Integer>> results = new ArrayList<>();\n        List<Integer> result = new ArrayList<>();\n\n        helper(results, result, nums, nums.length);\n\n        return results;\n    }\n\n    private void helper(List<List<Integer>> results, List<Integer> result, int[] nums, int length) {\n        if (result.size() == length) {\n            results.add(new ArrayList<>(result));\n            return;\n        }\n        for (int i = 0; i < length; i++) {\n            if (!result.contains(nums[i])) {\n                result.add(nums[i]);\n                helper(results, result, nums, length);\n                result.remove(result.size() - 1);\n            }\n        }\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/6377/my-ac-simple-iterative-java-python-solution\n     */\n    public List<List<Integer>> permute3(int[] num) {\n        List<List<Integer>> ans = new ArrayList<List<Integer>>();\n        if (num.length ==0) return ans;\n        List<Integer> l0 = new ArrayList<Integer>();\n        l0.add(num[0]);\n        ans.add(l0);\n        for (int i = 1; i< num.length; ++i){\n            List<List<Integer>> new_ans = new ArrayList<List<Integer>>();\n            for (int j = 0; j<=i; ++j){\n                for (List<Integer> l : ans){\n                    List<Integer> new_l = new ArrayList<Integer>(l);\n                    new_l.add(j,num[i]);\n                    new_ans.add(new_l);\n                }\n            }\n            ans = new_ans;\n        }\n        return ans;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/23036/java-clean-code-two-recursive-solutions\n     */\n    public List<List<Integer>> permute4(int[] nums) {\n     \t\tList<List<Integer>> permutations = new ArrayList<>();\n     \t\tif (nums.length == 0) {\n     \t\t\t  return permutations;\n     \t\t}\n\n     \t\tcollectPermutations(nums, 0, new ArrayList<>(), permutations);\n     \t\treturn permutations;\n    }\n\n   \tprivate void collectPermutations(int[] nums, int start, List<Integer> permutation,\n    \t\tList<List<Integer>>  permutations) {\n\n     \t\tif (permutation.size() == nums.length) {\n       \t\t\tpermutations.add(permutation);\n       \t\t\treturn;\n     \t\t}\n\n     \t\tfor (int i = 0; i <= permutation.size(); i++) {\n     \t\t\t  List<Integer> newPermutation = new ArrayList<>(permutation);\n     \t\t\t  newPermutation.add(i, nums[start]);\n     \t\t\t  collectPermutations(nums, start + 1, newPermutation, permutations);\n     \t\t}\n   \t}\n\n\n    /**\n     * https://discuss.leetcode.com/topic/42417/2ms-java-solution-beats-93-i-think-it-could-be-optimized\n     */\n    public List<List<Integer>> permute5(int[] nums) {\n        List<List<Integer>> result = new ArrayList<List<Integer>>();\n      \tperm(result, nums, 0, nums.length - 1);\n      \treturn result;\n    }\n    public static void perm(List<List<Integer>> result, int[] nums, int start, int end){\n      \tif(start == end){\n        \t\tInteger[] ele = new Integer[nums.length];\n        \t\tfor(int i = 0; i < nums.length; i++){\n        \t\t\t  ele[i] = nums[i];\n        \t\t}\n        \t\tresult.add(Arrays.asList(ele));\n      \t}\n      \telse{\n        \t\tfor(int i = start; i <= end; i++){\n          \t\t\tint temp = nums[start];\n          \t\t\tnums[start] = nums[i];\n          \t\t\tnums[i] = temp;\n\n          \t\t\tperm(result, nums, start + 1, end);\n\n          \t\t\ttemp = nums[start];\n          \t\t\tnums[start] = nums[i];\n          \t\t\tnums[i] = temp;\n        \t\t}\n      \t}\n    }\n\n\n    public List<List<Integer>> permute6(int[] nums) {\n        List<List<Integer>> result = new ArrayList<List<Integer>>();\n      \tperm(result, nums, 0);\n      \treturn result;\n    }\n\n    private static void perm(List<List<Integer>> result, int[] nums, int start){\n      \tif (start == nums.length-1) {\n            Integer[] ele = new Integer[nums.length];\n            for(int i = 0; i < nums.length; i++){\n                ele[i] = nums[i];\n            }\n            result.add(Arrays.asList(ele));\n            return;\n        }\n        for (int i = start; i < nums.length; i++){\n            swap(nums, start, i);\n            perm(result, nums, start + 1);\n            swap(nums, start, i);\n        }\n    }\n\n    private static void swap(int[] nums, int i, int j) {\n        int temp = nums[i];\n        nums[i] = nums[j];\n        nums[j] = temp;\n    }\n\n}\n"
  },
  {
    "path": "src/PermutationsII47.java",
    "content": "/**\n * Given a collection of numbers that might contain duplicates, return all\n * possible unique permutations.\n *\n * For example,\n * [1,1,2] have the following unique permutations:\n * [\n *   [1,1,2],\n *   [1,2,1],\n *   [2,1,1]\n * ]\n *\n */\n\npublic class PermutationsII47 {\n    public List<List<Integer>> permuteUnique(int[] nums) {\n        Arrays.sort(nums);\n        Set<List<Integer>> result = new HashSet<>();\n        perm(result, nums, 0);\n        List<List<Integer>> res = new ArrayList<>();\n        for (List<Integer> l: result) res.add(l);\n        return res;\n    }\n\n    private static void perm(Set<List<Integer>> result, int[] nums, int start){\n        if (start == nums.length-1) {\n            Integer[] ele = new Integer[nums.length];\n            for(int i = 0; i < nums.length; i++){\n                ele[i] = nums[i];\n            }\n            result.add(Arrays.asList(ele));\n            return;\n        }\n        int pre = nums[start];\n        for (int i = start; i < nums.length; i++) {\n            if (start != i && (nums[start] == nums[i] || pre == nums[i])) continue;\n            pre = nums[i];\n            swap(nums, start, i);\n            perm(result, nums, start + 1);\n            swap(nums, start, i);\n        }\n    }\n\n    private static void swap(int[] nums, int i, int j) {\n        int temp = nums[i];\n        nums[i] = nums[j];\n        nums[j] = temp;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/permutations-ii/discuss/18648/Share-my-Java-code-with-detailed-explanantion\n     */\n    public List<List<Integer>> permuteUnique2(int[] nums) {\n        Arrays.sort(nums);\n        List<List<Integer>> result = new ArrayList<>();\n      \tperm(result, nums, 0);\n      \treturn result;\n    }\n\n    private static void perm(List<List<Integer>> result, int[] nums, int start){\n      \tif (start == nums.length-1) {\n            Integer[] ele = new Integer[nums.length];\n            for(int i = 0; i < nums.length; i++){\n                ele[i] = nums[i];\n            }\n            result.add(Arrays.asList(ele));\n            return;\n        }\n        Set<Integer> seen = new HashSet<>();\n        for (int i = start; i < nums.length; i++) {\n            if (seen.add(nums[i])) {\n                swap(nums, start, i);\n                perm(result, nums, start + 1);\n                swap(nums, start, i);\n            }\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/permutations-ii/discuss/18594/Really-easy-Java-solution-much-easier-than-the-solutions-with-very-high-vote\n     */\n    public List<List<Integer>> permuteUnique3(int[] nums) {\n        List<List<Integer>> res = new ArrayList<List<Integer>>();\n        if(nums==null || nums.length==0) return res;\n        boolean[] used = new boolean[nums.length];\n        List<Integer> list = new ArrayList<Integer>();\n        Arrays.sort(nums);\n        dfs(nums, used, list, res);\n        return res;\n    }\n\n    public void dfs(int[] nums, boolean[] used, List<Integer> list, List<List<Integer>> res){\n        if(list.size()==nums.length){\n            res.add(new ArrayList<Integer>(list));\n            return;\n        }\n        for(int i=0;i<nums.length;i++){\n            if(used[i]) continue;\n            if(i>0 &&nums[i-1]==nums[i] && !used[i-1]) continue;\n            used[i]=true;\n            list.add(nums[i]);\n            dfs(nums,used,list,res);\n            used[i]=false;\n            list.remove(list.size()-1);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/permutations-ii/discuss/18601/Short-iterative-Java-solution\n     */\n    public List<List<Integer>> permuteUnique4s(int[] num) {\n        LinkedList<List<Integer>> res = new LinkedList<>();\n        res.add(new ArrayList<>());\n        for (int i = 0; i < num.length; i++) {\n            Set<String> cache = new HashSet<>();\n            while (res.peekFirst().size() == i) {\n                List<Integer> l = res.removeFirst();\n                for (int j = 0; j <= l.size(); j++) {\n                    List<Integer> newL = new ArrayList<>(l.subList(0,j));\n                    newL.add(num[i]);\n                    newL.addAll(l.subList(j,l.size()));\n                    if (cache.add(newL.toString())) res.add(newL);\n                }\n            }\n        }\n        return res;\n    }\n\n\n}\n"
  },
  {
    "path": "src/PlusOne66.java",
    "content": "/**\n * Given a non-negative integer represented as a non-empty array of digits,\n * plus one to the integer.\n *\n * You may assume the integer do not contain any leading zero, except the\n * number 0 itself.\n *\n * The digits are stored such that the most significant digit is at the head\n * of the list.\n */\n\npublic class PlusOne66 {\n    public int[] plusOne(int[] digits) {\n        int[] res = new int[digits.length+1];\n        int c = 1;\n        for (int i=digits.length-1; i>=0; i--) {\n            int s = digits[i] + c;\n            c = s / 10;\n            res[i+1] = s % 10;\n        }\n        res[0] = c;\n        return (res[0] != 0) ? res : Arrays.copyOfRange(res, 1, res.length);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/plus-one/discuss/24082/My-Simple-Java-Solution\n     */\n    public int[] plusOne2(int[] digits) {\n        int n = digits.length;\n        for(int i=n-1; i>=0; i--) {\n            if(digits[i] < 9) {\n                digits[i]++;\n                return digits;\n            }\n            digits[i] = 0;\n        }\n        int[] newNumber = new int [n+1];\n        newNumber[0] = 1;\n        return newNumber;\n    }\n\n}\n"
  },
  {
    "path": "src/PlusOneLinkedList369.java",
    "content": "/**\n * Given a non-negative integer represented as non-empty a singly linked list\n * of digits, plus one to the integer.\n * \n * You may assume the integer do not contain any leading zero, except the\n * number 0 itself.\n * \n * The digits are stored such that the most significant digit is at the head\n * of the list.\n * \n * Example:\n * Input:\n * 1->2->3\n * \n * Output:\n * 1->2->4\n */\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\npublic class PlusOneLinkedList369 {\n    public ListNode plusOne(ListNode head) {\n        if (head == null) return null;\n        int carry = helper(head);\n        if (carry == 0) return head;\n        ListNode h = new ListNode(carry);\n        h.next = head;\n        return h;\n    }\n\n    public int helper(ListNode head) {\n        if (head == null) return 1;\n        int carry = helper(head.next);\n        int sum = carry + head.val;\n        head.val = sum % 10;\n        return sum / 10;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/plus-one-linked-list/discuss/84150/Two-Pointers-Java-Solution:-O(n)-time-O(1)-space\n     */\n    public ListNode plusOne2(ListNode head) {\n        ListNode dummy = new ListNode(0);\n        dummy.next = head;\n        ListNode i = dummy;\n        ListNode j = dummy;\n\n        while (j.next != null) {\n            j = j.next;\n            if (j.val != 9) {\n                i = j;\n            }\n        }\n        // i = index of last non-9 digit\n    \n        i.val++;\n        i = i.next;\n        while (i != null) {\n            i.val = 0;\n            i = i.next;\n        }\n        \n        if (dummy.val == 0) return dummy.next;\n        return dummy;\n    }\n\n}\n"
  },
  {
    "path": "src/Point.java",
    "content": "public class Point {\n    int x;\n    int y;\n    Point() { x = 0; y = 0; }\n    Point(int a, int b) { x = a; y = b; }\n}\n"
  },
  {
    "path": "src/PopulatingNextRightPointersInEachNode116.java",
    "content": "/**\n * Given a binary tree\n *\n *     struct TreeLinkNode {\n *       TreeLinkNode *left;\n *       TreeLinkNode *right;\n *       TreeLinkNode *next;\n *     }\n * Populate each next pointer to point to its next right node. If there is no\n * next right node, the next pointer should be set to NULL.\n *\n * Initially, all next pointers are set to NULL.\n *\n * Note:\n * You may only use constant extra space.\n * You may assume that it is a perfect binary tree (ie, all leaves are at the\n * same level, and every parent has two children).\n *\n *\n * For example,\n * Given the following perfect binary tree,\n *          1\n *        /  \\\n *       2    3\n *      / \\  / \\\n *     4  5  6  7\n * After calling your function, the tree should look like:\n *          1 -> NULL\n *        /  \\\n *       2 -> 3 -> NULL\n *      / \\  / \\\n *     4->5->6->7 -> NULL\n *\n */\n\n\n/**\n * Definition for binary tree with next pointer.\n * public class TreeLinkNode {\n *     int val;\n *     TreeLinkNode left, right, next;\n *     TreeLinkNode(int x) { val = x; }\n * }\n */\n\n\npublic class PopulatingNextRightPointersInEachNode116 {\n    public void connect(TreeLinkNode root) {\n        if (root == null || (root.left == null && root.right == null)) return;\n        LinkedList<TreeLinkNode> q = new LinkedList<>();\n        q.add(root.left);\n        q.add(root.right);\n\n        int num = 2;\n        while (!q.isEmpty()) {\n            TreeLinkNode pre = q.remove();\n            if (pre == null) return;\n            q.add(pre.left);\n            q.add(pre.right);\n            int i = 0;\n            if (q.isEmpty()) return;\n            while (i<num-1) {\n                TreeLinkNode now = q.remove();\n                if (now == null) return;\n                q.add(now.left);\n                q.add(now.right);\n                pre.next = now;\n                pre = now;\n                i++;\n            }\n            num <<= 1;\n        }\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/6221/java-solution-with-o-1-memory-o-n-time\n     */\n    public void connect2(TreeLinkNode root) {\n        TreeLinkNode level_start=root;\n        while(level_start!=null){\n            TreeLinkNode cur=level_start;\n            while(cur!=null){\n                if(cur.left!=null) cur.left.next=cur.right;\n                if(cur.right!=null && cur.next!=null) cur.right.next=cur.next.left;\n\n                cur=cur.next;\n            }\n            level_start=level_start.left;\n        }\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/12241/my-recursive-solution-java\n     */\n    public void connect3(TreeLinkNode root) {\n        if(root == null)\n            return;\n\n        if(root.left != null){\n            root.left.next = root.right;\n            if(root.next != null)\n                root.right.next = root.next.left;\n        }\n\n        connect3(root.left);\n        connect3(root.right);\n    }\n\n\n    public void connect4(TreeLinkNode root) {\n        if (root == null) return;\n        LinkedList<TreeLinkNode> level = new LinkedList<>();\n        level.add(root);\n        connect(level);\n    }\n\n    private void connect(LinkedList<TreeLinkNode> level) {\n        LinkedList<TreeLinkNode> newLevel = new LinkedList<>();\n        if (level.isEmpty()) return;\n        while (!level.isEmpty()) {\n            TreeLinkNode n = level.remove();\n            if (n == null) return;\n            n.next = level.peek();\n            if (n.left != null) {\n                newLevel.add(n.left);\n                newLevel.add(n.right);\n            }\n        }\n\n        connect(newLevel);\n    }\n\n}\n"
  },
  {
    "path": "src/PopulatingNextRightPointersInEachNodeII117.java",
    "content": "/**\n * Follow up for problem \"Populating Next Right Pointers in Each Node\".\n *\n * What if the given tree could be any binary tree? Would your previous\n * solution still work?\n *\n * Note:\n *\n * You may only use constant extra space.\n * For example,\n * Given the following binary tree,\n *          1\n *        /  \\\n *       2    3\n *      / \\    \\\n *     4   5    7\n * After calling your function, the tree should look like:\n *          1 -> NULL\n *        /  \\\n *       2 -> 3 -> NULL\n *      / \\    \\\n *     4-> 5 -> 7 -> NULL\n */\n\n/**\n * Definition for binary tree with next pointer.\n * public class TreeLinkNode {\n *     int val;\n *     TreeLinkNode left, right, next;\n *     TreeLinkNode(int x) { val = x; }\n * }\n */\n\npublic class PopulatingNextRightPointersInEachNodeII117 {\n    public void connect(TreeLinkNode root) {\n        if (root == null) return;\n        LinkedList<TreeLinkNode> level = new LinkedList<>();\n        level.add(root);\n        connect(level);\n    }\n\n    private void connect(LinkedList<TreeLinkNode> level) {\n        LinkedList<TreeLinkNode> newLevel = new LinkedList<>();\n        if (level.isEmpty()) return;\n        while (!level.isEmpty()) {\n            TreeLinkNode n = level.remove();\n            if (n == null) return;\n            n.next = level.peek();\n            if (n.left != null) newLevel.add(n.left);\n            if (n.right != null) newLevel.add(n.right);\n        }\n\n        connect(newLevel);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/discuss/37811/Simple-solution-using-constant-space/35836\n     */\n    public void connect2(TreeLinkNode root) {\n        TreeLinkNode tempChild = new TreeLinkNode(0);\n        while (root != null) {\n            TreeLinkNode currentChild = tempChild;\n            while (root != null) {\n                if (root.left != null) {\n                    currentChild.next = root.left;\n                    currentChild = currentChild.next;\n                }\n                if (root.right != null) {\n                    currentChild.next = root.right;\n                    currentChild = currentChild.next;\n                }\n                root = root.next;\n            }\n            root = tempChild.next;\n            tempChild.next = null;\n        }\n    }\n\n\n    public void connect3(TreeLinkNode root) {\n        if (root == null) return;\n        Queue<TreeLinkNode> q = new LinkedList<>();\n        q.add(root);\n        while (!q.isEmpty()) {\n            int size = q.size();\n            TreeLinkNode pre = q.remove();\n            if (pre.left != null) q.add(pre.left);\n            if (pre.right != null) q.add(pre.right);\n            TreeLinkNode curr = null;\n            for (int i=1; i<size; i++) {\n                curr = q.remove();\n                if (curr.left != null) q.add(curr.left);\n                if (curr.right != null) q.add(curr.right);\n                pre.next = curr;\n                pre = curr;\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/PossibleBipartition886.java",
    "content": "/**\n * Given a set of N people (numbered 1, 2, ..., N), we would like to split\n * everyone into two groups of any size.\n * \n * Each person may dislike some other people, and they should not go into the\n * same group. \n * \n * Formally, if dislikes[i] = [a, b], it means it is not allowed to put the\n * people numbered a and b into the same group.\n * \n * Return true if and only if it is possible to split everyone into two groups\n * in this way.\n * \n * Example 1:\n * Input: N = 4, dislikes = [[1,2],[1,3],[2,4]]\n * Output: true\n * Explanation: group1 [1,4], group2 [2,3]\n * \n * Example 2:\n * Input: N = 3, dislikes = [[1,2],[1,3],[2,3]]\n * Output: false\n *\n * Example 3:\n * Input: N = 5, dislikes = [[1,2],[2,3],[3,4],[4,5],[1,5]]\n * Output: false\n * \n * Note:\n * 1 <= N <= 2000\n * 0 <= dislikes.length <= 10000\n * 1 <= dislikes[i][j] <= N\n * dislikes[i][0] < dislikes[i][1]\n * There does not exist i != j for which dislikes[i] == dislikes[j].\n */\n\npublic class PossibleBipartition886 {\n    public boolean possibleBipartition(int N, int[][] dislikes) {\n        Set<Integer>[] nonGraph = new Set[N+1];\n        for (int[] d: dislikes) {\n            if (nonGraph[d[0]] == null) {\n                nonGraph[d[0]] = new HashSet<>();\n            }\n            if (nonGraph[d[1]] == null) {\n                nonGraph[d[1]] = new HashSet<>();\n            }\n            nonGraph[d[0]].add(d[1]);\n            nonGraph[d[1]].add(d[0]);\n        }\n\n        int[] visited = new int[N+1];\n        for (int i=1; i<=N; i++) {\n            if (visited[i] == 0) {\n                if (!helper(i, nonGraph, N, visited, 1)) return false;\n            }\n        }\n        return true;\n    }\n\n    private boolean helper(int curr, Set<Integer>[] nonGraph, int N, int[] visited, int pre) {\n        if (visited[curr] != 0) return visited[curr] == pre;\n        visited[curr] = pre;\n        if (nonGraph[curr] == null) return true;\n        for (int next: nonGraph[curr]) {\n            if (visited[next] == pre) return false;\n            if (visited[next] == 0) {\n                if (!helper(next, nonGraph, N, visited, -pre)) return false;\n            }\n        }\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/possible-bipartition/discuss/159085/java-graph\n     */\n    public boolean possibleBipartition2(int N, int[][] dislikes) {\n        Set<Integer>[] nonGraph = new Set[N+1];\n        for (int[] d: dislikes) {\n            if (nonGraph[d[0]] == null) {\n                nonGraph[d[0]] = new HashSet<>();\n            }\n            if (nonGraph[d[1]] == null) {\n                nonGraph[d[1]] = new HashSet<>();\n            }\n            nonGraph[d[0]].add(d[1]);\n            nonGraph[d[1]].add(d[0]);\n        }\n\n        int[] visited = new int[N+1];\n        for (int i=1; i<=N; i++) {\n            if (visited[i] == 0) {\n                visited[i] = 1;\n                Queue<Integer> q = new LinkedList<>();\n                q.add(i);\n                while (!q.isEmpty()) {\n                    int curr = q.poll();\n                    if (nonGraph[curr] == null) continue;\n                    for (int next: nonGraph[curr]) {\n                        if (visited[next] == 0) {\n                            visited[next] = -visited[curr];\n                            q.add(next);\n                        } else {\n                            if (visited[next] == visited[curr]) return false;\n                        }\n                    }\n                }\n            }\n        }\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "src/PowXN50.java",
    "content": "/**\n * Implement pow(x, n), which calculates x raised to the power n (xn).\n * \n * Example 1:\n * Input: 2.00000, 10\n * Output: 1024.00000\n * \n * Example 2:\n * Input: 2.10000, 3\n * Output: 9.26100\n * \n * Example 3:\n * Input: 2.00000, -2\n * Output: 0.25000\n * Explanation: 2-2 = 1/22 = 1/4 = 0.25\n * \n * Note:\n * -100.0 < x < 100.0\n * n is a 32-bit signed integer, within the range [−231, 231 − 1]\n */\n\npublic class PowXN50 {\n    /**\n     * https://leetcode.com/problems/powx-n/solution/\n     */\n    public double myPow(double x, int n) {\n        long N = n;\n        if (N < 0) {\n            x = 1 / x;\n            N = -N;\n        }\n        return fastPow(x, N);\n    }\n\n    private double fastPow(double x, long n) {\n        if (n == 0) {\n            return 1.0;\n        }\n        double half = fastPow(x, n / 2);\n        if (n % 2 == 0) {\n            return half * half;\n        } else {\n            return half * half * x;\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/powx-n/solution/\n     */\n    public double myPow2(double x, int n) {\n        long N = n;\n        if (N < 0) {\n            x = 1 / x;\n            N = -N;\n        }\n        double ans = 1;\n        double current_product = x;\n        for (long i = N; i > 0; i /= 2) {\n            if ((i % 2) == 1) {\n                ans = ans * current_product;\n            }\n            current_product = current_product * current_product;\n        }\n        return ans;\n    }\n\n}\n"
  },
  {
    "path": "src/PowerOfTwo231.java",
    "content": "/**\n * Given an integer, write a function to determine if it is a power of two.\n * \n * Example 1:\n * Input: 1\n * Output: true \n * Explanation: 2^0 = 1\n * \n * Example 2:\n * Input: 16\n * Output: true\n * Explanation: 2^4 = 16\n * \n * Example 3:\n * Input: 218\n * Output: false\n */\n\npublic class PowerOfTwo231 {\n    public boolean isPowerOfTwo(int n) {\n        if (n <= 0) return false;\n        while (n > 1) {\n            if (n % 2 != 0) return false;\n            n /= 2;\n        }\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/power-of-two/discuss/63974/Using-nand(n-1)-trick\n     */\n    public boolean isPowerOfTwo2(int n) {\n        if (n<=0) return false;\n        return (n & (n-1)) == 0;\n    }\n\n}\n"
  },
  {
    "path": "src/PredictTheWinner486.java",
    "content": "/**\n * Given an array of scores that are non-negative integers. Player 1 picks one\n * of the numbers from either end of the array followed by the player 2 and\n * then player 1 and so on. Each time a player picks a number, that number will\n * not be available for the next player. This continues until all the scores\n * have been chosen. The player with the maximum score wins.\n * \n * Given an array of scores, predict whether player 1 is the winner. You can\n * assume each player plays to maximize his score.\n * \n * Example 1:\n * Input: [1, 5, 2]\n * Output: False\n * Explanation: Initially, player 1 can choose between 1 and 2. \n * If he chooses 2 (or 1), then player 2 can choose from 1 (or 2) and 5. If\n * player 2 chooses 5, then player 1 will be left with 1 (or 2). \n * So, final score of player 1 is 1 + 2 = 3, and player 2 is 5. \n * Hence, player 1 will never be the winner and you need to return False.\n * \n * Example 2:\n * Input: [1, 5, 233, 7]\n * Output: True\n * Explanation: Player 1 first chooses 1. Then player 2 have to choose between\n * 5 and 7. No matter which number player 2 choose, player 1 can choose 233.\n * Finally, player 1 has more score (234) than player 2 (12), so you need to\n * return True representing player1 can win.\n * \n * Note:\n * 1 <= length of the array <= 20.\n * Any scores in the given array are non-negative integers and will not exceed\n * 10,000,000.\n * If the scores of both players are equal, then player 1 is still the winner.\n */\n\npublic class PredictTheWinner486 {\n    public boolean PredictTheWinner(int[] nums) {\n        if (nums.length <= 1) return true;\n        int sum = 0;\n        for (int n: nums) sum += n;\n        int player1 = helper(nums, 0, 0, nums.length - 1, true);\n        return player1 >= (sum - player1);\n    }\n\n    private int helper(int[] nums, int p1, int left, int right, boolean turn1) {\n        if (left == right) return p1 + (turn1 ? nums[left] : 0);\n        if (turn1) {\n            p1 += nums[left];\n            int a = helper(nums, p1, left+1, right, false);\n            p1 -= nums[left];\n            p1 += nums[right];\n            int b = helper(nums, p1, left, right-1, false);\n            p1 -= nums[right];\n            return Math.max(a, b);\n        } else {\n            int a = helper(nums, p1, left+1, right, true);\n            int b = helper(nums, p1, left, right-1, true);\n            return Math.min(a, b);\n        }\n    }\n\n\n    public boolean PredictTheWinner2(int[] nums) {\n        if (nums.length <= 1) return true;\n        int sum = 0;\n        for (int n: nums) sum += n;\n        int player1 = helper(nums, 0, nums.length - 1, true);\n        return player1 >= (sum - player1);\n    }\n\n    private int helper(int[] nums, int left, int right, boolean turn1) {\n        if (left == right) return turn1 ? nums[left] : 0;\n\n        if (turn1) {\n            int a = nums[left] + helper(nums, left+1, right, false);\n            int b = nums[right] + helper(nums, left, right-1, false);\n            return Math.max(a, b);\n        } else {\n            int a = helper(nums, left+1, right, true);\n            int b = helper(nums, left, right-1, true);\n            return Math.min(a, b);\n        }\n    }\n\n\n    public boolean PredictTheWinner3(int[] nums) {\n        if (nums.length <= 1) return true;\n        int sum = 0;\n        for (int n: nums) sum += n;\n        int[][][] mem = new int[2][nums.length][nums.length];\n        int player1 = helper(nums, 0, nums.length - 1, true, mem);\n        return player1 >= (sum - player1);\n    }\n\n    private int helper(int[] nums, int left, int right, boolean turn1, int[][][] mem) {\n        if (left == right) return turn1 ? nums[left] : 0;\n\n        if (turn1) {\n            if (mem[0][left][right] > 0) return mem[0][left][right];\n            int a = nums[left] + helper(nums, left+1, right, false, mem);\n            int b = nums[right] + helper(nums, left, right-1, false, mem);\n            mem[0][left][right] = Math.max(a, b);\n            return Math.max(a, b);\n        } else {\n            if (mem[1][left][right] > 0) return mem[1][left][right];\n            int a = helper(nums, left+1, right, true, mem);\n            int b = helper(nums, left, right-1, true, mem);\n            mem[1][left][right] = Math.min(a, b);\n            return Math.min(a, b);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/predict-the-winner/solution/\n     */\n    public boolean PredictTheWinner4(int[] nums) {\n        Integer[][] memo = new Integer[nums.length][nums.length];\n        return winner(nums, 0, nums.length - 1, memo) >= 0;\n    }\n\n    public int winner(int[] nums, int s, int e, Integer[][] memo) {\n        if (s == e)\n            return nums[s];\n        if (memo[s][e] != null)\n            return memo[s][e];\n        int a = nums[s] - winner(nums, s + 1, e, memo);\n        int b = nums[e] - winner(nums, s, e - 1, memo);\n        memo[s][e] = Math.max(a, b);\n        return memo[s][e];\n    }\n\n\n    /**\n     * https://leetcode.com/problems/predict-the-winner/solution/\n     */\n    public boolean PredictTheWinner5(int[] nums) {\n        int[][] dp = new int[nums.length + 1][nums.length];\n        for (int s = nums.length; s >= 0; s--) {\n            for (int e = s + 1; e < nums.length; e++) {\n                int a = nums[s] - dp[s + 1][e];\n                int b = nums[e] - dp[s][e - 1];\n                dp[s][e] = Math.max(a, b);\n            }\n        }\n        return dp[0][nums.length - 1] >= 0;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/predict-the-winner/solution/\n     */\n    public boolean PredictTheWinner6(int[] nums) {\n        int[] dp = new int[nums.length];\n        for (int s = nums.length; s >= 0; s--) {\n            for (int e = s + 1; e < nums.length; e++) {\n                int a = nums[s] - dp[e];\n                int b = nums[e] - dp[e - 1];\n                dp[e] = Math.max(a, b);\n            }\n        }\n        return dp[nums.length - 1] >= 0;\n    }\n\n}\n"
  },
  {
    "path": "src/ProductOfArrayExceptSelf238.java",
    "content": "/**\n * Given an array nums of n integers where n > 1,  return an array output such\n * that output[i] is equal to the product of all the elements of nums except\n * nums[i].\n * \n * Example:\n * Input:  [1,2,3,4]\n * Output: [24,12,8,6]\n * \n * Note: Please solve it without division and in O(n).\n * \n * Follow up:\n * Could you solve it with constant space complexity? (The output array does\n * not count as extra space for the purpose of space complexity analysis.)\n */\n\n\npublic class ProductOfArrayExceptSelf238 {\n    public int[] productExceptSelf(int[] nums) {\n        if (nums == null || nums.length == 0) return new int[0];\n        int[] L = new int[nums.length];\n        int[] R = new int[nums.length];\n        L[0] = 1;\n        for (int i=1; i<nums.length; i++) L[i] = L[i-1] * nums[i-1];\n        R[nums.length-1] = 1;\n        for (int i=nums.length-2; i>=0; i--) R[i] = R[i+1] * nums[i+1];\n        int[] res = new int[nums.length];\n        for (int i=0; i<nums.length; i++) res[i] = L[i] * R[i];\n        return res;\n    }\n\n\n    public int[] productExceptSelf2(int[] nums) {\n        if (nums == null || nums.length == 0) return new int[0];\n        int[] res = new int[nums.length];\n        \n        int sum = 1;\n        for (int i=0; i<nums.length; i++) {\n            res[i] = sum;\n            sum = sum * nums[i];\n        }\n        sum = 1;\n        for (int i=nums.length-1; i>=0; i--) {\n            res[i] = res[i] * sum;\n            sum = sum * nums[i];\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/ProfitableSchemes879.java",
    "content": "/**\n * There are G people in a gang, and a list of various crimes they could commit.\n * \n * The i-th crime generates a profit[i] and requires group[i] gang members to\n * participate.\n * \n * If a gang member participates in one crime, that member can't participate in\n * another crime.\n * \n * Let's call a profitable scheme any subset of these crimes that generates at\n * least P profit, and the total number of gang members participating in that\n * subset of crimes is at most G.\n * \n * How many schemes can be chosen?  Since the answer may be very large, return\n * ∂it modulo 10^9 + 7.\n * \n * Example 1:\n * Input: G = 5, P = 3, group = [2,2], profit = [2,3]\n * Output: 2\n * Explanation: \n * To make a profit of at least 3, the gang could either commit crimes 0 and 1,\n * or just crime 1.\n * In total, there are 2 schemes.\n * \n * Example 2:\n * Input: G = 10, P = 5, group = [2,3,5], profit = [6,7,8]\n * Output: 7\n * Explanation: \n * To make a profit of at least 5, the gang could commit any crimes, as long\n * as they commit one.\n * \n * There are 7 possible schemes: (0), (1), (2), (0,1), (0,2), (1,2), and (0,1,2).\n * \n * Note:\n * 1 <= G <= 100\n * 0 <= P <= 100\n * 1 <= group[i] <= 100\n * 0 <= profit[i] <= 100\n * 1 <= group.length = profit.length <= 100\n */\n\npublic class ProfitableSchemes879 {\n\n    public int profitableSchemes(int G, int P, int[] group, int[] profit) {\n        int K = group.length;\n        int[][][] dp = new int[K + 1][P + 1][G + 1];\n        dp[0][0][0] = 1;\n        int mod = (int)1e9 + 7;\n        for (int k=1; k<=K; k++) {\n            int pk = profit[k-1];\n            int gk = group[k-1];\n            for (int i=0; i<=P; i++) {\n                for (int j=0; j<=G; j++) {\n                    dp[k][i][j] = (dp[k-1][i][j] +  (j < gk ? 0 : dp[k-1][Math.max(0, i-pk)][j - gk])) % mod;\n                }\n            }\n        }\n        \n        int res = 0;\n        for (int a: dp[K][P]) {\n            res = (res + a) % mod;\n        }\n        return res;\n    }\n\n\n    public int profitableSchemes2(int G, int P, int[] group, int[] profit) {\n        int K = group.length;\n        int[][] dp = new int[P + 1][G + 1];\n        dp[0][0] = 1;\n        int mod = (int)1e9 + 7;\n        for (int k=1; k<=K; k++) {\n            int pk = profit[k-1];\n            int gk = group[k-1];\n            \n            int[][] tmp = new int[P + 1][G + 1];\n            for (int i=0; i<=P; i++) {\n                for (int j=0; j<=G; j++) {\n                    tmp[i][j] = dp[i][j];\n                }\n            }\n            \n            for (int i=0; i<=P; i++) {\n                for (int j=0; j<=G; j++) {\n                    dp[i][j] = (tmp[i][j] +  (j < gk ? 0 : tmp[Math.max(0, i-pk)][j - gk])) % mod;\n                }\n            }\n        }\n        \n        int res = 0;\n        for (int a: dp[P]) {\n            res = (res + a) % mod;\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/profitable-schemes/solution/\n     */\n    public int profitableSchemes3(int G, int P, int[] group, int[] profit) {\n        int MOD = 1_000_000_007;\n        int N = group.length;\n        long[][][] dp = new long[2][P+1][G+1];\n        dp[0][0][0] = 1;\n\n        for (int i = 0; i < N; ++i) {\n            int p0 = profit[i];  // the current crime profit\n            int g0 = group[i];  // the current crime group size\n\n            long[][] cur = dp[i % 2];\n            long[][] cur2 = dp[(i + 1) % 2];\n\n            // Deep copy cur into cur2\n            for (int jp = 0; jp <= P; ++jp)\n                for (int jg = 0; jg <= G; ++jg)\n                    cur2[jp][jg] = cur[jp][jg];\n\n            for (int p1 = 0; p1 <= P; ++p1) {  // p1 : the current profit\n                // p2 : the new profit after committing this crime\n                int p2 = Math.min(p1 + p0, P);\n                for (int g1 = 0; g1 <= G - g0; ++g1) {  // g1 : the current group size\n                    // g2 : the new group size after committing this crime\n                    int g2 = g1 + g0;\n                    cur2[p2][g2] += cur[p1][g1];\n                    cur2[p2][g2] %= MOD;\n                }\n            }\n        }\n\n        // Sum all schemes with profit P and group size 0 <= g <= G.\n        long ans = 0;\n        for (long x: dp[N%2][P])\n            ans += x;\n\n        return (int) (ans % MOD);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/profitable-schemes/discuss/154617/C++JavaPython-DP\n     */\n    public int profitableSchemes4(int G, int P, int[] group, int[] profit) {\n        int[][] dp = new int[P + 1][G + 1];\n        dp[0][0] = 1;\n        int res = 0, mod = (int)1e9 + 7;\n        for (int k = 0; k < group.length; k++) {\n            int g = group[k], p = profit[k];\n            for (int i = P; i >= 0; i--)\n                for (int j = G - g; j >= 0; j--)\n                    dp[Math.min(i + p, P)][j + g] = (dp[Math.min(i + p, P)][j + g] + dp[i][j]) % mod;\n        }\n        for (int x : dp[P]) res = (res + x) % mod;\n        return res;\n    }\n\n\n    /**\n     * https://www.youtube.com/watch?v=MjOIR61txFc\n     */\n    public int profitableSchemes5(int G, int P, int[] group, int[] profit) {\n        int K = group.length;\n        int[][] dp = new int[P + 1][G + 1];\n        dp[0][0] = 1;\n        int mod = (int)1e9 + 7;\n        for (int k=1; k<=K; k++) {\n            int pk = profit[k-1];\n            int gk = group[k-1];\n            for (int i=P; i>=0; i--) {\n                int ip = Math.min(P, i + pk);\n                for (int j=G-gk; j>=0; j--) {\n                    dp[ip][j+gk] = (dp[ip][j+gk] + dp[i][j]) % mod;\n                }\n            }\n        }\n\n        int res = 0;\n        for (int a: dp[P]) {\n            res = (res + a) % mod;\n        }\n        return res;\n    }\n\n\n}\n"
  },
  {
    "path": "src/ProjectionAreaOf3DShapes887.java",
    "content": "/**\n * On a N * N grid, we place some 1 * 1 * 1 cubes that are axis-aligned with the x, y, and z axes.\n * \n * Each value v = grid[i][j] represents a tower of v cubes placed on top of grid cell (i, j).\n * \n * Now we view the projection of these cubes onto the xy, yz, and zx planes.\n * \n * A projection is like a shadow, that maps our 3 dimensional figure to a 2 dimensional plane. \n * \n * Here, we are viewing the \"shadow\" when looking at the cubes from the top, the front, and the side.\n * \n * Return the total area of all three projections.\n * \n * Example 1:\n * Input: [[2]]\n * Output: 5\n * \n * Example 2:\n * Input: [[1,2],[3,4]]\n * Output: 17\n * Explanation: \n * Here are the three projections (\"shadows\") of the shape made with each axis-aligned plane.\n * https://s3-lc-upload.s3.amazonaws.com/uploads/2018/08/02/shadow.png\n * \n * Example 3:\n * Input: [[1,0],[0,2]]\n * Output: 8\n * \n * Example 4:\n * Input: [[1,1,1],[1,0,1],[1,1,1]]\n * Output: 14\n * \n * Example 5:\n * Input: [[2,2,2],[2,1,2],[2,2,2]]\n * Output: 21\n * \n * Note:\n * 1 <= grid.length = grid[0].length <= 50\n * 0 <= grid[i][j] <= 50\n */\n\n\npublic class ProjectionAreaOf3DShapes887 {\n    public int projectionArea(int[][] grid) {\n        int M = grid.length;\n        int N = grid[0].length;\n        int top = 0;\n        int side = 0;\n        int[] maxFront = new int[N];\n\n        for (int i=0; i<M; i++) {\n            int rowMax = 0;\n            for (int j=0; j<N; j++) {\n                int now = grid[i][j];\n                if (now > 0) top++;\n                if (now > rowMax) rowMax = now;\n                if (now > maxFront[j]) maxFront[j] = now;\n            }\n            side += rowMax;\n        }\n\n        int front = 0;\n        for (int col: maxFront) {\n            front += col;\n        }\n        return top + front + side;\n    }\n\n}\n"
  },
  {
    "path": "src/QuadTreeIntersection558.java",
    "content": "/**\n * A quadtree is a tree data in which each internal node has exactly four\n * children: topLeft, topRight, bottomLeft and bottomRight. Quad trees are\n * often used to partition a two-dimensional space by recursively subdividing\n * it into four quadrants or regions.\n * \n * We want to store True/False information in our quad tree. The quad tree is\n * used to represent a N * N boolean grid. For each node, it will be\n * subdivided into four children nodes until the values in the region it\n * represents are all the same. Each node has another two boolean attributes:\n * isLeaf and val. isLeaf is true if and only if the node is a leaf node.\n * The val attribute for a leaf node contains the value of the region it\n * represents.\n * \n * For example, below are two quad trees A and B:\n * \n * A:\n * +-------+-------+   T: true\n * |       |       |   F: false\n * |   T   |   T   |\n * |       |       |\n * +-------+-------+\n * |       |       |\n * |   F   |   F   |\n * |       |       |\n * +-------+-------+\n * topLeft: T\n * topRight: T\n * bottomLeft: F\n * bottomRight: F\n * \n * B:               \n * +-------+---+---+\n * |       | F | F |\n * |   T   +---+---+\n * |       | T | T |\n * +-------+---+---+\n * |       |       |\n * |   T   |   F   |\n * |       |       |\n * +-------+-------+\n * topLeft: T\n * topRight:\n *      topLeft: F\n *      topRight: F\n *      bottomLeft: T\n *      bottomRight: T\n * bottomLeft: T\n * bottomRight: F \n * \n * Your task is to implement a function that will take two quadtrees and return\n * a quadtree that represents the logical OR (or union) of the two trees.\n * \n * A:                 B:                 C (A or B):\n * +-------+-------+  +-------+---+---+  +-------+-------+\n * |       |       |  |       | F | F |  |       |       |\n * |   T   |   T   |  |   T   +---+---+  |   T   |   T   |\n * |       |       |  |       | T | T |  |       |       |\n * +-------+-------+  +-------+---+---+  +-------+-------+\n * |       |       |  |       |       |  |       |       |\n * |   F   |   F   |  |   T   |   F   |  |   T   |   F   |\n * |       |       |  |       |       |  |       |       |\n * +-------+-------+  +-------+-------+  +-------+-------+\n * \n * Note:\n * Both A and B represent grids of size N * N.\n * N is guaranteed to be a power of 2.\n * If you want to know more about the quad tree, you can refer to its wiki.\n * The logic OR operation is defined as this: \"A or B\" is true if A is true, or\n * if B is true, or if both A and B are true.\n */\n\n/*\n// Definition for a QuadTree node.\nclass Node {\n    public boolean val;\n    public boolean isLeaf;\n    public Node topLeft;\n    public Node topRight;\n    public Node bottomLeft;\n    public Node bottomRight;\n\n    public Node() {}\n\n    public Node(boolean _val,boolean _isLeaf,Node _topLeft,Node _topRight,Node _bottomLeft,Node _bottomRight) {\n        val = _val;\n        isLeaf = _isLeaf;\n        topLeft = _topLeft;\n        topRight = _topRight;\n        bottomLeft = _bottomLeft;\n        bottomRight = _bottomRight;\n    }\n};\n*/\n\npublic class QuadTreeIntersection558 {\n    public Node intersect(Node quadTree1, Node quadTree2) {\n        if (quadTree1 == null || quadTree2 == null) {\n            return null;\n        }\n\n        Node res = new Node();\n        if (quadTree1.isLeaf && quadTree2.isLeaf) {\n            res.isLeaf = true;\n            res.val = quadTree1.val || quadTree2.val;\n            return res;\n        }\n\n        res.topLeft = intersect(getTopLeft(quadTree1), getTopLeft(quadTree2));\n        res.topRight = intersect(getTopRight(quadTree1), getTopRight(quadTree2));\n        res.bottomLeft = intersect(getBottomLeft(quadTree1), getBottomLeft(quadTree2));\n        res.bottomRight = intersect(getBottomRight(quadTree1), getBottomRight(quadTree2));\n\n        if (allLeaves(res) && allSame(res)) {\n            res.isLeaf = true;\n            res.val = res.topLeft.val;\n            return res;\n        }\n        return res;\n    }\n\n    private Node getTopLeft(Node n) {\n        return n.isLeaf ? n : n.topLeft;\n    }\n\n    private Node getTopRight(Node n) {\n        return n.isLeaf ? n : n.topRight;\n    }\n\n    private Node getBottomLeft(Node n) {\n        return n.isLeaf ? n : n.bottomLeft;\n    }\n\n    private Node getBottomRight(Node n) {\n        return n.isLeaf ? n : n.bottomRight;\n    }\n\n    private boolean allLeaves(Node n) {\n        return n.topLeft.isLeaf &&\n            n.topRight.isLeaf &&\n            n.bottomLeft.isLeaf &&\n            n.bottomRight.isLeaf;\n    }\n\n    private boolean allSame(Node n) {\n        return (n.topLeft.val == n.topRight.val) &&\n                (n.bottomLeft.val && n.bottomRight.val) &&\n                (n.topLeft.val && n.bottomLeft.val);\n    }\n\n\n    public Node intersect2(Node q1, Node q2) {\n        if (q1.isLeaf) return q1.val ? q1 : q2;\n        if (q2.isLeaf) return q2.val ? q2 : q1;\n        q1.topLeft = intersect(q1.topLeft, q2.topLeft);\n        q1.topRight = intersect(q1.topRight, q2.topRight);\n        q1.bottomLeft = intersect(q1.bottomLeft, q2.bottomLeft);\n        q1.bottomRight = intersect(q1.bottomRight, q2.bottomRight);\n        if (allLeaves(q1) && allSame(q1)) {\n            q1.isLeaf = true;\n            q1.val = q1.topLeft.val;\n        }\n        return q1;\n    }\n\n}\n\n"
  },
  {
    "path": "src/QueueReconstructionByHeight406.java",
    "content": "/**\n * Suppose you have a random list of people standing in a queue. Each person\n * is described by a pair of integers (h, k), where h is the height of the\n * person and k is the number of people in front of this person who have a\n * height greater than or equal to h. Write an algorithm to reconstruct the\n * queue.\n *\n * Note:\n * The number of people is less than 1,100.\n *\n *\n * Example\n *\n * Input:\n * [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]\n *\n * Output:\n * [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]\n *\n */\n\n\npublic class QueueReconstructionByHeight406 {\n    public int[][] reconstructQueue(int[][] people) {\n        int y = people.length;\n        if (y == 0) return people;\n\n        Arrays.sort(people, new SortRule());\n\n        LinkedList<int[]> res = new LinkedList<>();\n        for(int[] p: people){\n            res.add(p[1], p);\n        }\n\n        return res.toArray(new int[people.length][]);\n    }\n\n    class SortRule implements Comparator<int[]> {\n        @Override\n        public int compare(int[] a, int[] b) {\n            int diff = a[0] - b[0];\n            if (diff < 0) return 1;\n            else if (diff > 0) return -1;\n            else return a[1] - b[1];\n        }\n    }\n}\n"
  },
  {
    "path": "src/RandomFlipMatrix519.java",
    "content": "/**\n * You are given the number of rows n_rows and number of columns n_cols of a\n * 2D binary matrix where all values are initially 0. Write a function flip\n * which chooses a 0 value uniformly at random, changes it to 1, and then\n * returns the position [row.id, col.id] of that value. Also, write a function\n * reset which sets all values back to 0. Try to minimize the number of calls\n * to system's Math.random() and optimize the time and space complexity.\n * \n * Note:\n * 1 <= n_rows, n_cols <= 10000\n * 0 <= row.id < n_rows and 0 <= col.id < n_cols\n * flip will not be called when the matrix has no 0 values left.\n * the total number of calls to flip and reset will not exceed 1000.\n * \n * Example 1:\n * Input: \n * [\"Solution\",\"flip\",\"flip\",\"flip\",\"flip\"]\n * [[2,3],[],[],[],[]]\n * Output: [null,[0,1],[1,2],[1,0],[1,1]]\n * \n * Example 2:\n * Input: \n * [\"Solution\",\"flip\",\"flip\",\"reset\",\"flip\"]\n * [[1,2],[],[],[],[]]\n * Output: [null,[0,0],[0,1],null,[0,0]]\n * Explanation of Input Syntax:\n * The input is two lists: the subroutines called and their arguments.\n * Solution's constructor has two arguments, n_rows and n_cols. flip and\n * reset have no arguments. Arguments are always wrapped with a list, even\n * if there aren't any.\n */\n\npublic class RandomFlipMatrix519 {\n    /**\n     * https://leetcode.com/problems/random-flip-matrix/discuss/154053/Java-AC-Solution-call-Least-times-of-Random.nextInt()-function\n     */\n    class Solution {\n        private Map<Integer, Integer> map = new HashMap<>();\n        private int size;\n        private int N;\n        private int nCols;\n        private Random rand = new Random();\n    \n        public Solution(int n_rows, int n_cols) {\n            this.N = n_rows * n_cols;\n            this.nCols = n_cols;\n            this.size = this.N;        \n        }\n        \n        public int[] flip() {\n            int idx = rand.nextInt(this.size--);\n            int val = map.getOrDefault(idx, idx);\n            map.put(idx, map.getOrDefault(this.size, this.size));\n            return new int[]{val / this.nCols, val % this.nCols};\n        }\n        \n        public void reset() {\n            map.clear();\n            this.size = this.N;\n        }\n    }\n    \n\n    class Solution2 {\n        private int N;\n        private int nCols;\n        private Random rand = new Random();\n        private Set<Integer> set = new HashSet<>();\n    \n        public Solution(int n_rows, int n_cols) {\n            this.N = n_rows * n_cols;\n            this.nCols = n_cols;\n            // this.size = this.N;        \n        }\n        \n        public int[] flip() {\n            int val = rand.nextInt(this.N);\n            while (set.contains(val)) {\n                val = rand.nextInt(this.N);\n            }\n            set.add(val);\n            return new int[]{val / this.nCols, val % this.nCols};\n        }\n        \n        public void reset() {\n            this.set.clear();\n        }\n    }\n\n\n/**\n * Your Solution object will be instantiated and called as such:\n * Solution obj = new Solution(n_rows, n_cols);\n * int[] param_1 = obj.flip();\n * obj.reset();\n */\n\n\n}\n\n"
  },
  {
    "path": "src/RandomListNode.java",
    "content": "\npublic class RandomListNode {\n    int label;\n    RandomListNode next, random;\n    RandomListNode(int x) { this.label = x; }\n}\n"
  },
  {
    "path": "src/RandomPickIndex398.java",
    "content": "/**\n * Given an array of integers with possible duplicates, randomly output the\n * index of a given target number. You can assume that the given target number\n * must exist in the array.\n * \n * Note:\n * The array size can be very large. Solution that uses too much extra space\n * will not pass the judge.\n * \n * Example:\n * \n * int[] nums = new int[] {1,2,3,3,3};\n * Solution solution = new Solution(nums);\n * \n * // pick(3) should return either index 2, 3, or 4 randomly. Each index\n * should have equal probability of returning.\n * solution.pick(3);\n * \n * // pick(1) should return 0. Since in the array only nums[0] is equal to 1.\n * solution.pick(1);\n */\n\npublic class RandomPickIndex398 {\n\n    class Solution {\n        private Map<Integer, List<Integer>> map = new HashMap<>();\n        private Random rand = new Random();\n        public Solution(int[] nums) {\n            for (int i=0; i<nums.length; i++) {\n                if (!map.containsKey(nums[i])) {\n                    map.put(nums[i], new ArrayList<>());\n                }\n                map.get(nums[i]).add(i);\n            }\n        }\n\n        public int pick(int target) {\n            int idx = rand.nextInt(map.get(target).size());\n            return map.get(target).get(idx);\n        }\n    }\n\n\n    class Solution2 {\n        private int[] nums;\n        private Random random;\n        \n        public Solution2(int[] nums) {\n            this.nums = nums;\n            this.random = new Random();\n        }\n        \n        public int pick(int target) {\n            int count = 0;\n            int res = -1;\n            for (int i = 0; i < nums.length; i++) {\n                if (nums[i] == target) {\n                    count++;\n                    int rand = random.nextInt(count) + 1;\n                    if (rand == count) {\n                        res = i;\n                    }\n                }\n            }\n            return res;\n        }\n    }\n\n/**\n * Your Solution object will be instantiated and called as such:\n * Solution obj = new Solution(nums);\n * int param_1 = obj.pick(target);\n */\n\n}\n"
  },
  {
    "path": "src/RangeAddition370.java",
    "content": "/**\n * Assume you have an array of length n initialized with all 0's and are given\n * k update operations.\n * \n * Each operation is represented as a triplet: [startIndex, endIndex, inc]\n * which increments each element of subarray A[startIndex ... endIndex]\n * (startIndex and endIndex inclusive) with inc.\n * \n * Return the modified array after all k operations were executed.\n * \n * Example:\n * Input: length = 5, updates = [[1,3,2],[2,4,3],[0,2,-2]]\n * Output: [-2,0,3,5,3]\n * \n * Explanation:\n * \n * Initial state:\n * [0,0,0,0,0]\n * \n * After applying operation [1,3,2]:\n * [0,2,2,2,0]\n * \n * After applying operation [2,4,3]:\n * [0,2,5,5,3]\n * \n * After applying operation [0,2,-2]:\n * [-2,0,3,5,3]\n */\n\npublic class RangeAddition370 {\n    // brute force\n    public int[] getModifiedArray(int length, int[][] updates) {\n        int[] res = new int[length];\n        for (int[] up: updates) {\n            for (int i=up[0]; i<=up[1]; i++) {\n                res[i] += up[2];\n            }\n        }\n        return res;\n    }\n\n\n    // brute force\n    public int[] getModifiedArray2(int length, int[][] updates) {\n        int[] res = new int[length];\n        for (int i=0; i<length; i++) {\n            for (int[] up: updates) {\n                if (up[0] <= i && up[1] >= i) {\n                    res[i] += up[2];\n                }\n            }\n        }\n        return res;\n    }\n\n\n    public int[] getModifiedArray3(int length, int[][] updates) {\n        int[] res = new int[length];\n        int[] starts = new int[length];\n        int[] ends = new int[length];\n        for (int[] up: updates) {\n            starts[up[0]] += up[2];\n            if (up[1]+1 < length) ends[up[1]+1] += up[2];\n        }\n        int curr = 0;\n        for (int i=0; i<length; i++) {\n            curr += starts[i];\n            curr -= ends[i];\n            res[i] += curr;\n        }\n        return res;\n    }\n\n\n    public int[] getModifiedArray4(int length, int[][] updates) {\n        int[] res = new int[length];\n        int[] ends = new int[length];\n        for (int[] up: updates) {\n            res[up[0]] += up[2];\n            if (up[1]+1 < length) ends[up[1]+1] += up[2];\n        }\n        int curr = 0;\n        for (int i=0; i<length; i++) {\n            curr += res[i];\n            curr -= ends[i];\n            res[i] = curr;\n        }\n        return res;\n    }\n\n\n    public int[] getModifiedArray5(int length, int[][] updates) {\n        int[] res = new int[length];\n        for (int[] up: updates) {\n            res[up[0]] += up[2];\n            if (up[1]+1 < length) res[up[1]+1] -= up[2];\n        }\n        int curr = 0;\n        for (int i=0; i<length; i++) {\n            curr += res[i];\n            res[i] = curr;\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/range-addition/discuss/84219/Java-O(n+k)-time-O(1)-space-with-algorithm-explained\n     */\n    public int[] getModifiedArray6(int length, int[][] updates) {\n        int[] nums = new int[length];\n        for (int[] update : updates) {\n            nums[update[1]] += update[2];\n            if (update[0] > 0) {\n                nums[update[0] - 1] -= update[2];\n            } \n        }\n        \n        int sum = nums[length - 1];\n        for (int i = length - 2; i >= 0; i--) {\n            nums[i] += sum;\n            sum = nums[i]; \n        }\n        return nums;\n    }\n\n}\n"
  },
  {
    "path": "src/RangeModule715.java",
    "content": "/**\n * A Range Module is a module that tracks ranges of numbers. Your task is to\n * design and implement the following interfaces in an efficient manner.\n * \n * - addRange(int left, int right) Adds the half-open interval [left, right),\n * tracking every real number in that interval. Adding an interval that\n * partially overlaps with currently tracked numbers should add any numbers in\n * the interval [left, right) that are not already tracked.\n * - queryRange(int left, int right) Returns true if and only if every real\n * number in the interval [left, right) is currently being tracked.\n * - removeRange(int left, int right) Stops tracking every real number\n * currently being tracked in the interval [left, right).\n * \n * Example 1:\n * addRange(10, 20): null\n * removeRange(14, 16): null\n * queryRange(10, 14): true (Every number in [10, 14) is being tracked)\n * queryRange(13, 15): false (Numbers like 14, 14.03, 14.17 in [13, 15) are\n * not being tracked)\n * queryRange(16, 17): true (The number 16 in [16, 17) is still being tracked,\n * despite the remove operation)\n * \n * Note:\n * A half open interval [left, right) denotes all real numbers left <= x < right.\n * 0 < left < right < 10^9 in all calls to addRange, queryRange, removeRange.\n * The total number of calls to addRange in a single test case is at most 1000.\n * The total number of calls to queryRange in a single test case is at most 5000.\n * The total number of calls to removeRange in a single test case is at most 1000.\n */\n\n\npublic class RangeModule715 {\n    class RangeModule {\n        private TreeMap<Integer, Integer> ranges;\n\n        public RangeModule() {\n            ranges = new TreeMap<>();\n        }\n\n        public void addRange(int left, int right) {\n            Integer l = left;\n            Integer r = right;\n            Integer floor = ranges.floorKey(l);\n            if (floor != null && l <= ranges.get(floor)) {\n                if (r <= ranges.get(floor)) return;\n                l = floor;\n                r = Math.max(ranges.get(floor), r);\n                ranges.remove(floor);\n            }\n\n            Integer higher = ranges.higherKey(l);\n            while (higher != null && higher <= r) {\n                r = Math.max(ranges.get(higher), r);\n                ranges.remove(higher);\n                higher = ranges.higherKey(l);\n            }\n           ranges.put(l, r);\n        }\n\n        public boolean queryRange(int left, int right) {\n            Integer floor = ranges.floorKey(left);\n            return floor != null && ranges.get(floor) >= right;\n        }\n\n        public void removeRange(int left, int right) {\n            Integer l = left;\n            Integer r = right;\n            Map.Entry<Integer, Integer> lower = ranges.lowerEntry(l);\n            if (lower != null && l < lower.getValue()) {\n                ranges.remove(lower.getKey());\n                ranges.put(lower.getKey(), l);\n                if (lower.getValue() > r) {\n                    ranges.put(r, lower.getValue());\n                    return;\n                } else if (lower.getValue() == r) {\n                    return;\n                } else {\n                    l = lower.getValue();\n                }\n            }\n\n            Map.Entry<Integer, Integer> ceiling = ranges.ceilingEntry(l);\n            while (ceiling != null && ceiling.getKey() <= r) {\n                ranges.remove(ceiling.getKey());\n                if (ceiling.getValue() > r) {\n                    ranges.put(r, ceiling.getValue());\n                    return;\n                }\n                ceiling = ranges.ceilingEntry(l);\n            }\n        }\n    }\n\n\n    class RangeModule2 {\n        private TreeSet<Range> ranges = new TreeSet<>((r1, r2) -> Integer.compare(r1.left, r2.left));\n        public RangeModule() {\n        }\n\n        public void addRange(int left, int right) {\n            Range newRange = new Range(left, right);\n            Range floor = ranges.floor(newRange);\n            if (floor != null && floor.right >= left) {\n                if (floor.right >= right) return;\n                newRange.left = floor.left;\n                newRange.right = Math.max(floor.right, right);\n                ranges.remove(floor);\n            }\n\n            while (true) {\n                Range ceiling = ranges.ceiling(newRange);\n                if (ceiling == null || ceiling.left > newRange.right) break;\n                newRange.right = Math.max(ceiling.right, newRange.right);\n                ranges.remove(ceiling);\n            }\n            ranges.add(newRange);\n        }\n\n        public boolean queryRange(int left, int right) {\n            Range floor = ranges.floor(new Range(left, right));\n            if (floor == null) return false;\n            return floor.right >= right;\n        }\n\n        public void removeRange(int left, int right) {\n            Range toBeRemoved = new Range(left, right);\n            Range floor = ranges.floor(toBeRemoved);\n            if (floor != null && floor.right >= left) {\n                int fRight = floor.right;\n                floor.right = left;\n                if (fRight == right) return;\n                if (fRight > right) {\n                    Range add = new Range(right, fRight);\n                    ranges.add(add);\n                    return;\n                }\n            }\n\n            while (true) {\n                Range ceiling = ranges.ceiling(toBeRemoved);\n                if (ceiling == null || ceiling.left >= toBeRemoved.right) break;\n                ranges.remove(ceiling);\n                if (ceiling.right > toBeRemoved.right) {\n                    ceiling.left = toBeRemoved.right;\n                    ranges.add(ceiling);\n                    break;\n                }\n            }\n        }\n\n        class Range {\n            int left;\n            int right;\n            Range (int l, int r) {\n                left = l;\n                right = r;\n            }\n        }\n    }\n\n\n/**\n * Your RangeModule object will be instantiated and called as such:\n * RangeModule obj = new RangeModule();\n * obj.addRange(left,right);\n * boolean param_2 = obj.queryRange(left,right);\n * obj.removeRange(left,right);\n */\n\n}\n"
  },
  {
    "path": "src/RangeSumQuery2DImmutable304.java",
    "content": "/**\n * Given a 2D matrix matrix, find the sum of the elements inside the rectangle\n * defined by its upper left corner (row1, col1) and lower right corner\n * (row2, col2).\n * \n * Range Sum Query 2D\n * https://leetcode.com/static/images/courses/range_sum_query_2d.png\n * \n * The above rectangle (with the red border) is defined by\n * (row1, col1) = (2, 1) and (row2, col2) = (4, 3), which contains sum = 8.\n * \n * Example:\n * Given matrix = [\n *   [3, 0, 1, 4, 2],\n *   [5, 6, 3, 2, 1],\n *   [1, 2, 0, 1, 5],\n *   [4, 1, 0, 1, 7],\n *   [1, 0, 3, 0, 5]\n * ]\n * \n * sumRegion(2, 1, 4, 3) -> 8\n * sumRegion(1, 1, 2, 2) -> 11\n * sumRegion(1, 2, 2, 4) -> 12\n * \n * Note:\n * You may assume that the matrix does not change.\n * There are many calls to sumRegion function.\n * You may assume that row1 ≤ row2 and col1 ≤ col2.\n */\n\n\npublic class RangeSumQuery2DImmutable304 {\n    class NumMatrix {\n        private int[][] sum;\n        public NumMatrix(int[][] matrix) {\n            if (matrix.length == 0 || matrix[0].length == 0) return;\n            int M = matrix.length;\n            int N = matrix[0].length;\n            sum = new int[M+1][N+1];\n            for (int i=1; i<=M; i++) {\n                for (int j=1; j<=N; j++) {\n                    sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + matrix[i-1][j-1];\n                }\n            }\n        }\n        \n        public int sumRegion(int row1, int col1, int row2, int col2) {\n            if (sum == null) return 0;\n            return sum[row2+1][col2+1] - sum[row2+1][col1] - sum[row1][col2+1] + sum[row1][col1];\n        }\n    }\n\n\n    class NumMatrix2 {\n        private int[][] sums;\n        private int M;\n        private int N;\n\n        public NumMatrix2(int[][] matrix) {\n            if (matrix.length != 0 && matrix[0].length != 0) {\n                this.M = matrix.length;\n                this.N = matrix[N].length;\n                this.sums = new int[M][N + 1];\n                for (int i=0; i<M; i++) {\n                    for (int j=1; j<=N; j++) {\n                        this.sums[i][j] += this.sums[i][j-1] + matrix[i][j-1];\n                    }\n                }\n            }\n        }\n\n        public int sumRegion(int row1, int col1, int row2, int col2) {\n            int res = 0;\n            for (int i=row1; i<=row2; i++) {\n                res += this.sums[i][col2+1] - this.sums[i][col1];\n            }\n            return res;\n        }\n    }\n    \n    /**\n     * Your NumMatrix object will be instantiated and called as such:\n     * NumMatrix obj = new NumMatrix(matrix);\n     * int param_1 = obj.sumRegion(row1,col1,row2,col2);\n     */\n\n\n\n/**\n * Your NumMatrix object will be instantiated and called as such:\n * NumMatrix obj = new NumMatrix(matrix);\n * int param_1 = obj.sumRegion(row1,col1,row2,col2);\n */\n\n}\n\n"
  },
  {
    "path": "src/RangeSumQuery2DMutable308.java",
    "content": "/**\n * Given a 2D matrix matrix, find the sum of the elements inside the rectangle\n * defined by its upper left corner (row1, col1) and lower right corner\n * (row2, col2).\n * \n * Range Sum Query 2D\n * https://leetcode.com/static/images/courses/range_sum_query_2d.png\n * \n * The above rectangle (with the red border) is defined by\n * (row1, col1) = (2, 1) and (row2, col2) = (4, 3), which contains sum = 8.\n * \n * Example:\n * Given matrix = [\n *   [3, 0, 1, 4, 2],\n *   [5, 6, 3, 2, 1],\n *   [1, 2, 0, 1, 5],\n *   [4, 1, 0, 1, 7],\n *   [1, 0, 3, 0, 5]\n * ]\n * \n * sumRegion(2, 1, 4, 3) -> 8\n * update(3, 2, 2)\n * sumRegion(2, 1, 4, 3) -> 10\n * \n * Note:\n * The matrix is only modifiable by the update function.\n * You may assume the number of calls to update and sumRegion function is\n * distributed evenly.\n * You may assume that row1 ≤ row2 and col1 ≤ col2.\n */\n\npublic class RangeSumQuery2DMutable308 {\n    class NumMatrix {\n        private Node root;\n      \n        public NumMatrix(int[][] matrix) {\n            if (matrix != null && matrix.length != 0 && matrix[0].length != 0) {\n                this.root = constructTree(matrix, 0, 0, matrix.length-1, matrix[0].length-1);\n            }\n        }\n        \n        private Node constructTree(int[][] matrix, int row1, int col1, int row2, int col2) {\n            if (row1 > row2 || col1 > col2) return null;\n            Node res = new Node(row1, col1, row2, col2, matrix[row1][col1]);\n            if (row1 == row2 && col1 == col2) return res;\n            \n            int midRow = (row1 + row2) / 2;\n            int midCol = (col1 + col2) / 2;\n            Node tl = constructTree(matrix, row1, col1, midRow, midCol);\n            Node tr = constructTree(matrix, row1, midCol+1, midRow, col2);\n            Node bl = constructTree(matrix, midRow+1, col1, row2, midCol);\n            Node br = constructTree(matrix, midRow+1, midCol+1, row2, col2);\n            res.tl = tl;\n            res.tr = tr;\n            res.bl = bl;\n            res.br = br;\n            res.sum = (tl == null ? 0 : tl.sum) +\n                    (tr == null ? 0 : tr.sum) +\n                    (bl == null ? 0 : bl.sum) +\n                    (br == null ? 0 : br.sum);\n            return res;   \n        }\n        \n        public void update(int row, int col, int val) {\n            update(this.root, row, col, val);\n        }\n        \n        private void update(Node root, int row, int col, int val) {\n            if (root.row1 == root.row2 && root.row1 == row && root.col1 == root.col2 && root.col1 == col) {\n                root.sum = val;\n                return;\n            }\n            int rowMid = (root.row1 + root.row2) / 2;\n            int colMid = (root.col1 + root.col2) / 2;\n            Node next;\n            if (row <= rowMid) {\n                if (col <= colMid) {\n                    next = root.tl;\n                } else {\n                    next = root.tr;\n                }\n            } else {\n                if (col <= colMid) {\n                    next = root.bl;\n                } else {\n                    next = root.br;\n                }\n            }\n            root.sum -= next.sum;\n            update(next, row, col, val);\n            root.sum += next.sum;\n        }\n        \n        public int sumRegion(int row1, int col1, int row2, int col2) {\n            return sumRegion(this.root, row1, col1, row2, col2);\n        }\n        \n        private int sumRegion(Node root, int row1, int col1, int row2, int col2) {\n            if (root == null || root.row2 < row1 || root.row1 > row2 || root.col2 < col1 || root.col1 > col2) return 0;\n            if (root.row1 >= row1 && root.row2 <= row2 && root.col1 >= col1 && root.col2 <= col2) return root.sum;\n            return sumRegion(root.tl, row1, col1, row2, col2) +\n                sumRegion(root.tr, row1, col1, row2, col2) +\n                sumRegion(root.bl, row1, col1, row2, col2) +\n                sumRegion(root.br, row1, col1, row2, col2);\n        }\n    \n        class Node {\n            Node tl;\n            Node tr;\n            Node bl;\n            Node br;\n            int sum;\n            int row1;\n            int col1;\n            int row2;\n            int col2;\n            Node (int row1, int col1, int row2, int col2, int sum) {\n                this.row1 = row1;\n                this.col1 = col1;\n                this.row2 = row2;\n                this.col2 = col2;\n                this.sum = sum;\n            }\n        }\n    }\n\n    /**\n     * https://leetcode.com/problems/range-sum-query-2d-mutable/discuss/75870/Java-2D-Binary-Indexed-Tree-Solution-clean-and-short-17ms\n     */\n    // time should be O(log(m) * log(n)) \n    class NumMatrix2 {\n        int[][] tree;\n        int[][] nums;\n        int m;\n        int n;\n\n        public NumMatrix2(int[][] matrix) {\n            if (matrix.length == 0 || matrix[0].length == 0) return;\n            m = matrix.length;\n            n = matrix[0].length;\n            tree = new int[m+1][n+1];\n            nums = new int[m][n];\n            for (int i = 0; i < m; i++) {\n                for (int j = 0; j < n; j++) {\n                    update(i, j, matrix[i][j]);\n                }\n            }\n        }\n\n        public void update(int row, int col, int val) {\n            if (m == 0 || n == 0) return;\n            int delta = val - nums[row][col];\n            nums[row][col] = val;\n            for (int i = row + 1; i <= m; i += i & (-i)) {\n                for (int j = col + 1; j <= n; j += j & (-j)) {\n                    tree[i][j] += delta;\n                }\n            }\n        }\n\n        public int sumRegion(int row1, int col1, int row2, int col2) {\n            if (m == 0 || n == 0) return 0;\n            return sum(row2+1, col2+1) + sum(row1, col1) - sum(row1, col2+1) - sum(row2+1, col1);\n        }\n\n        public int sum(int row, int col) {\n            int sum = 0;\n            for (int i = row; i > 0; i -= i & (-i)) {\n                for (int j = col; j > 0; j -= j & (-j)) {\n                    sum += tree[i][j];\n                }\n            }\n            return sum;\n        }\n    }\n\n\n    class NumMatrix3 {\n        private int[][] sum;\n        private int[][] board;\n\n        public NumMatrix3(int[][] matrix) {\n            this.board = matrix;\n            if (matrix.length != 0 && matrix[0].length != 0) {\n                this.sum = new int[matrix.length][matrix[0].length + 1];\n                for (int i=0; i<matrix.length; i++) {\n                    for (int j=1; j<=matrix[0].length; j++) {\n                        this.sum[i][j] += this.sum[i][j-1] + this.board[i][j-1];\n                    }\n                }\n            }\n        }\n\n        public void update(int row, int col, int val) {\n            int curr = this.board[row][col];\n            int diff = val - curr;\n            for (int j=col+1; j<=this.board[0].length; j++) {\n                this.sum[row][j] += diff;\n            }\n            this.board[row][col] = val;\n        }\n\n        public int sumRegion(int row1, int col1, int row2, int col2) {\n            int res = 0;\n            for (int i=row1; i<=row2; i++) {\n                res += this.sum[i][col2+1] - this.sum[i][col1];\n            }\n            return res;\n        }\n    }\n\n/**\n * Your NumMatrix object will be instantiated and called as such:\n * NumMatrix obj = new NumMatrix(matrix);\n * obj.update(row,col,val);\n * int param_2 = obj.sumRegion(row1,col1,row2,col2);\n */\n\n}\n\n"
  },
  {
    "path": "src/RangeSumQueryImmutable303.java",
    "content": "/**\n * Given an integer array nums, find the sum of the elements between indices\n * i and j (i ≤ j), inclusive.\n * \n * Example:\n * Given nums = [-2, 0, 3, -5, 2, -1]\n * \n * sumRange(0, 2) -> 1\n * sumRange(2, 5) -> -1\n * sumRange(0, 5) -> -3\n * \n * Note:\n * You may assume that the array does not change.\n * There are many calls to sumRange function.\n */\n\n\npublic class RangeSumQueryImmutable303 {\n    class NumArray {\n        private int[] sum;\n        \n        public NumArray(int[] nums) {\n            sum = new int[nums.length+1];\n            for (int i=1; i<=nums.length; i++) {\n                sum[i] = sum[i-1] + nums[i-1];\n            } \n        }\n        \n        public int sumRange(int i, int j) {\n            return sum[j+1] - sum[i];\n        }\n    }\n\n/**\n* Your NumArray object will be instantiated and called as such:\n* NumArray obj = new NumArray(nums);\n* int param_1 = obj.sumRange(i,j);\n*/\n\n}\n\n\n"
  },
  {
    "path": "src/RangeSumQueryMutable307.java",
    "content": "/**\n * Given an integer array nums, find the sum of the elements between indices i\n * and j (i ≤ j), inclusive.\n * \n * The update(i, val) function modifies nums by updating the element at\n * index i to val.\n * \n * Example:\n * Given nums = [1, 3, 5]\n * sumRange(0, 2) -> 9\n * update(1, 2)\n * sumRange(0, 2) -> 8\n * \n * Note:\n * \n * The array is only modifiable by the update function.\n * You may assume the number of calls to update and sumRange function is\n * distributed evenly.\n */\n\n\npublic class RangeSumQueryMutable307 {\n    class NumArray {\n        private int[] sum;\n        private int[] nums;\n        \n        public NumArray(int[] nums) {\n            this.nums = nums;\n            sum = new int[nums.length+1];\n            for (int i=1; i<=nums.length; i++) {\n                sum[i] = sum[i-1] + nums[i-1];\n            }\n        }\n        \n        public void update(int i, int val) {\n            int diff = val - nums[i];\n            for (int j=i+1; j<sum.length; j++) {\n                sum[j] += diff;\n            }\n            nums[i] = val;\n        }\n        \n        public int sumRange(int i, int j) {\n            return sum[j+1] - sum[i];\n        }\n    }\n\n\n    class NumArray2 {\n        private Node root;\n        \n        public NumArray(int[] nums) {\n            this.root = constructTree(nums);\n        }\n        \n        private Node constructTree(int[] nums) {\n            return constructTree(nums, 0, nums.length-1); \n        }\n        \n        private Node constructTree(int[] nums, int l, int r) {\n            if (l > r) return null;\n            Node res = new Node(l, r, nums[l]);\n            if (l == r) return res;\n            \n            int mid = (l + r) / 2;\n            Node left = constructTree(nums, l, mid);\n            Node right = constructTree(nums, mid+1, r); \n            res.left = left;\n            res.right = right;\n            res.sum = left.sum + right.sum;\n            return res;\n        }\n        \n        public void update(int i, int val) {\n            update(this.root, i, val);\n        }\n        \n        public void update(Node root, int i, int val) {\n            if (root.l == root.r && root.l == i) {\n                root.sum = val;\n                return;\n            }\n            int mid = (root.l + root.r) / 2;\n            \n            if (i <= mid) {\n                update(root.left, i, val);\n            } else {\n                update(root.right, i, val);\n            }\n            root.sum = root.left.sum + root.right.sum;\n        }\n        \n        public int sumRange(int i, int j) {\n            return sumRange(this.root, i, j);\n        }\n        \n        private int sumRange(Node root, int i, int j) {\n            if (root.l == i && root.r == j) {\n                return root.sum;\n            }\n            int mid = (root.l + root.r) / 2;\n            \n            if (mid < i) {\n                return sumRange(root.right, i, j);\n            } else if (mid >= j) {\n                return sumRange(root.left, i, j);\n            } else {\n                return sumRange(root.left, i, mid) + sumRange(root.right, mid+1, j);\n            }\n        }\n        \n        class Node {\n            Node left;\n            Node right;\n            int l;\n            int r;\n            int sum;\n            Node(int l, int r, int s) {\n                this.l = l;\n                this.r = r;\n                sum = s;\n            }\n        }\n        \n    }\n\n\n    /**\n     * https://leetcode.com/problems/range-sum-query-mutable/solution/\n     */\n    class NumArray3 {\n        int[] tree;\n        int n;\n        public NumArray(int[] nums) {\n            if (nums.length > 0) {\n                n = nums.length;\n                tree = new int[n * 2];\n                buildTree(nums);\n            }\n        }\n        private void buildTree(int[] nums) {\n            for (int i = n, j = 0;  i < 2 * n; i++,  j++)\n                tree[i] = nums[j];\n            for (int i = n - 1; i > 0; --i)\n                tree[i] = tree[i * 2] + tree[i * 2 + 1];\n        }\n\n        public void update(int pos, int val) {\n            pos += n;\n            tree[pos] = val;\n            while (pos > 0) {\n                int left = pos;\n                int right = pos;\n                if (pos % 2 == 0) {\n                    right = pos + 1;\n                } else {\n                    left = pos - 1;\n                }\n                // parent is updated after child is updated\n                tree[pos / 2] = tree[left] + tree[right];\n                pos /= 2;\n            }\n        }\n\n        public int sumRange(int l, int r) {\n            // get leaf with value 'l'\n            l += n;\n            // get leaf with value 'r'\n            r += n;\n            int sum = 0;\n            while (l <= r) {\n                if ((l % 2) == 1) {\n                  sum += tree[l];\n                  l++;\n                }\n                if ((r % 2) == 0) {\n                  sum += tree[r];\n                  r--;\n                }\n                l /= 2;\n                r /= 2;\n            }\n            return sum;\n        }\n    }\n\n\n    class NumArray4 {\n\n        private int[] tree;\n        private int L;\n        \n        public NumArray(int[] nums) {\n            tree = new int[nums.length * 3];\n            L = nums.length;\n            constructTree(nums);\n        }\n        \n        private void constructTree(int[] nums) {\n            constructTree(nums, 0, nums.length-1, 0); \n        }\n        \n        private void constructTree(int[] nums, int l, int r, int i) {\n            if (l > r) return;\n            if (l == r) {\n                tree[i] = nums[l];\n                return;\n            }\n            \n            int mid = (l + r) / 2;\n            constructTree(nums, l, mid, left(i));\n            constructTree(nums, mid+1, r, right(i));\n            tree[i] = tree[left(i)] + tree[right(i)];\n        }\n        \n        public void update(int i, int val) {\n            update(0, L-1, i, val, 0);\n        }\n        \n        public void update(int l, int r, int i, int val, int n) {\n            if (l == r && l == i) {\n                tree[n] = val;\n                return;\n            }\n            int mid = (l + r) / 2;\n            \n            if (i <= mid) {\n                update(l, mid, i, val, left(n));\n            } else {\n                update(mid + 1, r, i, val, right(n));\n            }\n            tree[n] = tree[left(n)] + tree[right(n)];\n        }\n        \n        public int sumRange(int i, int j) {\n            return sumRange(0, L-1, i, j, 0);\n        }\n        \n        private int sumRange(int l, int r, int i, int j, int n) {\n            if (l == i && r == j) {\n                return tree[n];\n            }\n            int mid = (l + r) / 2;\n            \n            if (mid < i) {\n                return sumRange(mid+1, r, i, j, right(n));\n            } else if (mid >= j) {\n                return sumRange(l, mid, i, j, left(n));\n            } else {\n                return sumRange(l, mid, i, mid, left(n)) + sumRange(mid+1, r, mid+1, j, right(n));\n            }\n        }\n        \n        private int left(int i) {\n            return 2 * i + 1;\n        }\n        private int right(int i) {\n            return 2 * i + 2;\n        }\n        \n    }\n\n\n    class NumArray5 {\n\n        private int[] nums;\n        private int[] tree;\n        private int L;\n        \n        public NumArray(int[] nums) {\n            this.nums = nums;\n            this.L = nums.length;\n            constructTree(nums);\n        }\n        \n        private void constructTree(int[] nums) {\n            this.tree = new int[nums.length + 1];\n            for (int i=0; i<L; i++) {\n                updateDiff(i, nums[i]);\n            }\n        }\n    \n        private void updateDiff(int i, int val) {\n            int idx = i + 1;\n            while (idx <= L) {\n                this.tree[idx] += val;\n                idx += idx & -idx;\n            }\n        }\n        \n        public void update(int i, int val) {\n            int diff = val - this.nums[i];\n            this.nums[i] = val;\n            updateDiff(i, diff);\n        }\n    \n        public int sumRange(int i, int j) {\n            return getSum(j) - getSum(i-1);\n        }\n        \n        public int getSum(int i) {\n            int res = 0;\n            int idx = i + 1;\n            while (idx > 0) {\n                res += this.tree[idx];\n                idx -= idx & -idx;\n            }\n            return res;\n        }\n    \n    }\n\n\n/**\n * Your NumArray object will be instantiated and called as such:\n * NumArray obj = new NumArray(nums);\n * obj.update(i,val);\n * int param_2 = obj.sumRange(i,j);\n */\n\n}\n\n"
  },
  {
    "path": "src/RansomNote383.java",
    "content": "/**\n * Given an arbitrary ransom note string and another string containing letters\n * from all the magazines, write a function that will return true if the ransom\n * note can be constructed from the magazines ; otherwise, it will return false.\n * \n * Each letter in the magazine string can only be used once in your ransom note.\n * \n * Note:\n * You may assume that both strings contain only lowercase letters.\n * \n * canConstruct(\"a\", \"b\") -> false\n * canConstruct(\"aa\", \"ab\") -> false\n * canConstruct(\"aa\", \"aab\") -> true\n */\n\n\npublic class RansomNote383 {\n    public boolean canConstruct(String ransomNote, String magazine) {\n        Map<Character, Integer> dict = new HashMap<>();\n        for (char c: magazine.toCharArray()) dict.put(c, dict.getOrDefault(c, 0) + 1);\n        for (char c: ransomNote.toCharArray()) {\n            int count = dict.getOrDefault(c, 0);\n            if (count <= 0) return false;\n            dict.put(c, count-1);\n        }\n        return true;\n    }\n\n    public boolean canConstruct2(String ransomNote, String magazine) {\n        int[] dict = new int[26];\n        for (char c: magazine.toCharArray()) dict[c-'a']++;\n        for (char c: ransomNote.toCharArray()) {\n            dict[c-'a']--;\n            if (dict[c-'a'] < 0) return false;\n        }\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "src/ReadNCharactersGivenRead4IICallMultipleTimes158.java",
    "content": "/**\n * The API: int read4(char *buf) reads 4 characters at a time from a file.\n *\n * The return value is the actual number of characters read. For example, it\n * returns 3 if there is only 3 characters left in the file.\n *\n * By using the read4 API, implement the function int read(char *buf, int n)\n * that reads n characters from the file.\n *\n * Note:\n * The read function may be called multiple times.\n *\n */\n\n/* The read4 API is defined in the parent class Reader4.\n      int read4(char[] buf); */\n\npublic class ReadNCharactersGivenRead4IICallMultipleTimes158 extends Reader4 {\n    private int cacheSize = 0;\n    private int ptr = 0;\n    private int SIZE = 4;\n    private char[] cache = new char[SIZE];\n\n    /**\n     * @param buf Destination buffer\n     * @param n   Maximum number of characters to read\n     * @return    The number of characters read\n     */\n    public int read(char[] buf, int n) {\n        int count = 0;\n        while (cacheSize > 0) {\n            if (count >= n) {\n                return count;\n            }\n            buf[count] = cache[ptr];\n            count++;\n            cacheSize--;\n            ptr = (ptr+1) % SIZE;\n        }\n        char[] buf4 = new char[4];\n        while (count < n) {\n            int k = read4(buf4);\n            if (k == 0) {\n                cacheSize = 0;\n                return count;\n            }\n            int add = Math.min(k, n - count);\n            for (int i=0; i<add; i++) buf[i+count] = buf4[i];\n            if (n - count < k) {\n                int p = ptr;\n                cacheSize = k - (n-count);\n                for (int i=0; i<cacheSize; i++) {\n                    cache[p] = buf4[add+i];\n                    p = (p+1) % SIZE;\n                }\n            }\n            count += add;\n        }\n\n        return count;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/read-n-characters-given-read4-ii-call-multiple-times/discuss/49598/A-simple-Java-code\n     */\n    private int buffPtr = 0;\n    private int buffCnt = 0;\n    private char[] buff = new char[4];\n    public int read2(char[] buf, int n) {\n        int ptr = 0;\n        while (ptr < n) {\n            if (buffPtr == 0) {\n                buffCnt = read4(buff);\n            }\n            if (buffCnt == 0) break;\n            while (ptr < n && buffPtr < buffCnt) {\n                buf[ptr++] = buff[buffPtr++];\n            }\n            if (buffPtr >= buffCnt) buffPtr = 0;\n        }\n        return ptr;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/read-n-characters-given-read4-ii-call-multiple-times/discuss/49615/Clean-solution-in-Java\n     */\n    char[] prevBuf = new char[4];\n    int prevSize = 0;\n    int prevIndex = 0;\n    public int read3(char[] buf, int n) {\n        int counter = 0;\n\n        while (counter < n) {\n            if (prevIndex < prevSize) {\n                buf[counter++] = prevBuf[prevIndex++];\n            } else {\n                prevSize = read4(prevBuf);\n                prevIndex = 0;\n                if (prevSize == 0) {\n                    // no more data to consume from stream\n                    break;\n                }\n            }\n        }\n        return counter;\n    }\n\n    // private char[] cache = new char[4];\n    // private int ptr = 0;\n    // private int len = 0;\n    // /**\n    //  * @param buf Destination buffer\n    //  * @param n   Maximum number of characters to read\n    //  * @return    The number of characters read\n    //  */\n    // public int read(char[] buf, int n) {\n    //     int res = 0;\n    //     while (true) {\n    //         while (ptr < len && res < n) {\n    //             buf[res++] = cache[ptr++];\n    //         }\n    //         if (res == n) break;\n    //         len = read4(cache);\n    //         ptr = 0;\n    //         if (len == 0) break;\n    //     }\n    //     return res;\n    // }\n\n}\n"
  },
  {
    "path": "src/ReadNCharactersGivenReadFour157.java",
    "content": "/**\n * The API: int read4(char *buf) reads 4 characters at a time from a file.\n *\n * The return value is the actual number of characters read. For example, it\n * returns 3 if there is only 3 characters left in the file.\n *\n * By using the read4 API, implement the function int read(char *buf, int n)\n * that reads n characters from the file.\n *\n * Note:\n * The read function will only be called once for each test case.\n *\n */\n\n/* The read4 API is defined in the parent class Reader4.\n      int read4(char[] buf); */\n\npublic class ReadNCharactersGivenReadFour157 extends Reader4 {\n    /**\n     * @param buf Destination buffer\n     * @param n   Maximum number of characters to read\n     * @return    The number of characters read\n     */\n    public int read(char[] buf, int n) {\n        int count = 0;\n        char[] buf4 = new char[4];\n        while (count < n) {\n            int k = read4(buf4);\n            if (k == 0) return count;\n            int add = Math.min(k, n-count);\n            for (int i=0; i<add; i++) buf[count+i] = buf4[i];\n            count += add;\n        }\n\n        return count;\n    }\n\n}\n"
  },
  {
    "path": "src/RearrangeStringKDistanceApart358.java",
    "content": "/**\n * Given a non-empty string s and an integer k, rearrange the string such that\n * the same characters are at least distance k from each other.\n * \n * All input strings are given in lowercase letters. If it is not possible to\n * rearrange the string, return an empty string \"\".\n * \n * Example 1:\n * Input: s = \"aabbcc\", k = 3\n * Output: \"abcabc\" \n * Explanation: The same letters are at least distance 3 from each other.\n * \n * Example 2:\n * Input: s = \"aaabc\", k = 3\n * Output: \"\" \n * Explanation: It is not possible to rearrange the string.\n * \n * Example 3:\n * Input: s = \"aaadbbcc\", k = 2\n * Output: \"abacabcd\"\n * Explanation: The same letters are at least distance 2 from each other.\n */\n\npublic class RearrangeStringKDistanceApart358 {\n    /**\n     * https://leetcode.com/problems/rearrange-string-k-distance-apart/discuss/83192/Java-7-version-of-PriorityQueue-O(nlogn)-with-comments-and-explanations\n     */\n    public String rearrangeString(String s, int k) {\n        if (k == 0) return s;\n        int N = s.length();\n        Map<Character, Integer> map = new HashMap<>();\n        for (char ch: s.toCharArray()) {\n            map.put(ch, map.getOrDefault(ch, 0) + 1);\n        }\n\n        Comparator<Map.Entry<Character, Integer>> comp = (e1, e2) -> Integer.compare(e2.getValue(), e1.getValue());\n        PriorityQueue<Map.Entry<Character, Integer>> pq = new PriorityQueue<>(1, comp);\n        for (Map.Entry<Character, Integer> e: map.entrySet()) {\n            pq.add(e);\n        }\n\n        StringBuilder sb = new StringBuilder();\n        Queue<Map.Entry<Character, Integer>> cache = new LinkedList<>();\n        while (!pq.isEmpty()) {\n            Map.Entry<Character, Integer> curr = pq.poll();\n            sb.append(curr.getKey());\n            curr.setValue(curr.getValue() - 1);\n            cache.add(curr);\n            // intial k-1 chars, cache not full yet\n            if (cache.size() < k) continue;\n            // release from cache if char is already k apart\n            Map.Entry<Character, Integer> next = cache.poll();\n            //note that char with 0 count still needs to be placed in cache as a place holder\n            if (next.getValue() > 0) {\n                pq.add(next);\n            }\n        }\n        return sb.length() == N ? sb.toString() : \"\";\n    }\n\n\n    public String rearrangeString2(String s, int k) {\n        if (k == 0) return s;\n        int N = s.length(); \n        int[] map = new int[26];\n        for (char ch: s.toCharArray()) {\n            map[ch-'a']++;\n        }\n\n        Comparator<Character> comp = (c1, c2) -> Integer.compare(map[c2-'a'], map[c1-'a']);\n        PriorityQueue<Character> pq = new PriorityQueue<>(1, comp);\n        for (char c='a'; c<='z'; c++) {\n            if (map[c-'a'] > 0) {\n                pq.add(c);\n            }\n        }\n        \n        StringBuilder sb = new StringBuilder();\n        Queue<Character> cache = new LinkedList<>();\n        while (!pq.isEmpty()) {\n            char curr = pq.poll();\n            sb.append(curr);\n            map[curr-'a']--;\n            cache.add(curr);\n            if (cache.size() < k) continue;\n            char next = cache.poll();\n            if (map[next-'a'] > 0) {\n                pq.add(next);\n            }\n        }\n        return  sb.length() == N ? sb.toString() : \"\";\n    }\n\n\n    /**\n     * https://leetcode.com/problems/rearrange-string-k-distance-apart/discuss/83193/Java-15ms-Solution-with-Two-auxiliary-array.-O(N)-time.\n     */\n    public String rearrangeString3(String str, int k) {\n        int length = str.length();\n        int[] count = new int[26];\n        int[] nextIndex = new int[26];\n        char[] chars = str.toCharArray();\n        for (char ch: chars){\n            count[ch-'a']++;\n        }\n\n        StringBuilder sb = new StringBuilder();\n        for (int i=0; i<length; i++) {\n            int idx = findValidMax(count, nextIndex, i);\n            if (idx == -1) return \"\";\n            sb.append((char) (idx + 'a'));\n            count[idx]--;\n            nextIndex[idx] = i+k;\n        }\n        return sb.toString();\n    }\n\n    private int findValidMax(int[] count, int[] nextIndex, int index){\n        int max = Integer.MIN_VALUE;\n        int idx = -1;\n        for (int i=0; i<26; i++) {\n            if (count[i] != 0 && count[i] > max && index >= nextIndex[i]) {\n                max = count[i];\n                idx = i;\n            }\n        }\n        return idx;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/rearrange-string-k-distance-apart/discuss/83205/Java_solution_in_12_ms-O(N)-time-and-space\n     */\n    public String rearrangeString4(String str, int k) {\n        if (k < 2) return str;\n        int[][] times = new int[26][2];\n        for(int i = 0; i < 26; i++) times[i][1] = 'a'+i;\n        for (int i = 0; i < str.length(); i++) {\n            times[str.charAt(i) - 'a'][0]++;\n        }\n        Comparator<int[]> comp = (a, b) -> a[0] == b[0] ? Integer.compare(a[1], b[1]) : Integer.compare(b[0], a[0]); \n        Arrays.sort(times, comp);\n\n        int len = str.length(), maxlen = (len + k - 1)/k, count = 0, i = 0;\n        if(times[0][0] > maxlen) return \"\";\n\n        char[] res = new char[len];\n        if((count = (len % k)) != 0){\n            for(i = 0; i < 26; i++){\n                if(times[i][0] < maxlen) break;\n                if(i >= count) return \"\";\n                for(int j = i; j < len; j += k) res[j] = (char)times[i][1];\n            }\n        }\n\n        count = i; maxlen = i;\n        for(int j = 25; j >= maxlen; j--){\n            for(int t = 0; t < times[j][0]; t++){\n                res[count] = (char)times[j][1];\n                count += k;\n                if(count >= len) count = ++i;\n            }\n        }\n        return new String(res);\n    }\n\n}\n"
  },
  {
    "path": "src/ReconstructItinerary332.java",
    "content": "/**\n * Given a list of airline tickets represented by pairs of departure and\n * arrival airports [from, to], reconstruct the itinerary in order. All of the\n * tickets belong to a man who departs from JFK. Thus, the itinerary must\n * begin with JFK.\n * \n * Note:\n * If there are multiple valid itineraries, you should return the itinerary\n * that has the smallest lexical order when read as a single string. For\n * example, the itinerary [\"JFK\", \"LGA\"] has a smaller lexical order than\n * [\"JFK\", \"LGB\"].\n * All airports are represented by three capital letters (IATA code).\n * You may assume all tickets form at least one valid itinerary.\n * \n * Example 1:\n * Input: [[\"MUC\", \"LHR\"], [\"JFK\", \"MUC\"], [\"SFO\", \"SJC\"], [\"LHR\", \"SFO\"]]\n * Output: [\"JFK\", \"MUC\", \"LHR\", \"SFO\", \"SJC\"]\n * \n * Example 2:\n * Input: [[\"JFK\",\"SFO\"],[\"JFK\",\"ATL\"],[\"SFO\",\"ATL\"],[\"ATL\",\"JFK\"],[\"ATL\",\"SFO\"]]\n * Output: [\"JFK\",\"ATL\",\"JFK\",\"SFO\",\"ATL\",\"SFO\"]\n * \n * Explanation: Another possible reconstruction is\n * [\"JFK\",\"SFO\",\"ATL\",\"JFK\",\"ATL\",\"SFO\"].\n * But it is larger in lexical order.\n */\n\npublic class ReconstructItinerary332 {\n    public List<String> findItinerary(String[][] tickets) {\n        Map<String, List<String>> graph = new HashMap<>();\n        for (String[] ticket: tickets) {\n            if (!graph.containsKey(ticket[0])) {\n                graph.put(ticket[0], new ArrayList<>());\n            }\n            graph.get(ticket[0]).add(ticket[1]);\n        }\n        for (List<String> nexts: graph.values()) {\n            Collections.sort(nexts);\n        }\n        \n        List<String> res = new ArrayList<>();\n        res.add(\"JFK\");\n        dfs(graph, tickets.length, \"JFK\", res, 0);\n        return res;\n    }\n\n    private boolean dfs(Map<String, List<String>> graph, int N, String start, List<String> res, int level) {\n        if (level == N) return true;\n        List<String> nexts = graph.get(start);\n        if (nexts == null) return false;\n        int size = nexts.size();\n        for (int i=0; i<size; i++) {\n            String next = nexts.remove(i);\n            res.add(next);\n            boolean canWork = dfs(graph, N, next, res, level+1);\n            if (canWork) return true;\n            res.remove(res.size()-1);\n            nexts.add(i, next);\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "src/ReconstructOriginalDigitsFromEnglish423.java",
    "content": "/**\n * Given a non-empty string containing an out-of-order English representation\n * of digits 0-9, output the digits in ascending order.\n * \n * Note:\n * 1. Input contains only lowercase English letters.\n * 2. Input is guaranteed to be valid and can be transformed to its original\n * digits. That means invalid inputs such as \"abc\" or \"zerone\" are not permitted.\n * 3. Input length is less than 50,000.\n * \n * Example 1:\n * Input: \"owoztneoer\"\n * Output: \"012\"\n * \n * Example 2:\n * Input: \"fviefuro\"\n * Output: \"45\"\n */\n\n\npublic class ReconstructOriginalDigitsFromEnglish423 {\n\n    /**\n     * https://leetcode.com/problems/reconstruct-original-digits-from-english/discuss/91207/one-pass-O(n)-JAVA-Solution-Simple-and-Clear\n     */\n    public String originalDigits(String s) {\n        int[] count = new int[10];\n        for (int i = 0; i < s.length(); i++){\n            char c = s.charAt(i);\n            if (c == 'z') count[0]++;\n            if (c == 'w') count[2]++;\n            if (c == 'x') count[6]++;\n            if (c == 's') count[7]++; //7-6\n            if (c == 'g') count[8]++;\n            if (c == 'u') count[4]++; \n            if (c == 'f') count[5]++; //5-4\n            if (c == 'h') count[3]++; //3-8\n            if (c == 'i') count[9]++; //9-8-5-6\n            if (c == 'o') count[1]++; //1-0-2-4\n        }\n        count[7] -= count[6];\n        count[5] -= count[4];\n        count[3] -= count[8];\n        count[9] = count[9] - count[8] - count[5] - count[6];\n        count[1] = count[1] - count[0] - count[2] - count[4];\n        StringBuilder sb = new StringBuilder();\n        for (int i = 0; i <= 9; i++){\n            for (int j = 0; j < count[i]; j++){\n                sb.append(i);\n            }\n        }\n        return sb.toString();\n    }\n\n}\n"
  },
  {
    "path": "src/RectangleArea223.java",
    "content": "/**\n * Find the total area covered by two rectilinear rectangles in a 2D plane.\n *\n * Each rectangle is defined by its bottom left corner and top right corner as\n * shown in the figure.\n *\n * https://leetcode.com/static/images/problemset/rectangle_area.png\n *\n * Rectangle Area\n * Assume that the total area is never beyond the maximum possible value of int.\n *\n */\n\n\npublic class RectangleArea223 {\n    public int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) {\n        return (int) computeArea((long) A, (long) B, (long) C, (long) D, (long) E, (long) F, (long) G, (long) H);\n    }\n\n    public long computeArea(long A, long B, long C, long D, long E, long F, long G, long H) {\n        boolean sign = true;\n        long t1 = Math.min(G, C) - Math.max(E, A);\n        if (t1 < 0) sign = false;\n        long t2 = Math.min(H, D) - Math.max(F, B);\n        if (t2 < 0 || !sign) sign = false;\n        long overlap = t1*t2;\n        overlap = (sign) ? overlap : 0;\n        long area1 = (D-B)*(C-A);\n        long area2 = (H-F)*(G-E);\n        return area1+area2-overlap;\n    }\n\n}\n"
  },
  {
    "path": "src/RectangleAreaII850.java",
    "content": "/**\n * We are given a list of (axis-aligned) rectangles.  Each rectangle[i] =\n * [x1, y1, x2, y2] , where (x1, y1) are the coordinates of the bottom-left\n * corner, and (x2, y2) are the coordinates of the top-right corner of the ith\n * rectangle.\n * \n * Find the total area covered by all rectangles in the plane.  Since the\n * answer may be too large, return it modulo 10^9 + 7.\n * \n * https://s3-lc-upload.s3.amazonaws.com/uploads/2018/06/06/rectangle_area_ii_pic.png\n * \n * Example 1:\n * Input: [[0,0,2,2],[1,0,2,3],[1,0,3,1]]\n * Output: 6\n * Explanation: As illustrated in the picture.\n * \n * Example 2:\n * Input: [[0,0,1000000000,1000000000]]\n * Output: 49\n * Explanation: The answer is 10^18 modulo (10^9 + 7), which is (10^9)^2 = (-7)^2 = 49.\n * \n * Note:\n * 1 <= rectangles.length <= 200\n * rectanges[i].length = 4\n * 0 <= rectangles[i][j] <= 10^9\n * The total area covered by all rectangles will never exceed 2^63 - 1 and\n * thus will fit in a 64-bit signed integer.\n */\n\n\npublic class RectangleAreaII850 {\n    /**\n     * https://leetcode.com/problems/rectangle-area-ii/\n     * Sweep Line + Meeting Room + Merge Intervals\n     */\n    private static int MOD = 1_000_000_007;\n    public int rectangleArea(int[][] rectangles) {\n        int OPEN = 0, CLOSE = 1;\n        int[][] events = new int[rectangles.length * 2][];\n        int t = 0;\n        for (int[] rec: rectangles) {\n            events[t++] = new int[]{rec[1], OPEN, rec[0], rec[2]};\n            events[t++] = new int[]{rec[3], CLOSE, rec[0], rec[2]};\n        }\n        Arrays.sort(events, (a, b) -> Integer.compare(a[0], b[0]));\n\n        List<int[]> active = new ArrayList();\n        int currY = events[0][0];\n        long ans = 0;\n        for (int[] event: events) {\n            int y = event[0], typ = event[1], x1 = event[2], x2 = event[3];\n            ans += mergeIntervals(active) * (y - currY);\n            if (typ == OPEN) {\n                active.add(new int[]{x1, x2});\n            } else {\n                for (int i = 0; i < active.size(); ++i) {\n                    if (active.get(i)[0] == x1 && active.get(i)[1] == x2) {\n                        active.remove(i);\n                        break;\n                    }\n                }\n            }\n            currY = y;\n        }\n        ans %= MOD;\n        return (int) ans;\n    }\n\n    private long mergeIntervals(List<int[]> active) {\n        long query = 0;\n        int cur = -1;\n        Collections.sort(active, (a, b) -> Integer.compare(a[0], b[0]));\n        for (int[] xs: active) {\n            cur = Math.max(cur, xs[0]);\n            query += Math.max(xs[1] - cur, 0);\n            cur = Math.max(cur, xs[1]);\n        }\n        return query;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/rectangle-area-ii/solution/\n     */\n    public int rectangleArea2(int[][] rectangles) {\n        int OPEN = 1, CLOSE = -1;\n        int[][] events = new int[rectangles.length * 2][];\n        Set<Integer> Xvals = new HashSet();\n        int t = 0;\n        for (int[] rec: rectangles) {\n            events[t++] = new int[]{rec[1], OPEN, rec[0], rec[2]};\n            events[t++] = new int[]{rec[3], CLOSE, rec[0], rec[2]};\n            Xvals.add(rec[0]);\n            Xvals.add(rec[2]);\n        }\n\n        Arrays.sort(events, (a, b) -> Integer.compare(a[0], b[0]));\n\n        Integer[] X = Xvals.toArray(new Integer[0]);\n        Arrays.sort(X);\n        Map<Integer, Integer> Xi = new HashMap();\n        for (int i = 0; i < X.length; ++i)\n            Xi.put(X[i], i);\n\n        Node active = new Node(0, X.length - 1, X);\n        long ans = 0;\n        long cur_x_sum = 0;\n        int cur_y = events[0][0];\n\n        for (int[] event: events) {\n            int y = event[0], typ = event[1], x1 = event[2], x2 = event[3];\n            ans += cur_x_sum * (y - cur_y);\n            cur_x_sum = active.update(Xi.get(x1), Xi.get(x2), typ);\n            cur_y = y;\n\n        }\n\n        ans %= 1_000_000_007;\n        return (int) ans;\n    }\n\n\n    class Node {\n        int start, end;\n        Integer[] X;\n        Node left, right;\n        int count;\n        long total;\n\n        public Node(int start, int end, Integer[] X) {\n            this.start = start;\n            this.end = end;\n            this.X = X;\n            left = null;\n            right = null;\n            count = 0;\n            total = 0;\n        }\n\n        public int getRangeMid() {\n            return start + (end - start) / 2;\n        }\n\n        public Node getLeft() {\n            if (left == null) left = new Node(start, getRangeMid(), X);\n            return left;\n        }\n\n        public Node getRight() {\n            if (right == null) right = new Node(getRangeMid(), end, X);\n            return right;\n        }\n\n        public long update(int i, int j, int val) {\n            if (i >= j) return 0;\n            if (start == i && end == j) {\n                count += val;\n            } else {\n                getLeft().update(i, Math.min(getRangeMid(), j), val);\n                getRight().update(Math.max(getRangeMid(), i), j, val);\n            }\n\n            if (count > 0) total = X[end] - X[start];\n            else total = getLeft().total + getRight().total;\n    \n            return total;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/RectangleOverlap863.java",
    "content": "/**\n * A rectangle is represented as a list [x1, y1, x2, y2], where (x1, y1) are\n * the coordinates of its bottom-left corner, and (x2, y2) are the coordinates\n * of its top-right corner.\n * \n * Two rectangles overlap if the area of their intersection is positive. To be\n * clear, two rectangles that only touch at the corner or edges do not overlap.\n * \n * Given two (axis-aligned) rectangles, return whether they overlap.\n * \n * Example 1:\n * Input: rec1 = [0,0,2,2], rec2 = [1,1,3,3]\n * Output: true\n * \n * Example 2:\n * Input: rec1 = [0,0,1,1], rec2 = [1,0,2,1]\n * Output: false\n * \n * Notes:\n * Both rectangles rec1 and rec2 are lists of 4 integers.\n * All coordinates in rectangles will be between -10^9 and 10^9.\n */\n\npublic class RectangleOverlap863 {\n    public boolean isRectangleOverlap(int[] rec1, int[] rec2) {\n        return isIntervalOverlap(rec1[0], rec1[2], rec2[0], rec2[2]) && isIntervalOverlap(rec1[1], rec1[3], rec2[1], rec2[3]);\n    }\n\n    private boolean isIntervalOverlap(int a1, int a2, int b1, int b2) {\n        return !(a2 <= b1 || b2 <= a1);\n    }\n\n\n    public boolean isRectangleOverlap2(int[] rec1, int[] rec2) {\n        return !(rec1[2] <= rec2[0] ||   // left\n                rec1[3] <= rec2[1] ||   // bottom\n                rec1[0] >= rec2[2] ||   // right\n                rec1[1] >= rec2[3]);    // top\n    }\n\n}\n"
  },
  {
    "path": "src/RedundantConnection684.java",
    "content": "/**\n * In this problem, a tree is an undirected graph that is connected and has no cycles.\n *\n * The given input is a graph that started as a tree with N nodes (with distinct\n * values 1, 2, ..., N), with one additional edge added. The added edge has two\n * different vertices chosen from 1 to N, and was not an edge that already existed.\n *\n * The resulting graph is given as a 2D-array of edges. Each element of edges\n * is a pair [u, v] with u < v, that represents an undirected edge connecting\n * nodes u and v.\n *\n * Return an edge that can be removed so that the resulting graph is a tree of\n * N nodes. If there are multiple answers, return the answer that occurs last\n * in the given 2D-array. The answer edge [u, v] should be in the same format,\n * with u < v.\n *\n * Example 1:\n * Input: [[1,2], [1,3], [2,3]]\n * Output: [2,3]\n * Explanation: The given undirected graph will be like this:\n *   1\n *  / \\\n * 2 - 3\n *\n * Example 2:\n * Input: [[1,2], [2,3], [3,4], [1,4], [1,5]]\n * Output: [1,4]\n * Explanation: The given undirected graph will be like this:\n * 5 - 1 - 2\n *     |   |\n *     4 - 3\n *\n * Note:\n * The size of the input 2D-array will be between 3 and 1000.\n * Every integer represented in the 2D-array will be between 1 and N, where N\n * is the size of the input array.\n *\n * Update (2017-09-26):\n * We have overhauled the problem description + test cases and specified clearly\n * the graph is an undirected graph. For the directed graph follow up please\n * see Redundant Connection II). We apologize for any inconvenience caused.\n *\n */\n\n\npublic class RedundantConnection684 {\n    public int[] findRedundantConnection(int[][] edges) {\n        Map<Integer, Set<Integer>> graph = new HashMap<>();\n        Set<Integer> visited = new HashSet<>();\n\n        for (int[] edge: edges) {\n            visited.clear();\n            Set<Integer> set0 = graph.getOrDefault(edge[0], new HashSet<Integer>());\n            Set<Integer> set1 = graph.getOrDefault(edge[1], new HashSet<Integer>());\n            if (!set0.isEmpty() && !set1.isEmpty() && dfs(graph, edge[0], edge[1], visited)) {\n                return edge;\n            }\n            set0.add(edge[1]);\n            graph.put(edge[0], set0);\n            set1.add(edge[0]);\n            graph.put(edge[1], set1);\n        }\n\n        return null;\n    }\n\n    private boolean dfs(Map<Integer, Set<Integer>> graph, int source, int target, Set<Integer> visited) {\n        if (!visited.contains(source)) {\n            visited.add(source);\n            if (source == target) return true;\n            for (int nei: graph.get(source)) {\n                if (dfs(graph, nei, target, visited)) return true;\n            }\n        }\n        return false;\n    }\n\n\n\n    /**\n     * https://leetcode.com/problems/redundant-connection/solution/\n     */\n    Set<Integer> seen = new HashSet();\n    int MAX_EDGE_VAL = 1000;\n\n    public int[] findRedundantConnection2(int[][] edges) {\n        ArrayList<Integer>[] graph = new ArrayList[MAX_EDGE_VAL + 1];\n        for (int i = 0; i <= MAX_EDGE_VAL; i++) {\n            graph[i] = new ArrayList();\n        }\n\n        for (int[] edge: edges) {\n            seen.clear();\n            if (!graph[edge[0]].isEmpty() && !graph[edge[1]].isEmpty() &&\n                    dfs(graph, edge[0], edge[1])) {\n                return edge;\n            }\n            graph[edge[0]].add(edge[1]);\n            graph[edge[1]].add(edge[0]);\n        }\n        throw new AssertionError();\n    }\n\n    public boolean dfs(ArrayList<Integer>[] graph, int source, int target) {\n        if (!seen.contains(source)) {\n            seen.add(source);\n            if (source == target) return true;\n            for (int nei: graph[source]) {\n                if (dfs(graph, nei, target)) return true;\n            }\n        }\n        return false;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/redundant-connection/solution/\n     */\n    public int[] findRedundantConnection3(int[][] edges) {\n        DSU dsu = new DSU(MAX_EDGE_VAL + 1);\n        for (int[] edge: edges) {\n            if (!dsu.union(edge[0], edge[1])) return edge;\n        }\n        throw new AssertionError();\n    }\n\n\n    /**\n     * https://leetcode.com/problems/redundant-connection/discuss/107984/10-line-Java-solution-Union-Find\n     */\n    public int[] findRedundantConnection4(int[][] edges) {\n        int[] parent = new int[1001];\n        for (int i = 0; i < parent.length; i++) parent[i] = i;\n\n        for (int[] edge: edges){\n            int f = edge[0], t = edge[1];\n            if (find(parent, f) == find(parent, t)) return edge;\n            else parent[find(parent, f)] = find(parent, t);\n        }\n\n        return new int[2];\n    }\n\n    private int find(int[] parent, int f) {\n        if (f != parent[f]) {\n          parent[f] = find(parent, parent[f]);\n        }\n        return parent[f];\n    }\n\n\n\n}\n\nclass DSU {\n    int[] parent;\n    int[] rank;\n\n    public DSU(int size) {\n        parent = new int[size];\n        for (int i = 0; i < size; i++) parent[i] = i;\n        rank = new int[size];\n    }\n\n    public int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n\n    public boolean union(int x, int y) {\n        int xr = find(x), yr = find(y);\n        if (xr == yr) {\n            return false;\n        } else if (rank[xr] < rank[yr]) {\n            parent[xr] = yr;\n        } else if (rank[xr] > rank[yr]) {\n            parent[yr] = xr;\n        } else {\n            parent[yr] = xr;\n            rank[xr]++;\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/RedundantConnectionII685.java",
    "content": "/**\n * In this problem, a rooted tree is a directed graph such that, there is\n * exactly one node (the root) for which all other nodes are descendants of\n * this node, plus every node has exactly one parent, except for the root\n * node which has no parents.\n * \n * The given input is a directed graph that started as a rooted tree with N\n * nodes (with distinct values 1, 2, ..., N), with one additional directed\n * edge added. The added edge has two different vertices chosen from 1 to N,\n * and was not an edge that already existed.\n * \n * The resulting graph is given as a 2D-array of edges. Each element of edges\n * is a pair [u, v] that represents a directed edge connecting nodes u and v,\n * where u is a parent of child v.\n * \n * Return an edge that can be removed so that the resulting graph is a rooted\n * tree of N nodes. If there are multiple answers, return the answer that\n * occurs last in the given 2D-array.\n * \n * Example 1:\n * Input: [[1,2], [1,3], [2,3]]\n * Output: [2,3]\n * Explanation: The given directed graph will be like this:\n *   1\n *  / \\\n * v   v\n * 2-->3\n * \n * Example 2:\n * Input: [[1,2], [2,3], [3,4], [4,1], [1,5]]\n * Output: [4,1]\n * Explanation: The given directed graph will be like this:\n * 5 <- 1 -> 2\n *      ^    |\n *      |    v\n *      4 <- 3\n * \n * Note:\n * The size of the input 2D-array will be between 3 and 1000.\n * Every integer represented in the 2D-array will be between 1 and N,\n * where N is the size of the input array.\n */\n\n\npublic class RedundantConnectionII685 {\n    public int[] findRedundantDirectedConnection(int[][] edges) {\n        int N = edges.length;\n        int[] res1 = null;\n        int[] res2 = null;\n        \n        int[] parent = new int[N+1];\n        boolean twoParentsExist = false;\n        for (int[] edge: edges) {\n            int u = edge[0];\n            int v = edge[1];\n            if (parent[v] != 0) {\n                res1 = new int[]{parent[v], v};\n                res2 = new int[]{u, v};\n                twoParentsExist = true;\n                break;\n            }\n            parent[v] = u;\n        }\n        \n        DisjointSet djs = new DisjointSet(N);\n        for (int[] edge: edges) {\n            int u = edge[0];\n            int v = edge[1];\n            if (twoParentsExist && ((u == res1[0] && v == res1[1]) || (u == res2[0] && v == res2[1]))) continue;\n            int up = djs.find(u);\n            int vp = djs.find(v);\n\n            if (up == vp) {\n                return edge;\n            } else {\n                djs.union(u, v);\n            }\n        }      \n        if (twoParentsExist && djs.find(res1[0]) == djs.find(res1[1])) {\n            return res1;\n        }\n        return res2;\n    }\n\n    class DisjointSet {\n        int[] parent;\n        int[] rank;\n        DisjointSet(int N) {\n            parent = new int[N+1];\n            for (int i=0; i<N; i++) parent[i] = i;\n            rank = new int[N+1];\n        }\n        \n        int find(int x) {\n            if (parent[x] != x) {\n                parent[x] = find(parent[x]);\n            }\n            return parent[x];\n        }\n        \n        void union(int x, int y) {\n            int xp = find(x);\n            int yp = find(y);\n            \n            if (rank[xp] > rank[yp]) {\n                parent[yp] = xp;\n            } else if (rank[xp] < rank[yp]) {\n                parent[xp] = yp;\n            } else {\n                parent[xp] = yp;\n                rank[yp]++;\n            }\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/redundant-connection-ii/discuss/108045/C++Java-Union-Find-with-explanation-O(n)\n     */\n    public int[] findRedundantDirectedConnection2(int[][] edges) {\n        int[] can1 = {-1, -1};\n        int[] can2 = {-1, -1};\n        int[] parent = new int[edges.length + 1];\n        for (int i = 0; i < edges.length; i++) {\n            if (parent[edges[i][1]] == 0) {\n                parent[edges[i][1]] = edges[i][0];\n            } else {\n                can2 = new int[] {edges[i][0], edges[i][1]};\n                can1 = new int[] {parent[edges[i][1]], edges[i][1]};\n                edges[i][1] = 0;\n            }\n        }\n        for (int i = 0; i < edges.length; i++) {\n            parent[i] = i;\n        }\n        for (int i = 0; i < edges.length; i++) {\n            if (edges[i][1] == 0) {\n                continue;\n            }\n            int child = edges[i][1], father = edges[i][0];\n            if (root(parent, father) == child) {\n                if (can1[0] == -1) {\n                    return edges[i];\n                }\n                return can1;\n            }\n            parent[child] = father;\n        }\n        return can2;\n    }\n    \n    int root(int[] parent, int i) {\n        while (i != parent[i]) {\n            parent[i] = parent[parent[i]];\n            i = parent[i];\n        }   \n        return i;\n    }\n\n}\n\n"
  },
  {
    "path": "src/RegularExpressionMatching10.java",
    "content": "/**\n * Implement regular expression matching with support for '.' and '*'.\n *\n * '.' Matches any single character.\n * '*' Matches zero or more of the preceding element.\n *\n * The matching should cover the entire input string (not partial).\n *\n * The function prototype should be:\n * bool isMatch(const char *s, const char *p)\n *\n * Some examples:\n * isMatch(\"aa\",\"a\") → false\n * isMatch(\"aa\",\"aa\") → true\n * isMatch(\"aaa\",\"aa\") → false\n * isMatch(\"aa\", \"a*\") → true\n * isMatch(\"aa\", \".*\") → true\n * isMatch(\"ab\", \".*\") → true\n * isMatch(\"aab\", \"c*a*b\") → true\n *\n */\n\n\npublic class RegularExpressionMatching10 {\n\n    /**\n     * https://leetcode.com/problems/regular-expression-matching/solution/\n     */\n    public boolean isMatch(String text, String pattern) {\n        if (pattern.isEmpty()) return text.isEmpty();\n        boolean first_match = (!text.isEmpty() &&\n                               (pattern.charAt(0) == text.charAt(0) || pattern.charAt(0) == '.'));\n\n        if (pattern.length() >= 2 && pattern.charAt(1) == '*'){\n            return (isMatch(text, pattern.substring(2)) ||\n                    (first_match && isMatch(text.substring(1), pattern)));\n        } else {\n            return first_match && isMatch(text.substring(1), pattern.substring(1));\n        }\n    }\n\n\n    public boolean isMatch2(String text, String pattern) {\n        return isMatch(0, 0, text, pattern);\n    }\n\n    public boolean isMatch(int i, int j, String text, String pattern) {\n        if (j == pattern.length()) return i == text.length();\n        boolean first_match = (i != text.length() &&\n                               (pattern.charAt(j) == text.charAt(i) || pattern.charAt(j) == '.'));\n\n        if (pattern.length() >= j+2 && pattern.charAt(j+1) == '*'){\n            return (isMatch(i, j+2, text, pattern) ||\n                    (first_match && isMatch(i+1, j, text, pattern)));\n        } else {\n            return first_match && isMatch(i+1, j+1, text, pattern);\n        }\n    }\n\n\n    public boolean isMatch3(String text, String pattern) {\n        int textLen = text.length();\n        int pattLen = pattern.length();\n        boolean[][] dp = new boolean[textLen+1][pattLen+1];\n        dp[0][0] = true;\n\n        for(int j=1; j<=pattLen; j++) {\n            if (pattern.charAt(j-1) == '*'){\n                dp[0][j] = dp[0][j-2];\n            }\n        }\n\n        for (int i=1; i<=textLen; i++) {\n            for(int j=1; j<=pattLen; j++) {\n                if (j >= 2 && pattern.charAt(j-1) == '*') {\n                    boolean preMatch = (pattern.charAt(j-2) == text.charAt(i-1) || pattern.charAt(j-2) == '.');\n                    dp[i][j] = dp[i][j-2] || (preMatch && dp[i-1][j]);\n                } else {\n                    boolean currMatch = (pattern.charAt(j-1) == text.charAt(i-1) || pattern.charAt(j-1) == '.');\n                    dp[i][j] = currMatch && dp[i-1][j-1];\n                }\n            }\n        }\n\n        return dp[text.length()][pattern.length()];\n    }\n\n\n    /**\n     * https://leetcode.com/problems/regular-expression-matching/solution/\n     */\n    enum Result {\n        TRUE, FALSE\n    }\n    Result[][] memo;\n\n    public boolean isMatch4(String text, String pattern) {\n        memo = new Result[text.length() + 1][pattern.length() + 1];\n        return dp(0, 0, text, pattern);\n    }\n\n    public boolean dp(int i, int j, String text, String pattern) {\n        if (memo[i][j] != null) {\n            return memo[i][j] == Result.TRUE;\n        }\n        boolean ans;\n        if (j == pattern.length()){\n            ans = i == text.length();\n        } else{\n            boolean first_match = (i < text.length() &&\n                                   (pattern.charAt(j) == text.charAt(i) ||\n                                    pattern.charAt(j) == '.'));\n\n            if (j + 1 < pattern.length() && pattern.charAt(j+1) == '*'){\n                ans = (dp(i, j+2, text, pattern) ||\n                       first_match && dp(i+1, j, text, pattern));\n            } else {\n                ans = first_match && dp(i+1, j+1, text, pattern);\n            }\n        }\n        memo[i][j] = ans ? Result.TRUE : Result.FALSE;\n        return ans;\n    }\n\n\n    public boolean isMatch5(String s, String p) {\n        if (s == null || p == null) return false;\n\n        boolean[][] dp = new boolean[s.length()+1][p.length()+1];\n        dp[0][0] = true;\n        for (int j=1; j<=p.length(); j++) dp[0][j] = p.charAt(j-1) == '*' ? dp[0][j-2] : false;\n        for (int i=1; i<=s.length(); i++) dp[i][0] = false;\n\n        for (int i=1; i<=s.length(); i++) {\n            for (int j=1; j<=p.length(); j++) {\n                char c = p.charAt(j-1);\n                switch (c) {\n                    case '.':\n                        dp[i][j] = dp[i-1][j-1];\n                        break;\n                    case '*':\n                        dp[i][j] = dp[i][j-2] || ((p.charAt(j-2) == '.' || p.charAt(j-2) == s.charAt(i-1)) && dp[i-1][j]);\n                        break;\n                    default:\n                        dp[i][j] = s.charAt(i-1) == p.charAt(j-1) && dp[i-1][j-1];\n                }\n            }\n        }\n        return dp[s.length()][p.length()];\n    }\n\n}\n"
  },
  {
    "path": "src/RemoveDuplicateLetters316.java",
    "content": "/**\n * Given a string which contains only lowercase letters, remove duplicate letters so that every\n * letter appear once and only once. You must make sure your result is the smallest in\n * lexicographical order among all possible results.\n * \n * Example:\n * Given \"bcabc\"\n * Return \"abc\"\n * \n * Given \"cbacdcbc\"\n * Return \"acdb\"\n */\n\npublic class RemoveDuplicateLetters316 {\n\n    /**\n     * https://leetcode.com/problems/remove-duplicate-letters/discuss/76766/Easy-to-understand-iterative-Java-solution\n     */\n    public String removeDuplicateLetters(String s) {\n        if (s == null || s.length() <= 1) return s;\n\n        Map<Character, Integer> lastPosMap = new HashMap<>();\n        for (int i = 0; i < s.length(); i++) {\n            lastPosMap.put(s.charAt(i), i);\n        }\n\n        char[] result = new char[lastPosMap.size()];\n        int begin = 0, end = findMinLastPos(lastPosMap);\n\n        for (int i = 0; i < result.length; i++) {\n            char minChar = 'z' + 1;\n            for (int k = begin; k <= end; k++) {\n                if (lastPosMap.containsKey(s.charAt(k)) && s.charAt(k) < minChar) {\n                    minChar = s.charAt(k);\n                    begin = k+1;\n                }\n            }\n\n            result[i] = minChar;\n            if (i == result.length-1) break;\n\n            lastPosMap.remove(minChar);\n            if (s.charAt(end) == minChar) end = findMinLastPos(lastPosMap);\n        }\n\n        return new String(result);\n    }\n\n    private int findMinLastPos(Map<Character, Integer> lastPosMap) {\n        if (lastPosMap == null || lastPosMap.isEmpty()) return -1;\n        int minLastPos = Integer.MAX_VALUE;\n        for (int lastPos : lastPosMap.values()) {\n             minLastPos = Math.min(minLastPos, lastPos);\n        }\n        return minLastPos;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/remove-duplicate-letters/discuss/76762/Java-O(n)-solution-using-stack-with-detail-explanation\n     */\n    public String removeDuplicateLetters2(String s) {\n        Stack<Character> stack = new Stack<>();\n        int[] count = new int[26];\n        char[] arr = s.toCharArray();\n        for(char c : arr) {\n            count[c-'a']++;\n        }\n        boolean[] visited = new boolean[26];\n        for(char c : arr) {\n            count[c-'a']--;\n            if(visited[c-'a']) {\n                continue;\n            }\n            while(!stack.isEmpty() && stack.peek() > c && count[stack.peek()-'a'] > 0) {\n                visited[stack.peek()-'a'] = false;\n                stack.pop();\n            }\n            stack.push(c);\n            visited[c-'a'] = true;\n        }\n        StringBuilder sb = new StringBuilder();\n        for(char c : stack) {\n            sb.append(c);\n        }\n        return sb.toString();\n    }\n\n}"
  },
  {
    "path": "src/RemoveDuplicatesFromSortedArray26.java",
    "content": "/**\n * Given a sorted array, remove the duplicates in place such that each element\n * appear only once and return the new length.\n *\n * Do not allocate extra space for another array, you must do this in place with\n * constant memory.\n *\n * For example,\n * Given input array nums = [1,1,2],\n *\n * Your function should return length = 2, with the first two elements of nums\n * being 1 and 2 respectively. It doesn't matter what you leave beyond the new\n * length.\n *\n */\n\npublic class RemoveDuplicatesFromSortedArray26 {\n    public int removeDuplicates(int[] nums) {\n        if (nums.length <= 1) {\n            return nums.length;\n        }\n        int slow = 0;\n        int fast = 1;\n        while (fast < nums.length) {\n            if (nums[fast] != nums[slow]) {\n                slow++;\n                nums[slow] = nums[fast];\n            }\n            fast++;\n        }\n        return slow+1;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/17252/5-lines-c-java-nicer-loops\n     */\n    public int removeDuplicates2(int[] nums) {\n        int i = nums.length > 0 ? 1 : 0;\n        for (int n : nums)\n            if (n > nums[i-1])\n                nums[i++] = n;\n        return i;\n    }\n\n\n    public int removeDuplicates3(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        int len = nums.length;\n        int i = 0;\n        int j = 0;\n        while (j < len) {\n            while (j > 0 && j < len && nums[j] == nums[j-1]) j++;\n            if (j == len) break;\n            nums[i++] = nums[j++];\n        }\n        return i;\n    }\n\n}\n"
  },
  {
    "path": "src/RemoveDuplicatesFromSortedArrayII80.java",
    "content": "/**\n * Follow up for \"Remove Duplicates\":\n * What if duplicates are allowed at most twice?\n *\n * For example,\n * Given sorted array nums = [1,1,1,2,2,3],\n *\n * Your function should return length = 5, with the first five elements of nums\n * being 1, 1, 2, 2 and 3. It doesn't matter what you leave beyond the new length.\n *\n */\n\npublic class RemoveDuplicatesFromSortedArrayII80 {\n    public int removeDuplicates(int[] nums) {\n        int count = 1;\n        int i = 0;\n        for (int j=1; j<nums.length; j++) {\n            if (nums[i] != nums[j]) {\n                i++;\n                nums[i] = nums[j];\n                count = 1;\n            } else if (count < 2)  {\n                count++;\n                i++;\n                nums[i] = nums[j];\n            }\n        }\n        return i+1;\n    }\n\n    /**\n     * https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii/discuss/27987/Short-and-Simple-Java-solution-(easy-to-understand)\n     */\n    public int removeDuplicates2(int[] nums) {\n       int i = 0;\n       for (int n : nums)\n          if (i < 2 || n > nums[i - 2])\n             nums[i++] = n;\n       return i;\n    }\n\n    // private int removeDuplicates(int[] nums, int k) {\n    //     int i = 0;\n    //     for (int n : nums)\n    //         if (i < k || n > nums[i-k])\n    //             nums[i++] = n;\n    //     return i;\n    // }\n\n}\n"
  },
  {
    "path": "src/RemoveDuplicatesFromSortedList83.java",
    "content": "/**\n * Given a sorted linked list, delete all duplicates such that each element\n * appear only once.\n * \n * Example 1:\n * Input: 1->1->2\n * Output: 1->2\n * \n * Example 2:\n * Input: 1->1->2->3->3\n * Output: 1->2->3\n */\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\npublic class RemoveDuplicatesFromSortedList83 {\n    public ListNode deleteDuplicates(ListNode head) {\n        if (head == null || head.next == null) return head; \n        ListNode fast = head.next;\n        ListNode slow = head;\n        slow.next = null;\n        while (fast != null) {\n            if (fast.val == slow.val) {\n                fast = fast.next;\n            } else {\n                slow.next = fast;\n                fast = fast.next;\n                slow = slow.next;\n                slow.next = null;\n            }\n        }\n        return head;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/remove-duplicates-from-sorted-list/solution/\n     */\n    public ListNode deleteDuplicates2(ListNode head) {\n        ListNode current = head;\n        while (current != null && current.next != null) {\n            if (current.next.val == current.val) {\n                current.next = current.next.next;\n            } else {\n                current = current.next;\n            }\n        }\n        return head;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/remove-duplicates-from-sorted-list/discuss/28625/3-Line-JAVA-recursive-solution\n     */\n    public ListNode deleteDuplicates3(ListNode head) {\n        if (head == null || head.next == null) return head;\n        head.next = deleteDuplicates3(head.next);\n        return head.val == head.next.val ? head.next : head;\n    }\n\n}\n"
  },
  {
    "path": "src/RemoveDuplicatesFromSortedListII82.java",
    "content": "/**\n * Given a sorted linked list, delete all nodes that have duplicate numbers,\n * leaving only distinct numbers from the original list.\n *\n * For example,\n * Given 1->2->3->3->4->4->5, return 1->2->5.\n * Given 1->1->1->2->3, return 2->3.\n *\n */\n\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\n\npublic class RemoveDuplicatesFromSortedListII82 {\n    public ListNode deleteDuplicates(ListNode head) {\n        ListNode dummy = new ListNode(0);\n        dummy.next = head;\n        ListNode p = dummy;\n        boolean isDuplicate = false;\n        int dup = 0;\n        while (p.next != null && p.next.next != null) {\n            if (isDuplicate) {\n                do {\n                    p.next = p.next.next;\n                } while (p.next != null && p.next.val == dup);\n                isDuplicate = false;\n            } else {\n                if (p.next.val != p.next.next.val) {\n                    p = p.next;\n                } else {\n                    isDuplicate = true;\n                    dup = p.next.val;\n                }\n            }\n        }\n        return dummy.next;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/3890/my-accepted-java-code\n     */\n    public ListNode deleteDuplicates2(ListNode head) {\n        if(head==null) return null;\n        ListNode FakeHead=new ListNode(0);\n        FakeHead.next=head;\n        ListNode pre=FakeHead;\n        ListNode cur=head;\n        while(cur!=null){\n            while(cur.next!=null&&cur.val==cur.next.val){\n                cur=cur.next;\n            }\n            if(pre.next==cur){\n                pre=pre.next;\n            }\n            else{\n                pre.next=cur.next;\n            }\n            cur=cur.next;\n        }\n        return FakeHead.next;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/5206/my-recursive-java-solution\n     */\n    public ListNode deleteDuplicates3(ListNode head) {\n        if (head == null) return null;\n\n        if (head.next != null && head.val == head.next.val) {\n            while (head.next != null && head.val == head.next.val) {\n                head = head.next;\n            }\n            return deleteDuplicates3(head.next);\n        } else {\n            head.next = deleteDuplicates3(head.next);\n        }\n        return head;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/24470/java-simple-and-clean-code-with-comment\n     */\n    public ListNode deleteDuplicates4(ListNode head) {\n    \t  //use two pointers, slow - track the node before the dup nodes,\n    \t  // fast - to find the last node of dups.\n        ListNode dummy = new ListNode(0), fast = head, slow = dummy;\n        slow.next = fast;\n        while(fast != null) {\n            while (fast.next != null && fast.val == fast.next.val) {\n                fast = fast.next;    //while loop to find the last node of the dups.\n            }\n            if (slow.next != fast) { //duplicates detected.\n                slow.next = fast.next; //remove the dups.\n                fast = slow.next;     //reposition the fast pointer.\n            } else { //no dup, move down both pointer.\n                slow = slow.next;\n                fast = fast.next;\n            }\n        }\n        return dummy.next;\n    }\n\n\n}\n"
  },
  {
    "path": "src/RemoveInvalidParentheses301.java",
    "content": "/**\n * Remove the minimum number of invalid parentheses in order to make the input\n * string valid. Return all possible results.\n *\n * Note: The input string may contain letters other than the parentheses ( and ).\n *\n * Examples:\n *      \"()())()\" -> [\"()()()\", \"(())()\"]\n *      \"(a)())()\" -> [\"(a)()()\", \"(a())()\"]\n *      \")(\" -> [\"\"]\n */\n\n\n/**\n * A review of all solutions (BFS and DFS)\n * https://leetcode.com/problems/remove-invalid-parentheses/discuss/75038/Evolve-from-intuitive-solution-to-optimal-a-review-of-all-solutions\n *\n * There are three challenges:\n *   - Remove minimum parenthesis\n *   - The result is valid\n *   - Without duplicates.\n *\n */\n\n\npublic class RemoveInvalidParentheses301 {\n    public List<String> removeInvalidParentheses(String s) {\n        Set<String> results = new HashSet<>();\n        int L = s.length();\n        if (L == 0) return Arrays.asList(\"\");\n\n        Stack<Character> st = new Stack<>();\n        StringBuilder sb = new StringBuilder(\"\");\n\n        int maxLength = helper(s, 0, st, sb, L, results);\n\n        return setToList(results, maxLength);\n    }\n\n    private int helper(String s, int level, Stack<Character> st, StringBuilder sb, int L, Set<String> results) {\n        int maxLength = 0;\n        if (level == L) {\n            if (st.size() == 0) {\n                maxLength = Math.max(maxLength, sb.length());\n                results.add(sb.toString());\n            }\n            return maxLength;\n        }\n\n        char c = s.charAt(level);\n        int localMax = 0;\n        if (c >= 'a' && c <= 'z') {\n            sb.append(c);\n            localMax = helper(s, level+1, st, sb, L, results);\n            maxLength = Math.max(maxLength, localMax);\n            sb.deleteCharAt(sb.length()-1);\n        } else if (c == '(') {\n            st.push('(');\n            sb.append('(');\n            localMax = helper(s, level+1, st, sb, L, results);\n            maxLength = Math.max(maxLength, localMax);\n            st.pop();\n            sb.deleteCharAt(sb.length()-1);\n            localMax = helper(s, level+1, st, sb, L, results);\n            maxLength = Math.max(maxLength, localMax);\n        } else if (c == ')' && !st.empty() && st.peek() == '(') {\n            st.pop();\n            sb.append(c);\n            localMax = helper(s, level+1, st, sb, L, results);\n            maxLength = Math.max(maxLength, localMax);\n            st.push('(');\n            sb.deleteCharAt(sb.length()-1);\n            localMax = helper(s, level+1, st, sb, L, results);\n            maxLength = Math.max(maxLength, localMax);\n        } else {\n            localMax = helper(s, level+1, st, sb, L, results);\n            maxLength = Math.max(maxLength, localMax);\n        }\n\n        return maxLength;\n    }\n\n\n    private List<String> setToList(Set<String> set, int maxLength) {\n        List<String> results = new ArrayList<>();\n        for (String s: set) {\n            if (s.length() == maxLength) {\n                results.add(s);\n            }\n        }\n        return results;\n    }\n\n\n\n    /**\n     * https://discuss.leetcode.com/topic/34875/easy-short-concise-and-fast-java-dfs-3-ms-solution\n     */\n    public List<String> removeInvalidParentheses2(String s) {\n        List<String> ans = new ArrayList<>();\n        remove(s, ans, 0, 0, new char[]{'(', ')'});\n        return ans;\n    }\n\n    public void remove(String s, List<String> ans, int last_i, int last_j,  char[] par) {\n        for (int stack = 0, i = last_i; i < s.length(); ++i) {\n            if (s.charAt(i) == par[0]) stack++;\n            if (s.charAt(i) == par[1]) stack--;\n            if (stack >= 0) continue;\n            for (int j = last_j; j <= i; ++j)\n                if (s.charAt(j) == par[1] && (j == last_j || s.charAt(j - 1) != par[1]))\n                    remove(s.substring(0, j) + s.substring(j + 1, s.length()), ans, i, j, par);\n            return;\n        }\n        String reversed = new StringBuilder(s).reverse().toString();\n        if (par[0] == '(') // finished left to right\n            remove(reversed, ans, 0, 0, new char[]{')', '('});\n        else // finished right to left\n            ans.add(reversed);\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/28827/share-my-java-bfs-solution\n     */\n    public List<String> removeInvalidParentheses3(String s) {\n      List<String> res = new ArrayList<>();\n\n      // sanity check\n      if (s == null) return res;\n\n      Set<String> visited = new HashSet<>();\n      Queue<String> queue = new LinkedList<>();\n\n      // initialize\n      queue.add(s);\n      visited.add(s);\n\n      boolean found = false;\n\n      while (!queue.isEmpty()) {\n        s = queue.poll();\n\n        if (isValid(s)) {\n          // found an answer, add to the result\n          res.add(s);\n          found = true;\n        }\n\n        if (found) continue;\n\n        // generate all possible states\n        for (int i = 0; i < s.length(); i++) {\n          // we only try to remove left or right paren\n          if (s.charAt(i) != '(' && s.charAt(i) != ')') continue;\n\n          String t = s.substring(0, i) + s.substring(i + 1);\n\n          if (!visited.contains(t)) {\n            // for each state, if it's not visited, add it to the queue\n            queue.add(t);\n            visited.add(t);\n          }\n        }\n      }\n\n      return res;\n    }\n\n    // helper function checks if string s contains valid parantheses\n    boolean isValid(String s) {\n      int count = 0;\n\n      for (int i = 0; i < s.length(); i++) {\n        char c = s.charAt(i);\n        if (c == '(') count++;\n        if (c == ')' && count-- == 0) return false;\n      }\n\n      return count == 0;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/30743/easiest-9ms-java-solution\n     */\n    public List<String> removeInvalidParentheses4(String s) {\n        int rmL = 0, rmR = 0;\n        for (int i = 0; i < s.length(); i++) {\n            if (s.charAt(i) == '(') {\n                rmL++;\n            } else if (s.charAt(i) == ')') {\n                if (rmL != 0) {\n                    rmL--;\n                } else {\n                    rmR++;\n                }\n            }\n        }\n        Set<String> res = new HashSet<>();\n        dfs(s, 0, res, new StringBuilder(), rmL, rmR, 0);\n        return new ArrayList<String>(res);\n    }\n\n    public void dfs(String s, int i, Set<String> res, StringBuilder sb, int rmL, int rmR, int open) {\n        if (rmL < 0 || rmR < 0 || open < 0) {\n            return;\n        }\n        if (i == s.length()) {\n            if (rmL == 0 && rmR == 0 && open == 0) {\n                res.add(sb.toString());\n            }\n            return;\n        }\n\n        char c = s.charAt(i);\n        int len = sb.length();\n\n        if (c == '(') {\n            dfs(s, i + 1, res, sb, rmL - 1, rmR, open);\t\t    // not use (\n        \tdfs(s, i + 1, res, sb.append(c), rmL, rmR, open + 1);       // use (\n\n        } else if (c == ')') {\n            dfs(s, i + 1, res, sb, rmL, rmR - 1, open);\t            // not use  )\n        \tdfs(s, i + 1, res, sb.append(c), rmL, rmR, open - 1);  \t    // use )\n\n        } else {\n            dfs(s, i + 1, res, sb.append(c), rmL, rmR, open);\n        }\n\n        sb.setLength(len);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/remove-invalid-parentheses/discuss/75095/Java-optimized-DFS-solution-3-ms\n     */\n    public List<String> removeInvalidParentheses5(String s) {\n         int count = 0, openN = 0, closeN = 0;\n\n         // calculate the total numbers of opening and closing parentheses\n         // that need to be removed in the final solution\n         for (char c : s.toCharArray()) {\n             if (c == '(') {\n                 count++;\n             } else if (c == ')') {\n                 if (count == 0) closeN++;\n                 else count--;\n             }\n         }\n         openN = count;\n         count = 0;\n\n         if (openN == 0 && closeN == 0) return Arrays.asList(s);\n\n         List<String> result = new ArrayList<>();\n         StringBuilder sb = new StringBuilder();\n\n         dfs(s.toCharArray(), 0, count, openN, closeN, result, sb);\n\n         return result;\n     }\n\n     private void dfs(char[] s, int p, int count, int openN, int closeN, List<String> result, StringBuilder sb) {\n         if (count < 0) return; // the parentheses is invalid\n\n         if (p == s.length) {\n             if (openN == 0 && closeN == 0) { // the minimum number of invalid parentheses have been removed\n                 result.add(sb.toString());\n             }\n             return;\n         }\n\n         if (s[p] != '(' && s[p] != ')') {\n             sb.append(s[p]);\n             dfs(s, p + 1, count, openN, closeN, result, sb);\n             sb.deleteCharAt(sb.length() - 1);\n         } else if (s[p] == '(') {\n             int i = 1;\n             while (p + i < s.length && s[p + i] == '(') i++; // use while loop to avoid duplicate result in DFS, instead of using HashSet\n             sb.append(s, p, i);\n             dfs(s, p + i, count + i, openN, closeN, result, sb);\n             sb.delete(sb.length() - i, sb.length());\n\n             if (openN > 0) {\n                 // remove the current opening parenthesis\n                 dfs(s, p + 1, count, openN - 1, closeN, result, sb);\n             }\n         } else {\n             int i = 1;\n             while (p + i < s.length && s[p + i] == ')') i++; // use while loop to avoid duplicate result in DFS, instead of using HashSet\n             sb.append(s, p, i);\n             dfs(s, p + i, count - i, openN, closeN, result, sb);\n             sb.delete(sb.length() - i, sb.length());\n\n             if (closeN > 0) {\n                 // remove the current closing parenthesis\n                 dfs(s, p + 1, count, openN, closeN - 1, result, sb);\n             }\n         }\n     }\n\n\n}\n"
  },
  {
    "path": "src/RemoveLinkedListElements203.java",
    "content": "/**\n * Remove all elements from a linked list of integers that have value val.\n * \n * Example:\n * Input:  1->2->6->3->4->5->6, val = 6\n * Output: 1->2->3->4->5\n */\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\npublic class RemoveLinkedListElements203 {\n    public ListNode removeElements(ListNode head, int val) {\n        ListNode dummy = new ListNode(0);\n        dummy.next = head;\n        ListNode p = dummy;\n        while (p.next != null) {\n            if (p.next.val == val) {\n                p.next = p.next.next;\n            } else {\n                p = p.next;\n            }\n        }\n        return dummy.next;\n    }\n\n    public ListNode removeElements2(ListNode head, int val) {\n        if (head == null) return null;\n        head.next = removeElements2(head.next, val);\n        return head.val == val ? head.next : head;\n    }\n\n}\n"
  },
  {
    "path": "src/RemoveNthNodeFromEndOfList19.java",
    "content": "/**\n * Given a linked list, remove the nth node from the end of list and return its head.\n *\n * For example,\n *\n *    Given linked list: 1->2->3->4->5, and n = 2.\n *\n *    After removing the second node from the end, the linked list becomes 1->2->3->5.\n * Note:\n * Given n will always be valid.\n * Try to do this in one pass.\n *\n */\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\n\npublic class RemoveNthNodeFromEndOfList19 {\n    public ListNode removeNthFromEnd(ListNode head, int n) {\n        if (head == null) return null;\n\n        int k = 1;\n        ListNode q = head;\n        while (q.next != null) {\n            k++;\n            q = q.next;\n        }\n        if (n == k) return head.next;\n\n        ListNode dummy = new ListNode(0);\n        ListNode p = head;\n        dummy.next = p;\n\n        int i = 1;\n        while (i < k-n) {\n            p = p.next;\n            i++;\n        }\n\n        p.next = p.next.next;\n\n        return dummy.next;\n    }\n\n\n    public ListNode removeNthFromEnd2(ListNode head, int n) {\n        if (head == null) return null;\n\n        ListNode dummy = new ListNode(0);\n        dummy.next = head;\n        ListNode f = dummy;\n        ListNode s = dummy;\n        int i = 0;\n        while (i < n) {\n            f = f.next;\n            i++;\n        }\n\n        while (f.next != null) {\n            f = f.next;\n            s = s.next;\n        }\n\n        s.next = s.next.next;\n\n        return dummy.next;\n    }\n\n\n    public ListNode removeNthFromEnd3(ListNode head, int n) {\n        int l = 0;\n        ListNode p = head;\n        while (p != null) {\n            p = p.next;\n            l++;\n        }\n\n        if (l < n) return head;\n        if (l == n) {\n            head = head.next;\n            return head;\n        }\n\n        int k = l-n;\n        int i = 1;\n        p = head;\n        while (i < k) {\n            p = p.next;\n            i++;\n        }\n        p.next = p.next.next;\n\n        return head;\n    }\n\n    public ListNode removeNthFromEnd4(ListNode head, int n) {\n        if (head == null) return null;\n        int m = 1;\n        ListNode f = head;\n        ListNode s = head;\n        while (f.next != null && f.next.next != null) {\n            s = s.next;\n            f = f.next.next;\n            m++;\n        }\n\n        int len = f.next == null ? (m*2-1) : m*2;\n        if (len < n) return head;\n        if (len == n) {\n            head = head.next;\n            return head;\n        }\n\n        int k = len-n;\n        if (m <= k) {\n            while (m < k) {\n                s = s.next;\n                m++;\n            }\n            s.next = s.next.next;\n        } else {\n            int i=1;\n            f = head;\n            while (i < k) {\n                f = f.next;\n                i++;\n            }\n            f.next = f.next.next;\n        }\n\n        return head;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/remove-nth-node-from-end-of-list/solution/\n     */\n    public ListNode removeNthFromEnd5(ListNode head, int n) {\n        ListNode dummy = new ListNode(0);\n        dummy.next = head;\n        int length  = 0;\n        ListNode first = head;\n        while (first != null) {\n            length++;\n            first = first.next;\n        }\n        length -= n;\n        first = dummy;\n        while (length > 0) {\n            length--;\n            first = first.next;\n        }\n        first.next = first.next.next;\n        return dummy.next;\n    }\n\n\n    public ListNode removeNthFromEnd6(ListNode head, int n) {\n        ListNode dummy = new ListNode(0);\n        dummy.next = head;\n        ListNode first = dummy;\n        ListNode second = dummy;\n        // Advances first pointer so that the gap between first and second is n nodes apart\n        for (int i = 1; i <= n + 1; i++) {\n            first = first.next;\n        }\n        // Move first to the end, maintaining the gap\n        while (first != null) {\n            first = first.next;\n            second = second.next;\n        }\n        second.next = second.next.next;\n        return dummy.next;\n    }\n\n}\n"
  },
  {
    "path": "src/ReorderList143.java",
    "content": "/**\n * Given a singly linked list L: L0?L1?…?Ln-1?Ln,\n * reorder it to: L0?Ln?L1?Ln-1?L2?Ln-2?…\n *\n * You must do this in-place without altering the nodes' values.\n *\n * For example,\n *      Given {1,2,3,4}, reorder it to {1,4,2,3}.\n */\n\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\npublic class ReorderList143 {\n    public void reorderList(ListNode head) {\n        if (head == null || head.next == null || head.next.next == null) return;\n        ListNode fast = head;\n        ListNode slow = head;\n\n        Stack<ListNode> st = new Stack<>();\n\n        while (fast.next != null && fast.next.next != null) {\n            st.push(slow);\n            slow = slow.next;\n            fast = fast.next.next;\n        }\n\n        ListNode dummy = new ListNode(0);\n        ListNode half = new ListNode(0);\n        if (fast.next == null) {\n            half = slow.next;\n            dummy.next = slow;\n            dummy.next.next = null;\n        } else if (fast.next.next == null) {\n            half = slow.next.next;\n            dummy.next = slow;\n            dummy.next.next.next = null;\n        }\n\n        while (half != null) {\n            ListNode newNode = half;\n            half = half.next;\n            newNode.next = dummy.next;\n            dummy.next = newNode;\n            newNode = st.pop();\n            newNode.next = dummy.next;\n            dummy.next = newNode;\n        }\n\n        head = dummy.next;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/13869/java-solution-with-3-steps\n     */\n    public void reorderList2(ListNode head) {\n        if(head==null||head.next==null) return;\n\n        //Find the middle of the list\n        ListNode p1=head;\n        ListNode p2=head;\n        while(p2.next!=null&&p2.next.next!=null){\n            p1=p1.next;\n            p2=p2.next.next;\n        }\n\n        //Reverse the half after middle  1->2->3->4->5->6 to 1->2->3->6->5->4\n        ListNode preMiddle=p1;\n        ListNode preCurrent=p1.next;\n        while(preCurrent.next!=null){\n            ListNode current=preCurrent.next;\n            preCurrent.next=current.next;\n            current.next=preMiddle.next;\n            preMiddle.next=current;\n        }\n\n        //Start reorder one by one  1->2->3->6->5->4 to 1->6->2->5->3->4\n        p1=head;\n        p2=preMiddle.next;\n        while(p1!=preMiddle){\n            preMiddle.next=p2.next;\n            p2.next=p1.next;\n            p1.next=p2;\n            p1=p2.next;\n            p2=preMiddle.next;\n        }\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/18092/java-solution-with-3-steps\n     */\n    public void reorderList3(ListNode head) {\n       if (head == null || head.next == null)\n           return;\n\n       // step 1. cut the list to two halves\n       // prev will be the tail of 1st half\n       // slow will be the head of 2nd half\n       ListNode prev = null, slow = head, fast = head, l1 = head;\n\n       while (fast != null && fast.next != null) {\n         prev = slow;\n         slow = slow.next;\n         fast = fast.next.next;\n       }\n\n       prev.next = null;\n\n       // step 2. reverse the 2nd half\n       ListNode l2 = reverse(slow);\n\n       // step 3. merge the two halves\n       merge(l1, l2);\n     }\n\n     ListNode reverse(ListNode head) {\n       ListNode prev = null, curr = head, next = null;\n\n       while (curr != null) {\n         next = curr.next;\n         curr.next = prev;\n         prev = curr;\n         curr = next;\n       }\n\n       return prev;\n     }\n\n     void merge(ListNode l1, ListNode l2) {\n       while (l1 != null) {\n         ListNode n1 = l1.next, n2 = l2.next;\n         l1.next = l2;\n\n         if (n1 == null)\n           break;\n\n         l2.next = n1;\n         l1 = n1;\n         l2 = n2;\n       }\n     }\n\n}\n"
  },
  {
    "path": "src/ReorganizeString767.java",
    "content": "/**\n * Given a string S, check if the letters can be rearranged so that two\n * characters that are adjacent to each other are not the same.\n * \n * If possible, output any possible result.  If not possible, return the\n * empty string.\n * \n * Example 1:\n * Input: S = \"aab\"\n * Output: \"aba\"\n * \n * Example 2:\n * Input: S = \"aaab\"\n * Output: \"\"\n * \n * Note:\n * S will consist of lowercase letters and have length in range [1, 500].\n */\n\npublic class ReorganizeString767 {\n    public String reorganizeString(String S) {\n        int[] hash = new int[26];\n        for(char c : S.toCharArray()) hash[c-'a']++;\n        int max = 0;\n        for(int i = 0; i<26; ++i){\n            if(hash[i] > hash[max]) max = i;\n        }\n        if(hash[max] > (S.length()+1)/2) return \"\";\n        char[] res = new char[S.length()];\n        int ptr = 0; \n        while(hash[max]-- > 0){\n            res[ptr] = (char)(max + 'a');\n            ptr += 2;\n        }\n\n        for(int i = 0; i<26; ++i){\n            while(hash[i]-- > 0){\n                if(ptr >= S.length()) ptr = 1;\n                res[ptr] = (char)(i + 'a');\n                ptr += 2;\n            }\n        }\n\n        return new String(res);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/reorganize-string/solution/\n     */\n    public String reorganizeString2(String S) {\n        int N = S.length();\n        int[] count = new int[26];\n        for (char c: S.toCharArray()) count[c-'a']++;\n        PriorityQueue<MultiChar> pq = new PriorityQueue<MultiChar>((a, b) ->\n            a.count == b.count ? a.letter - b.letter : b.count - a.count);\n\n        for (int i = 0; i < 26; ++i) if (count[i] > 0) {\n            if (count[i] > (N + 1) / 2) return \"\";\n            pq.add(new MultiChar(count[i], (char) ('a' + i)));\n        }\n\n        StringBuilder ans = new StringBuilder();\n        while (pq.size() >= 2) {\n            MultiChar mc1 = pq.poll();\n            MultiChar mc2 = pq.poll();\n            /*This code turns out to be superfluous, but explains what is happening\n            if (ans.length() == 0 || mc1.letter != ans.charAt(ans.length() - 1)) {\n                ans.append(mc1.letter);\n                ans.append(mc2.letter);\n            } else {\n                ans.append(mc2.letter);\n                ans.append(mc1.letter);\n            }*/\n            ans.append(mc1.letter);\n            ans.append(mc2.letter);\n            if (--mc1.count > 0) pq.add(mc1);\n            if (--mc2.count > 0) pq.add(mc2);\n        }\n\n        if (pq.size() > 0) ans.append(pq.poll().letter);\n        return ans.toString();\n    }\n\n    class MultiChar {\n        int count;\n        char letter;\n        MultiChar(int ct, char ch) {\n            count = ct;\n            letter = ch;\n        }\n    }\n\n    // use 358. Rearrange String k Distance Apart\n    public String reorganizeString3(String S) {\n        return rearrangeString(S, 2);\n    }\n\n    public String rearrangeString(String str, int k) {\n        int length = str.length();\n        int[] count = new int[26];\n        int[] nextIndex = new int[26];\n        char[] chars = str.toCharArray();\n        for (char ch: chars){\n            count[ch-'a']++;\n        }\n        StringBuilder sb = new StringBuilder();\n        for (int i=0; i<length; i++) {\n            int idx = findValidMax(count, nextIndex, i);\n            if (idx == -1) return \"\";\n            sb.append((char) (idx + 'a'));\n            count[idx]--;\n            nextIndex[idx] = i+k;\n        }\n        return sb.toString();\n    }\n\n    private int findValidMax(int[] count, int[] nextIndex, int index){\n        int max = Integer.MIN_VALUE;\n        int idx = -1;\n        for (int i=0; i<26; i++) {\n            if (count[i] != 0 && count[i] > max && index >= nextIndex[i]) {\n                max = count[i];\n                idx = i;\n            }\n        }\n        return idx;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/reorganize-string/discuss/113451/7-ms-Java-O(n)-Solution.-no-Sorting\n     */\n    public String reorganizeString4(String S) {\n        int n = S.length();\n        int[] cnt = new int[128];\n        char mc = 'a';\n        for (char c : S.toCharArray()) {\n            cnt[c]++;\n            mc = (cnt[c] > cnt[mc]) ? c : mc;\n        }\n        if (cnt[mc] == 1) {\n            return S;\n        }\n        if (n - cnt[mc] <= cnt[mc] - 2) {\n            return \"\";\n        }\n        StringBuilder[] sb = new StringBuilder[cnt[mc]];\n        for (int i = 0; i < sb.length; i ++) {\n            sb[i] = new StringBuilder();\n            sb[i].append(mc);\n        }\n        int k = 0;\n        for (char c = 'a'; c <= 'z'; c++) {\n            while (c != mc && cnt[c] > 0) {\n                sb[k++].append(c);\n                cnt[c]--;\n                k %= sb.length;\n            }\n        }\n        for (int i = 1; i < sb.length; i++) {\n            sb[0].append(sb[i]);\n        }\n        return sb[0].toString();\n    }\n\n}\n"
  },
  {
    "path": "src/RepeatedDNASequences187.java",
    "content": "/**\n * All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T,\n * for example: \"ACGAATTCCG\". When studying DNA, it is sometimes useful to\n * identify repeated sequences within the DNA.\n * \n * Write a function to find all the 10-letter-long sequences (substrings) that\n * occur more than once in a DNA molecule.\n * \n * Example:\n * Input: s = \"AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT\"\n * Output: [\"AAAAACCCCC\", \"CCCCCAAAAA\"]\n */\n\npublic class RepeatedDNASequences187 {\n    public List<String> findRepeatedDnaSequences(String s) {\n        List<String> res = new ArrayList<>();\n        Map<String, Boolean> map = new HashMap<>();\n        int N = s.length();\n        for (int i=0; i<=N-10; i++) {\n            String sub = s.substring(i, i+10);\n            if (map.containsKey(sub)) {\n                if (!map.get(sub)) {\n                    map.put(sub, true);\n                    res.add(sub);\n                }\n            } else {\n                map.put(sub, false);\n            }\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/RepeatedStringMatch686.java",
    "content": "/**\n * Given two strings A and B, find the minimum number of times A has to be\n * repeated such that B is a substring of it. If no such solution, return -1.\n * \n * For example, with A = \"abcd\" and B = \"cdabcdab\".\n * \n * Return 3, because by repeating A three times (“abcdabcdabcd”), B is a\n * substring of it; and B is not a substring of A repeated two times (\"abcdabcd\").\n * \n * Note:\n * The length of A and B will be between 1 and 10000.\n */\n\npublic class RepeatedStringMatch686 {\n    public int repeatedStringMatch(String A, String B) {\n        int lenA = A.length();\n        int lenB = B.length();\n        for (int i=0; i<lenA; i++) {\n            if (A.charAt(i) == B.charAt(0)) {\n                int bi = 0;\n                int ai = i;\n                int nr = 1;\n                boolean found = true;\n                while (bi < lenB) {\n                    char bc = B.charAt(bi);\n                    char ac = A.charAt(ai);\n                    if (ac != bc) {\n                        found = false;\n                        break;\n                    }\n                    bi++;\n                    if (bi == lenB) break;\n                    if (ai == lenA - 1) {\n                        ai = 0;\n                        nr++;\n                    } else {\n                        ai++;\n                    }\n                }\n                if (found) return nr;\n            }\n        }\n        return -1;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/repeated-string-match/solution/\n     */\n    public int repeatedStringMatch2(String A, String B) {\n        int q = 1;\n        StringBuilder S = new StringBuilder(A);\n        for (; S.length() < B.length(); q++) S.append(A);\n        if (S.indexOf(B) >= 0) return q;\n        if (S.append(A).indexOf(B) >= 0) return q+1;\n        return -1;\n    }\n\n\n}\n"
  },
  {
    "path": "src/RepeatedSubstringPattern459.java",
    "content": "/**\n * Given a non-empty string check if it can be constructed by taking a\n * substring of it and appending multiple copies of the substring together.\n * You may assume the given string consists of lowercase English letters only\n * and its length will not exceed 10000.\n * \n * Example 1:\n * Input: \"abab\"\n * Output: True\n * Explanation: It's the substring \"ab\" twice.\n * \n * Example 2:\n * Input: \"aba\"\n * Output: False\n * \n * Example 3:\n * Input: \"abcabcabcabc\"\n * Output: True\n * Explanation: It's the substring \"abc\" four times. (And the substring \"abcabc\" twice.)\n */\n\npublic class RepeatedSubstringPattern459 {\n\n    /**\n     * https://leetcode.com/problems/repeated-substring-pattern/discuss/94352/Java-Simple-Solution-with-Explanation\n     */\n    public boolean repeatedSubstringPattern(String s) {\n        if(s==null || s.length()<=1) return false;\n        \n        for(int i=1;i<=s.length()/2;i++){   \n            if(s.length()%i!=0) continue;      \n            String sub = s.substring(0,i);\n            if(dfs(s,sub,i)) return true;\n        }\n        return false;\n    }\n\n    private boolean dfs(String s,String sub,int i){\n        if(i==s.length()) return true;\n        if(!s.startsWith(sub,i)) return false;\n        return dfs(s,sub,i+sub.length());\n    }\n\n\n    /**\n     * https://leetcode.com/problems/repeated-substring-pattern/discuss/94344/Simple-Java-solution-2-lines\n     */\n    public boolean repeatedSubstringPattern2(String str) {\n        String s = str + str;\n        return s.substring(1, s.length() - 1).contains(str);\n    }\n\n\n\n    /**\n     * https://leetcode.com/problems/repeated-substring-pattern/discuss/94340/Java-and-O(n)\n     */\n    public boolean repeatedSubstringPattern3(String str) {\n        //This is the kmp issue\n        int[] prefix = kmp(str);\n        int len = prefix[str.length()-1];\n        int n = str.length();\n        return (len > 0 && n%(n-len) == 0);\n    }\n\n    private int[] kmp(String s){\n        int len = s.length();\n        int[] res = new int[len];\n        char[] ch = s.toCharArray();\n        int i = 0, j = 1;\n        res[0] = 0;\n        while(i < ch.length && j < ch.length){\n            if(ch[j] == ch[i]){\n                res[j] = i+1;\n                i++;\n                j++;\n            }else{\n                if(i == 0){\n                    res[j] = 0;\n                    j++;\n                }else{\n                    i = res[i-1];\n                }\n            }\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/ReplaceWords648.java",
    "content": "/**\n * In English, we have a concept called root, which can be followed by some\n * other words to form another longer word - let's call this word successor.\n * For example, the root an, followed by other, which can form another word\n * another.\n * \n * Now, given a dictionary consisting of many roots and a sentence. You need\n * to replace all the successor in the sentence with the root forming it. If\n * a successor has many roots can form it, replace it with the root with the\n * shortest length.\n * \n * You need to output the sentence after the replacement.\n * \n * Example 1:\n * Input: dict = [\"cat\", \"bat\", \"rat\"]\n * sentence = \"the cattle was rattled by the battery\"\n * Output: \"the cat was rat by the bat\"\n * \n * Note:\n * The input will only have lower-case letters.\n * 1 <= dict words number <= 1000\n * 1 <= sentence words number <= 1000\n * 1 <= root length <= 100\n * 1 <= sentence words length <= 1000\n */\n\npublic class ReplaceWords648 {\n    public String replaceWords(List<String> dict, String sentence) {\n        String[] words = sentence.split(\"\\\\s+\");\n        StringBuilder sb = new StringBuilder();\n        for (int i=0; i<words.length; i++) {\n            for (String d: dict) {\n                if (words[i].startsWith(d)) {\n                    words[i] = d;\n                }\n            }\n        }\n        return String.join(\" \", words);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/replace-words/solution/\n     */\n    public String replaceWords2(List<String> roots, String sentence) {\n        Set<String> rootset = new HashSet();\n        for (String root: roots) rootset.add(root);\n\n        StringBuilder ans = new StringBuilder();\n        for (String word: sentence.split(\"\\\\s+\")) {\n            String prefix = \"\";\n            for (int i = 1; i <= word.length(); ++i) {\n                prefix = word.substring(0, i);\n                if (rootset.contains(prefix)) break;\n            }\n            if (ans.length() > 0) ans.append(\" \");\n            ans.append(prefix);\n        }\n        return ans.toString();\n    }\n\n\n    public String replaceWords3(List<String> roots, String sentence) {\n        Trie trie = constructTrie(roots);\n        String[] words = sentence.split(\"\\\\s+\");\n        for (int i=0; i<words.length; i++) {\n            String found = trie.search(words[i]);\n            // System.out.println(found);\n            words[i] = found;\n        }\n        return String.join(\" \", words);\n    }\n\n    private Trie constructTrie(List<String> roots) {\n        Trie root = new Trie();\n        for (String word: roots) {\n            root.add(word);\n        }\n        return root;\n    }\n\n    class Trie {\n        Trie[] children = new Trie[26];\n        String word;\n\n        public void add(String word) {\n            add(word.toCharArray(), 0);\n        }\n\n        private void add(char[] chars, int i) {\n            if (i >= chars.length) {\n                this.word = new String(chars);\n                return;\n            }\n            if (children[chars[i]-'a'] == null) {\n                children[chars[i]-'a'] = new Trie();\n            }\n            children[chars[i]-'a'].add(chars, i+1);\n        }\n\n        public String search(String word) {\n            String found = search(word.toCharArray(), 0);\n            if (found == null) return word;\n            return found;\n        }\n\n        private String search(char[] chars, int i) {\n            if (i >= chars.length) {\n                return word;\n            }\n            if (word != null) return word;\n            if (children[chars[i]-'a'] == null) return word;\n            return children[chars[i]-'a'].search(chars, i+1);\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/RestoreIPAddresses93.java",
    "content": "/**\n * Given a string containing only digits, restore it by returning all possible\n * valid IP address combinations.\n *\n * For example:\n * Given \"25525511135\",\n *\n * return [\"255.255.11.135\", \"255.255.111.35\"]. (Order does not matter)\n */\n\n\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Stack;\n\n\npublic class RestoreIPAddresses93 {\n    public List<String> restoreIpAddresses(String s) {\n        List<String> results = new ArrayList<>();\n        int L = s.length();\n        if (L < 4) return results;\n\n        Stack<String> st = new Stack<>();\n\n        helper(s, results, st, 0, L);\n\n        return results;\n    }\n\n\n    private void helper(String s, List<String> results, Stack<String> st, int start, int L) {\n        if (st.size() == 3 && (start + 3) < L) return;\n\n        if (st.size() == 4) {\n            if (start == L) results.add(String.join(\".\", st));\n            return;\n        }\n\n        for (int i = 1; i<=3 && start+i<=L; i++) {\n            String current = s.substring(start, start+i);\n            if (!isValid(current)) continue;\n\n            st.push(current);\n            helper(s, results, st, start+i, L);\n            st.pop();\n        }\n    }\n\n    private boolean isValid(String current) {\n        // starts with \"0\" but not \"0\"\n        if (current.charAt(0)=='0' && current.length() > 1) return false;\n        // larger than 255\n        if (Integer.valueOf(current) > 255) return false;\n        return true;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/3919/my-code-in-java\n     */\n    public List<String> restoreIpAddresses2(String s) {\n        List<String> res = new ArrayList<String>();\n        int len = s.length();\n        for(int i = 1; i<4 && i<len-2; i++){\n            for(int j = i+1; j<i+4 && j<len-1; j++){\n                for(int k = j+1; k<j+4 && k<len; k++){\n                    String s1 = s.substring(0,i), s2 = s.substring(i,j), s3 = s.substring(j,k), s4 = s.substring(k,len);\n                    if(isValid2(s1) && isValid2(s2) && isValid2(s3) && isValid2(s4)){\n                        res.add(s1+\".\"+s2+\".\"+s3+\".\"+s4);\n                    }\n                }\n            }\n        }\n        return res;\n    }\n    public boolean isValid2(String s){\n        if(s.length()>3 || s.length()==0 || (s.charAt(0)=='0' && s.length()>1) || Integer.parseInt(s)>255)\n            return false;\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "src/ReverseLinkedList206.java",
    "content": "/**\n * Reverse a singly linked list.\n *\n * Hint:\n * A linked list can be reversed either iteratively or recursively.\n * Could you implement both?\n *\n */\n\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\npublic class ReverseLinkedList206 {\n    public ListNode reverseList(ListNode head) {\n        if (head == null || head.next == null) return head;\n\n        ListNode dummy = new ListNode(0);\n        ListNode tail = null;\n\n        while (head != null) {\n            ListNode t = head;\n            head = head.next;\n            tail = dummy.next;\n            dummy.next = t;\n            dummy.next.next = tail;\n        }\n\n        return dummy.next;\n    }\n\n\n    public ListNode reverseList2(ListNode head) {\n        if (head == null || head.next == null) return head;\n        ListNode dummy = new ListNode(0);\n        helper(head, dummy);\n        return dummy.next;\n    }\n\n    private void helper(ListNode head, ListNode dummy) {\n        if (head == null) return;\n        ListNode curr = head;\n        head = head.next;\n        ListNode tail = dummy.next;\n        dummy.next = curr;\n        dummy.next.next = tail;\n        helper(head, dummy);\n    }\n\n\n    public ListNode reverseList3(ListNode head) {\n        return helper2(head, null);\n    }\n\n    private ListNode helper2(ListNode head, ListNode h) {\n        if (head == null) return h;\n        ListNode tail = head.next;\n        head.next = h;\n        return helper2(tail, head);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/reverse-linked-list/solution/\n     */\n    public ListNode reverseList4(ListNode head) {\n        ListNode prev = null;\n        ListNode curr = head;\n        while (curr != null) {\n            ListNode nextTemp = curr.next;\n            curr.next = prev;\n            prev = curr;\n            curr = nextTemp;\n        }\n        return prev;\n    }\n\n\n    public ListNode reverseList5(ListNode head) {\n        if (head == null || head.next == null) return head;\n        ListNode p = reverseList(head.next);\n        head.next.next = head;\n        head.next = null;\n        return p;\n    }\n\n\n}\n"
  },
  {
    "path": "src/ReverseLinkedListII92.java",
    "content": "/**\n * Reverse a linked list from position m to n. Do it in-place and in one-pass.\n *\n * For example:\n * Given 1->2->3->4->5->NULL, m = 2 and n = 4,\n *\n * return 1->4->3->2->5->NULL.\n *\n * Note:\n * Given m, n satisfy the following condition:\n * 1 ? m ? n ? length of list.\n */\n\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\n\npublic class ReverseLinkedListII92 {\n    public ListNode reverseBetween(ListNode head, int m, int n) {\n        if (head == null || head.next == null || m == n) return head;\n        ListNode dummy = new ListNode(0);\n        dummy.next = head;\n        ListNode p = dummy;\n        int i = 0;\n        while (i < m-1) {\n            p = p.next;\n            i++;\n        }\n\n        ListNode before = p;\n        p = p.next;\n        i++;\n\n        ListNode start = new ListNode(0);\n        start.next = p;\n\n        while (i < n) {\n            ListNode r = p.next;\n            p.next = p.next.next;\n            r.next = start.next;\n            start.next = r;\n            i++;\n        }\n\n        before.next = start.next;\n\n        return dummy.next;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/8976/simple-java-solution-with-clear-explanation\n     */\n    public ListNode reverseBetween2(ListNode head, int m, int n) {\n        if(head == null) return null;\n        ListNode dummy = new ListNode(0); // create a dummy node to mark the head of this list\n        dummy.next = head;\n        ListNode pre = dummy; // make a pointer pre as a marker for the node before reversing\n        for(int i = 0; i<m-1; i++) pre = pre.next;\n\n        ListNode start = pre.next; // a pointer to the beginning of a sub-list that will be reversed\n        ListNode then = start.next; // a pointer to a node that will be reversed\n\n        // 1 - 2 -3 - 4 - 5 ; m=2; n =4 ---> pre = 1, start = 2, then = 3\n        // dummy-> 1 -> 2 -> 3 -> 4 -> 5\n\n        for(int i=0; i<n-m; i++) {\n            start.next = then.next;\n            then.next = pre.next;\n            pre.next = then;\n            then = start.next;\n        }\n\n        // first reversing : dummy->1 - 3 - 2 - 4 - 5; pre = 1, start = 2, then = 4\n        // second reversing: dummy->1 - 4 - 3 - 2 - 5; pre = 1, start = 2, then = 5 (finish)\n\n        return dummy.next;\n    }\n\n\n    public ListNode reverseBetween3(ListNode head, int m, int n) {\n        int i = 1;\n        ListNode dummy = new ListNode(0);\n        ListNode p = dummy;\n        ListNode h = head;\n        while (i < m) {\n            p.next = h;\n            h = h.next;\n            p = p.next;\n            p.next = null;\n            i++;\n        }\n\n        ListNode tail = h;\n        while (i <= n) {\n            ListNode in = h;\n            h = h.next;\n            in.next = p.next;\n            p.next = in;\n            i++;\n        }\n        \n        while (h != null) {\n            tail.next = h;\n            h = h.next;\n            tail = tail.next;\n            tail.next = null;\n        }\n        return dummy.next;\n    }\n\n\n}\n"
  },
  {
    "path": "src/ReverseNodesInKGroup25.java",
    "content": "/**\n * Given a linked list, reverse the nodes of a linked list k at a time and\n * return its modified list.\n *\n * k is a positive integer and is less than or equal to the length of the linked\n * list. If the number of nodes is not a multiple of k then left-out nodes in\n * the end should remain as it is.\n *\n * You may not alter the values in the nodes, only nodes itself may be changed.\n *\n * Only constant memory is allowed.\n *\n * For example,\n * Given this linked list: 1->2->3->4->5\n *\n * For k = 2, you should return: 2->1->4->3->5\n *\n * For k = 3, you should return: 3->2->1->4->5\n */\n\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\n\npublic class ReverseNodesInKGroup25 {\n    public ListNode reverseKGroup(ListNode head, int k) {\n\n        if (k == 0 || k == 1) {\n            return head;\n        }\n\n        if (head == null) {\n            return null;\n        }\n\n        ListNode now = head;\n        int i = 1;\n        ListNode r = new ListNode(0);\n        ListNode last = r;\n        ListNode tempHead = null;\n        ListNode tempTail = null;\n        while (now != null) {\n            ListNode temp = new ListNode(now.val);\n            if (i == 1) {\n                tempHead = temp;\n                tempHead.next = null;\n                tempTail = temp;\n                tempTail.next = null;\n                i++;\n            } else if (i == k) {\n                temp.next = tempHead;\n                tempHead = temp;\n                last.next = tempHead;\n                last = tempTail;\n                tempHead = null;\n                tempTail = null;\n                i = 1;\n            } else {\n                temp.next = tempHead;\n                tempHead = temp;\n                i++;\n            }\n            now = now.next;\n        }\n\n        ListNode tailHead = null;\n        while (tempHead != null) {\n            ListNode temp = new ListNode(tempHead.val);\n            temp.next = tailHead;\n            tailHead = temp;\n            last.next = tailHead;\n            tempHead = tempHead.next;\n        }\n\n        return r.next;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/7126/short-but-recursive-java-code-with-comments/27\n     */\n    public ListNode reverseKGroup2(ListNode head, int k) {\n        ListNode curr = head;\n        int count = 0;\n        while (curr != null && count != k) { // find the k+1 node\n            curr = curr.next;\n            count++;\n        }\n        if (count == k) { // if k+1 node is found\n            curr = reverseKGroup(curr, k); // reverse list with k+1 node as head\n            // head - head-pointer to direct part,\n            // curr - head-pointer to reversed part;\n            while (count-- > 0) { // reverse current k-group:\n                ListNode tmp = head.next; // tmp - next head in direct part\n                head.next = curr; // preappending \"direct\" head to the reversed list\n                curr = head; // move head of reversed part to a new node\n                head = tmp; // move \"direct\" head to the next node in direct part\n            }\n            head = curr;\n        }\n        return head;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/7126/short-but-recursive-java-code-with-comments/27\n     */\n    public ListNode reverseKGroup3(ListNode head, int k) {\n        int n = 0;\n        for (ListNode i = head; i != null; n++, i = i.next);\n\n        ListNode dmy = new ListNode(0);\n        dmy.next = head;\n        for(ListNode prev = dmy, tail = head; n >= k; n -= k) {\n            for (int i = 1; i < k; i++) {\n                ListNode next = tail.next.next;\n                tail.next.next = prev.next;\n                prev.next = tail.next;\n                tail.next = next;\n            }\n\n            prev = tail;\n            tail = tail.next;\n        }\n        return dmy.next;\n    }\n\n    /**\n     * https://leetcode.com/problems/reverse-nodes-in-k-group/#/solutions\n     */\n    public ListNode reverseKGroup4(ListNode head, int k) {\n        ListNode begin;\n        if (head==null || head.next ==null || k==1) return head;\n        ListNode dummyhead = new ListNode(-1);\n        dummyhead.next = head;\n        begin = dummyhead;\n        int i=0;\n        while (head != null){\n          \ti++;\n          \tif (i%k == 0){\n            \t\tbegin = reverse(begin, head.next);\n            \t\thead = begin.next;\n          \t} else {\n          \t\t  head = head.next;\n          \t}\n        }\n        return dummyhead.next;\n\n    }\n\n    public ListNode reverse(ListNode begin, ListNode end){\n      \tListNode curr = begin.next;\n      \tListNode next, first;\n      \tListNode prev = begin;\n      \tfirst = curr;\n      \twhile (curr!=end){\n        \t\tnext = curr.next;\n        \t\tcurr.next = prev;\n        \t\tprev = curr;\n        \t\tcurr = next;\n      \t}\n      \tbegin.next = prev;\n      \tfirst.next = curr;\n      \treturn first;\n    }\n\n\n}\n"
  },
  {
    "path": "src/ReverseString344.java",
    "content": "/**\n * Write a function that takes a string as input and returns the string reversed.\n *\n * Example:\n * Given s = \"hello\", return \"olleh\".\n */\n\npublic class ReverseString344 {\n    public String reverseString(String s) {\n        if (s == null || s.length() <= 1) return s;\n        char[] chars = s.toCharArray();\n        int i = 0;\n        int j = s.length()-1;\n        while (i < j) swap(chars, i++, j--);\n        return String.valueOf(chars);\n    }\n\n    private void swap(char[] chars, int i, int j) {\n        char t = chars[i];\n        chars[i] = chars[j];\n        chars[j] = t;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/reverse-string/discuss/80937/JAVA-Simple-and-Clean-with-Explanations-6-Solutions\n     */\n    public String reverseString2(String s) {\n        char[] word = s.toCharArray();\n        int i = 0;\n        int j = s.length() - 1;\n        while (i < j) {\n            word[i] = (char) (word[i] ^ word[j]);\n            word[j] = (char) (word[i] ^ word[j]);\n            word[i] = (char) (word[i] ^ word[j]);\n            i++;\n            j--;\n        }\n        return new String(word);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/reverse-string/discuss/80937/JAVA-Simple-and-Clean-with-Explanations-6-Solutions\n     */\n    public String reverseString3(String s) {\n        return new StringBuilder(s).reverse().toString();\n    }\n\n}\n"
  },
  {
    "path": "src/ReverseStringII541.java",
    "content": "/**\n * Given a string and an integer k, you need to reverse the first k characters\n * for every 2k characters counting from the start of the string. If there are\n * less than k characters left, reverse all of them. If there are less than 2k\n * but greater than or equal to k characters, then reverse the first k\n * characters and left the other as original.\n * \n * Example:\n * Input: s = \"abcdefg\", k = 2\n * Output: \"bacdfeg\"\n * \n * Restrictions:\n * The string consists of lower English letters only.\n * Length of the given string and k will in the range [1, 10000]\n * \n */\n\npublic class ReverseStringII541 {\n    public String reverseStr(String s, int k) {\n        if (s == null || s.length() == 0) return s;\n        char[] chars = s.toCharArray();\n        \n        for (int i=0; i<=s.length()/k; i++) {\n            if (i % 2 == 0) {\n                reverse(chars, i * k, Math.min((i+1)*k - 1, s.length()-1));\n            }\n        }\n\n        return new String(chars);\n\n    }\n\n    private void reverse(char[] chars, int left, int right) {\n        int i = 0;\n        while (i < (right-left+1)/2) {\n            swap(chars, left+i, right-i);\n            i++;\n        }\n    }\n\n    private void swap(char[] chars, int i, int j) {\n        char temp = chars[i];\n        chars[i] = chars[j];\n        chars[j] = temp;\n    }\n\n}\n"
  },
  {
    "path": "src/ReverseVowelsOfAString345.java",
    "content": "/**\n * Write a function that takes a string as input and reverse only the\n * vowels of a string.\n * \n * Example 1:\n * Given s = \"hello\", return \"holle\".\n * \n * Example 2:\n * Given s = \"leetcode\", return \"leotcede\".\n * \n * Note:\n * The vowels does not include the letter \"y\".\n */\n\npublic class ReverseVowelsOfAString345 {\n    private Set<Character> vowels = new HashSet<>(Arrays.asList('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'));\n    public String reverseVowels(String s) {\n        if (s == null || s.length() <= 1) return s;\n        char[] chars = s.toCharArray();\n        int i = 0;\n        int j = chars.length - 1;\n        while (i < j) {\n            while (i < j && !vowels.contains(chars[i])) i++;\n            while (i < j && !vowels.contains(chars[j])) j--;\n            if (i >= j) break;\n    \n            swap(chars, i, j);\n            i++;\n            j--;\n        }\n        return new String(chars);\n    }\n    \n    \n    private void swap(char[] chars, int i, int j) {\n        char tmp = chars[i];\n        chars[i] = chars[j];\n        chars[j] = tmp;\n    }\n\n}\n"
  },
  {
    "path": "src/ReverseWordsInAString151.java",
    "content": "/**\n * Given an input string, reverse the string word by word.\n * \n * Example:  \n * \n * Input: \"the sky is blue\",\n * Output: \"blue is sky the\".\n * \n * Note:\n * \n * A word is defined as a sequence of non-space characters.\n * Input string may contain leading or trailing spaces. However, your reversed\n * string should not contain leading or trailing spaces.\n * You need to reduce multiple spaces between two words to a single space in\n * the reversed string.\n */\n\n\npublic class ReverseWordsInAString151 {\n    public String reverseWords(String s) {\n        if (s == null)  return s;\n        String[] words = s.replaceAll(\"^\\\\s+\", \"\").split(\"\\\\s+\", 0);\n        int i = 0;\n        while (i < words.length/2) {\n            swap(words, i, words.length-i-1);\n            i++;\n        }\n\n        return String.join(\" \", words);\n    }\n\n    private void swap(String[] words, int i, int j) {\n        String temp = words[i];\n        words[i] = words[j];\n        words[j] = temp;\n    }\n\n    /**\n     * https://leetcode.com/problems/reverse-words-in-a-string/discuss/47781/Java-3-line-builtin-solution\n     */\n    public String reverseWords2(String s) {\n        String[] words = s.trim().split(\" +\");\n        Collections.reverse(Arrays.asList(words));\n        return String.join(\" \", words);\n    }\n\n\n    public String reverseWords3(String s) {\n        if (s == null || s.length() == 0){\n            return s;\n        }\n        String[] array = s.split(\" \");\n        StringBuilder res = new StringBuilder();\n        for (int i = array.length - 1; i >= 0; i--){\n            if(array[i].length() != 0){\n                if (res.length() > 0){\n                    res.append(\" \");\n                }\n                res.append(array[i]);\n            }\n        }\n        return res.toString();\n    }\n\n\n    /**\n     * https://leetcode.com/problems/reverse-words-in-a-string/discuss/47720/Clean-Java-two-pointers-solution-(no-trim(-)-no-split(-)-no-StringBuilder)\n     */\n    public String reverseWords4(String s) {\n        if (s == null) return null;\n        \n        char[] a = s.toCharArray();\n        int n = a.length;\n        \n        // step 1. reverse the whole string\n        reverse(a, 0, n - 1);\n        // step 2. reverse each word\n        reverseWords(a, n);\n        // step 3. clean up spaces\n        return cleanSpaces(a, n);\n    }\n    \n    void reverseWords(char[] a, int n) {\n        int i = 0, j = 0;\n          \n        while (i < n) {\n            while (i < j || i < n && a[i] == ' ') i++; // skip spaces\n            while (j < i || j < n && a[j] != ' ') j++; // skip non spaces\n            reverse(a, i, j - 1);                      // reverse the word\n        }\n    }\n    \n    // trim leading, trailing and multiple spaces\n    String cleanSpaces(char[] a, int n) {\n        int i = 0, j = 0;\n          \n        while (j < n) {\n            while (j < n && a[j] == ' ') j++;             // skip spaces\n            while (j < n && a[j] != ' ') a[i++] = a[j++]; // keep non spaces\n            while (j < n && a[j] == ' ') j++;             // skip spaces\n            if (j < n) a[i++] = ' ';                      // keep only one space\n        }\n      \n        return new String(a).substring(0, i);\n    }\n    \n    // reverse a[] from a[i] to a[j]\n    private void reverse(char[] a, int i, int j) {\n        while (i < j) {\n            char t = a[i];\n            a[i++] = a[j];\n            a[j--] = t;\n        }\n    }\n\n\n    public String reverseWords5(String s) {\n        if (s == null || s.length() == 0) return s;\n        char[] chars = s.trim().toCharArray();\n        int N = chars.length;\n        char[] res = new char[N];\n        int right = N - 1;\n        int left = 0;\n        while (right >= 0) {\n            while (right >= 0 && chars[right] == ' ') {\n                right--;\n            }\n            if (right < 0) break;\n            int end = right;\n            while (right >= 0 && chars[right] != ' ') {\n                right--;\n            }\n            \n            int i = right + 1;\n            while (i <= end) {\n                res[left++] = chars[i++];\n            }\n            if (right < 0) break;\n            res[left++] = ' ';\n        }\n        return new String(res, 0, left);\n    }\n\n}\n\n"
  },
  {
    "path": "src/ReverseWordsInAStringII186.java",
    "content": "/**\n * Given an input string , reverse the string word by word. \n * \n * Example:\n * \n * Input:  [\"t\",\"h\",\"e\",\" \",\"s\",\"k\",\"y\",\" \",\"i\",\"s\",\" \",\"b\",\"l\",\"u\",\"e\"]\n * Output: [\"b\",\"l\",\"u\",\"e\",\" \",\"i\",\"s\",\" \",\"s\",\"k\",\"y\",\" \",\"t\",\"h\",\"e\"]\n * \n * Note: \n * \n * A word is defined as a sequence of non-space characters.\n * The input string does not contain leading or trailing spaces.\n * The words are always separated by a single space.\n * Follow up: Could you do it in-place without allocating extra space?\n * \n */\n\n\npublic class ReverseWordsInAStringII186 {\n    public void reverseWords(char[] str) {\n        int i = 0;\n        while (i < str.length/2) {\n            swap(str, i, str.length-i-1);\n            i++;\n        }\n        i = 0;\n        while (i < str.length) {\n            int j = i;\n            while (j < str.length && str[j] != ' ') j++;\n            int k = 0;\n            while (k < (j-i)/2) {\n                swap(str, i+k, j-k-1);\n                k++;\n            }\n            i = j+1;\n        }\n        \n    }\n    \n    private void swap(char[] str, int i, int j) {\n        char temp = str[i];\n        str[i] = str[j];\n        str[j] = temp;\n    }\n\n\n    public void reverseWords2(char[] str) {\n        if (str == null || str.length <= 2) return;\n        int len = str.length;\n        int i = 0;\n        int j = len - 1;\n        int preI = i;\n        int preJ = j;\n        while (i <= j) {\n            if (str[i] == ' ') {\n                reverseOneWord(str, j+1, preJ);\n                preJ = j-1;\n            }\n            if (str[j] == ' ') {\n                reverseOneWord(str, preI, i-1);\n                preI = i + 1;\n            }\n            swap(str, i++, j--);\n        }\n        if (preI < preJ) {\n            reverseOneWord(str, preI, preJ);\n        }\n    }\n    \n    private void reverseOneWord(char[] str, int i, int j) {\n        while (i < j) {\n            swap(str, i++, j--);\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/ReverseWordsInAStringIII557.java",
    "content": "/**\n * Given a string, you need to reverse the order of characters in each word\n * within a sentence while still preserving whitespace and initial word order.\n * \n * Example 1:\n * Input: \"Let's take LeetCode contest\"\n * Output: \"s'teL ekat edoCteeL tsetnoc\"\n * Note: In the string, each word is separated by single space and there will\n * not be any extra space in the string.\n */\n\n\npublic class ReverseWordsInAStringIII557 {\n    public String reverseWords(String s) {\n        char[] chars = s.toCharArray();\n        int i = 0;\n        int j = 0;\n        while (i < s.length()) {\n            j = i;\n            while (j < s.length() && chars[j] != ' ') {\n                j++;\n            }\n            for (int k=0; k<(j-i)/2; k++) {\n                swap(chars, i+k, j-k-1);\n            }\n            i = j+1;\n        }\n        \n        return new String(chars);\n    }\n    \n    private void swap(char[] chars, int i, int j) {\n        char temp = chars[i];\n        chars[i] = chars[j];\n        chars[j] = temp;\n    }\n\n}\n"
  },
  {
    "path": "src/RobotRoomCleaner.java",
    "content": "/**\n * Given a robot cleaner in a room modeled as a grid.\n * \n * Each cell in the grid can be empty or blocked.\n * \n * The robot cleaner with 4 given APIs can move forward, turn left or turn\n * right. Each turn it made is 90 degrees.\n * \n * When it tries to move into a blocked cell, its bumper sensor detects the\n * obstacle and it stays on the current cell.\n * \n * Design an algorithm to clean the entire room using only the 4 given APIs\n * shown below.\n * \n * interface Robot {\n *   // returns true if next cell is open and robot moves into the cell.\n *   // returns false if next cell is obstacle and robot stays on the current cell.\n *   boolean move();\n * \n *   // Robot will stay on the same cell after calling turnLeft/turnRight.\n *   // Each turn will be 90 degrees.\n *   void turnLeft();\n *   void turnRight();\n * \n *   // Clean the current cell.\n *   void clean();\n * }\n * \n * Example:\n * Input:\n * room = [\n *   [1,1,1,1,1,0,1,1],\n *   [1,1,1,1,1,0,1,1],\n *   [1,0,1,1,1,1,1,1],\n *   [0,0,0,1,0,0,0,0],\n *   [1,1,1,1,1,1,1,1]\n * ],\n * row = 1,\n * col = 3\n * \n * Explanation:\n * All grids in the room are marked by either 0 or 1.\n * 0 means the cell is blocked, while 1 means the cell is accessible.\n * The robot initially starts at the position of row=1, col=3.\n * From the top left corner, its position is one row below and three columns right.\n * \n * Notes:\n * - The input is only given to initialize the room and the robot's position\n * internally. You must solve this problem \"blindfolded\". In other words,\n * you must control the robot using only the mentioned 4 APIs, without knowing\n * the room layout and the initial robot's position.\n * - The robot's initial position will always be in an accessible cell.\n * - The initial direction of the robot will be facing up.\n * - All accessible cells are connected, which means the all cells marked as 1\n * will be accessible by the robot.\n * - Assume all four edges of the grid are all surrounded by wall.\n */\n\n/**\n * // This is the robot's control interface.\n * // You should not implement it, or speculate about its implementation\n * interface Robot {\n *     // Returns true if the cell in front is open and robot moves into the cell.\n *     // Returns false if the cell in front is blocked and robot stays in the current cell.\n *     public boolean move();\n *\n *     // Robot will stay in the same cell after calling turnLeft/turnRight.\n *     // Each turn will be 90 degrees.\n *     public void turnLeft();\n *     public void turnRight();\n *\n *     // Clean the current cell.\n *     public void clean();\n * }\n */\n\npublic class RobotRoomCleaner {\n    public void cleanRoom(Robot robot) {\n        cleanRoom(robot, new HashMap<Integer, Set<Integer>>(), new int[2], 0, true);\n    }\n\n    public void cleanRoom(Robot robot, Map<Integer, Set<Integer>> map, int[] pos, int dir, boolean in) {\n        robot.clean();\n        if (!map.containsKey(pos[0])) {\n            map.put(pos[0], new HashSet<>());\n        }\n        map.get(pos[0]).add(pos[1]);\n        int[] nxt = next(pos, dir);\n        if (!contains(map, nxt) && robot.move()) {\n            cleanRoom(robot, map, nxt, dir, false);\n        }\n\n        dir = (dir + 1) % 4;\n        robot.turnLeft();\n        nxt = next(pos, dir);\n        if (!contains(map, nxt) && robot.move()) {\n            cleanRoom(robot, map, nxt, dir, false);\n        }\n\n        dir = (dir + 1) % 4;\n        robot.turnLeft();\n        nxt = next(pos, dir);\n        if (in && !contains(map, nxt) && robot.move()) {\n            cleanRoom(robot, map, nxt, dir, false);\n        }\n\n        dir = (dir + 1) % 4;\n        robot.turnLeft();\n        nxt = next(pos, dir);\n        if (!contains(map, nxt) && robot.move()) {\n            cleanRoom(robot, map, nxt, dir, false);\n        }\n        robot.turnRight();\n        robot.move();\n        robot.turnLeft();\n        robot.turnLeft();\n    }\n\n    private boolean contains(Map<Integer, Set<Integer>> map, int[] pos) {\n        return map.containsKey(pos[0]) && map.get(pos[0]).contains(pos[1]);\n    }\n\n    private int[] next(int[] now, int dir) {\n        if (dir == 0) {\n            return up(now);\n        } else if (dir == 1) {\n            return left(now);\n        } else if (dir == 2) {\n            return down(now);\n        } else {\n            return right(now);\n        }\n    }\n\n    private int[] up(int[] now) {\n        return new int[]{now[0]-1, now[1]};\n    }\n\n    private int[] left(int[] now) {\n        return new int[]{now[0], now[1]-1};\n    }\n\n    private int[] down(int[] now) {\n        return new int[]{now[0]+1, now[1]};\n    }\n\n    private int[] right(int[] now) {\n        return new int[]{now[0], now[1]+1};\n    }\n\n\n    public void cleanRoom2(Robot robot) {\n        dfs(robot, new HashMap<>(), new int[2], 0);\n    }\n\n    private void dfs(Robot robot, Map<Integer, Set<Integer>> visited, int[] pos, int dir) {\n        // System.out.println(pos[0] + \", \" + pos[1] + \": \" + dir);\n        if (visited.containsKey(pos[0]) && visited.get(pos[0]).contains(pos[1])) {\n            robot.turnRight();\n            robot.turnRight();\n            robot.move();\n            return;\n        }\n\n        if (!visited.containsKey(pos[0])) visited.put(pos[0], new HashSet<>());\n        visited.get(pos[0]).add(pos[1]);\n        robot.clean();\n\n        if (robot.move()) {\n            dfs(robot, visited, nextPos(pos, dir), dir);\n        } else {\n            robot.turnRight();\n            robot.turnRight();\n        }\n\n        robot.turnRight();\n        dir = nextDir(dir, 3);\n        if (robot.move()) {\n            dfs(robot, visited, nextPos(pos, dir), dir);\n        } else {\n            robot.turnRight();\n            robot.turnRight();\n        }\n\n        dir = nextDir(dir, 2);\n        if (robot.move()) {\n            dfs(robot, visited, nextPos(pos, dir), dir);\n            robot.turnLeft();\n        } else {\n            robot.turnRight();\n        }\n\n        dir = nextDir(dir, 1);\n        if (robot.move()) {\n            dfs(robot, visited, nextPos(pos, dir), dir);\n            robot.turnRight();\n            robot.turnRight();\n        }\n        robot.move();\n    }\n\n    private int nextDir(int dir, int move) {\n        return (dir + move) % 4; \n    }\n\n    private int[] nextPos(int[] pos, int dir) {\n        if (dir == 0) {\n            return new int[]{pos[0], pos[1]+1};\n        } else if (dir == 1) {\n            return new int[]{pos[0]+1, pos[1]};\n        } else if (dir == 2) {\n            return new int[]{pos[0], pos[1]-1};\n        } else {\n            return new int[]{pos[0]-1, pos[1]};\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/RomanToInteger13.java",
    "content": "/**\n * Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.\n * \n * Symbol       Value\n * I             1\n * V             5\n * X             10\n * L             50\n * C             100\n * D             500\n * M             1000\n * For example, two is written as II in Roman numeral, just two one's added\n * together. Twelve is written as, XII, which is simply X + II. The number\n * twenty seven is written as XXVII, which is XX + V + II.\n * \n * Roman numerals are usually written largest to smallest from left to right.\n * However, the numeral for four is not IIII. Instead, the number four is\n * written as IV. Because the one is before the five we subtract it making four.\n * The same principle applies to the number nine, which is written as IX. There\n * are six instances where subtraction is used:\n * \n * I can be placed before V (5) and X (10) to make 4 and 9. \n * X can be placed before L (50) and C (100) to make 40 and 90. \n * C can be placed before D (500) and M (1000) to make 400 and 900.\n * Given a roman numeral, convert it to an integer. Input is guaranteed to be\n * within the range from 1 to 3999.\n * \n * Example 1:\n * Input: \"III\"\n * Output: 3\n * \n * Example 2:\n * Input: \"IV\"\n * Output: 4\n * \n * Example 3:\n * Input: \"IX\"\n * Output: 9\n * \n *  Example 4:\n * Input: \"LVIII\"\n * Output: 58\n * Explanation: C = 100, L = 50, XXX = 30 and III = 3.\n * \n * Example 5:\n * Input: \"MCMXCIV\"\n * Output: 1994\n * Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.\n */\n\n\npublic class RomanToInteger13 {\n    public int romanToInt(String s) {\n        int res = 0;\n        int i = 0;\n        while (i < s.length()) {\n            char c = s.charAt(i);\n            switch (c) {\n                case 'I':\n                    if (i+1 < s.length()) {\n                        char next = s.charAt(i+1);\n                        if (next == 'V') {\n                            res += 4;\n                            i += 2;\n                        } else if (next == 'X') {\n                            res += 9;\n                            i += 2;\n                        } else {\n                            res += 1;\n                            i++;\n                        }\n                    } else {\n                        res += 1;\n                        i++;\n                    }\n                    break;\n                case 'V':\n                    res += 5;\n                    i++;\n                    break;\n                case 'X':\n                    if (i+1 < s.length()) {\n                        char next = s.charAt(i+1);\n                        if (next == 'L') {\n                            res += 40;\n                            i += 2;\n                        } else if (next == 'C') {\n                            res += 90;\n                            i += 2;\n                        } else {\n                            res += 10;\n                            i++;\n                        }\n                    } else {\n                        res += 10;\n                        i++;\n                    }\n                    break;\n                case 'L':\n                    res += 50;\n                    i++;\n                    break;\n                case 'C':\n                    if (i+1 < s.length()) {\n                        char next = s.charAt(i+1);\n                        if (next == 'D') {\n                            res += 400;\n                            i += 2;\n                        } else if (next == 'M') {\n                            res += 900;\n                            i += 2;\n                        } else {\n                            res += 100;\n                            i++;\n                        }\n                    } else {\n                        res += 100;\n                        i++;\n                    }\n                    break;\n                case 'D':\n                    res += 500;\n                    i++;\n                    break;\n                case 'M':\n                    res += 1000;\n                    i++;\n                    break;\n                default:\n                    return 0;\n            }\n        }\n        \n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/roman-to-integer/discuss/6509/7ms-solution-in-Java.-easy-to-understand\n     */\n    public int romanToInt2(String s) {\n        int nums[]=new int[s.length()];\n        for(int i=0;i<s.length();i++){\n            switch (s.charAt(i)){\n                case 'M':\n                    nums[i]=1000;\n                    break;\n                case 'D':\n                    nums[i]=500;\n                    break;\n                case 'C':\n                    nums[i]=100;\n                    break;\n                case 'L':\n                    nums[i]=50;\n                    break;\n                case 'X' :\n                    nums[i]=10;\n                    break;\n                case 'V':\n                    nums[i]=5;\n                    break;\n                case 'I':\n                    nums[i]=1;\n                    break;\n            }\n        }\n        int sum=0;\n        for(int i=0;i<nums.length-1;i++){\n            if(nums[i]<nums[i+1])\n                sum-=nums[i];\n            else\n                sum+=nums[i];\n        }\n        return sum+nums[nums.length-1];\n    }\n\n\n}"
  },
  {
    "path": "src/RotateArray189.java",
    "content": "/**\n * Rotate an array of n elements to the right by k steps.\n *\n * For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated\n * to [5,6,7,1,2,3,4].\n *\n * Note:\n * Try to come up as many solutions as you can, there are at least 3 different\n * ways to solve this problem.\n *\n * Hint:\n * Could you do it in-place with O(1) extra space?\n * Related problem: Reverse Words in a String II\n *\n */\n\n\npublic class RotateArray189 {\n    public void rotate(int[] nums, int k) {\n        int kk = k % nums.length;\n        if (kk == 0) return;\n\n        boolean[] visited = new boolean[nums.length];\n        for (int i=0; i<nums.length; i++) {\n            if (visited[i]) continue;\n            int j = i;\n            int r = nums[j];\n            while (true) {\n                int nextIndex = (j+k) % nums.length;\n                int temp = nums[nextIndex];\n                nums[nextIndex] = r;\n                visited[nextIndex] = true;\n                r = temp;\n                j = nextIndex;\n                if (j == i) break;\n            }\n        }\n    }\n\n    /**\n     * https://leetcode.com/problems/rotate-array/solution/\n     */\n    public void rotate2(int[] nums, int k) {\n        int[] a = new int[nums.length];\n        for (int i = 0; i < nums.length; i++) {\n            a[(i + k) % nums.length] = nums[i];\n        }\n        for (int i = 0; i < nums.length; i++) {\n            nums[i] = a[i];\n        }\n    }\n\n    /**\n     * https://leetcode.com/problems/rotate-array/solution/\n     */\n    public void rotate3(int[] nums, int k) {\n        k = k % nums.length;\n        int count = 0;\n        for (int start = 0; count < nums.length; start++) {\n            int current = start;\n            int prev = nums[start];\n            do {\n                int next = (current + k) % nums.length;\n                int temp = nums[next];\n                nums[next] = prev;\n                prev = temp;\n                current = next;\n                count++;\n            } while (start != current);\n        }\n    }\n\n    /**\n     * https://leetcode.com/problems/rotate-array/solution/\n     */\n    public void rotate4(int[] nums, int k) {\n        k %= nums.length;\n        reverse(nums, 0, nums.length - 1);\n        reverse(nums, 0, k - 1);\n        reverse(nums, k, nums.length - 1);\n    }\n    public void reverse(int[] nums, int start, int end) {\n        while (start < end) {\n            int temp = nums[start];\n            nums[start] = nums[end];\n            nums[end] = temp;\n            start++;\n            end--;\n        }\n    }\n\n\n    public void rotate5(int[] nums, int k) {\n        if (nums == null || nums.length <= 1) return;\n        int len = nums.length;\n        \n        k = k % len;\n        if (k == 0) return;        \n        int count = 0;\n        for (int i=0; i<k && count < len; i++) {\n            count += cipher(nums, k, i, len);\n        }\n    }\n    \n    private int cipher(int[] nums, int k, int start, int len) {\n        int res = 0;\n        int i = start;\n        int pre = nums[i];\n        do {\n            i = (i + k) % len;\n            int old = nums[i];\n            nums[i] = pre;\n            pre = old;\n            res++;\n        } while (i != start);\n        return res;\n    }\n    \n\n}\n"
  },
  {
    "path": "src/RotateFunction396.java",
    "content": "/**\n * Given an array of integers A and let n to be its length.\n * \n * Assume Bk to be an array obtained by rotating the array A k positions\n * clock-wise, we define a \"rotation function\" F on A as follow:\n * \n * F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1].\n * \n * Calculate the maximum value of F(0), F(1), ..., F(n-1).\n * \n * Note:\n * n is guaranteed to be less than 105.\n * \n * Example:\n * \n * A = [4, 3, 2, 6]\n * \n * F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25\n * F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16\n * F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23\n * F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26\n * \n * So the maximum value of F(0), F(1), F(2), F(3) is F(3) = 26.\n */\n\n\npublic class RotateFunction396 {\n    public int maxRotateFunction(int[] A) {\n        int sum = 0;\n        for (int i=0; i<A.length; i++) {\n            sum += A[i];\n        }\n\n        int rot = 0;\n        for (int i=0; i<A.length; i++) {\n            rot += i * A[i];\n        }\n        \n        int res = rot;\n        for (int i=0; i<A.length; i++) {\n            rot += sum;\n            rot -= A.length * A[A.length - 1 - i];\n            if (rot > res) {\n                res = rot;\n            }\n        }\n\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/RotateImage48.java",
    "content": "/**\n * You are given an n x n 2D matrix representing an image.\n *\n * Rotate the image by 90 degrees (clockwise).\n *\n * Note:\n * You have to rotate the image in-place, which means you have to modify the\n * input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation.\n *\n * Example 1:\n *\n * Given input matrix =\n * [\n *   [1,2,3],\n *   [4,5,6],\n *   [7,8,9]\n * ],\n *\n * rotate the input matrix in-place such that it becomes:\n * [\n *   [7,4,1],\n *   [8,5,2],\n *   [9,6,3]\n * ]\n *\n *\n * Example 2:\n *\n * Given input matrix =\n * [\n *   [ 5, 1, 9,11],\n *   [ 2, 4, 8,10],\n *   [13, 3, 6, 7],\n *   [15,14,12,16]\n * ],\n *\n * rotate the input matrix in-place such that it becomes:\n * [\n *   [15,13, 2, 5],\n *   [14, 3, 4, 1],\n *   [12, 6, 8, 9],\n *   [16, 7,10,11]\n * ]\n *\n */\n\n\npublic class RotateImage48 {\n    public void rotate(int[][] matrix) {\n        if (matrix == null || matrix.length == 0 || matrix.length == 1) return;\n        int len = matrix.length;\n        int mid = (len-1)/2;\n        for (int i=0; i<=mid; i++) {\n            if (i > len-i-2) continue;\n            int last = Math.max(len-i-2, i);\n            for (int j=i; j<=last; j++) {\n                int forth = matrix[j][len-i-1];\n                int first = matrix[i][j];\n                matrix[j][len-i-1] = first;\n                int second = matrix[len-j-1][i];\n                matrix[i][j] = second;\n                int third = matrix[len-i-1][len-j-1];\n                matrix[len-j-1][i] = third;\n                matrix[len-i-1][len-j-1] = forth;\n            }\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/rotate-image/discuss/18879/AC-Java-in-place-solution-with-explanation-Easy-to-understand.\n     */\n    public void rotate2(int[][] matrix) {\n        for(int i = 0; i<matrix.length; i++){\n            for(int j = i; j<matrix[0].length; j++){\n                int temp = 0;\n                temp = matrix[i][j];\n                matrix[i][j] = matrix[j][i];\n                matrix[j][i] = temp;\n            }\n        }\n        for(int i =0 ; i<matrix.length; i++){\n            for(int j = 0; j<matrix.length/2; j++){\n                int temp = 0;\n                temp = matrix[i][j];\n                matrix[i][j] = matrix[i][matrix.length-1-j];\n                matrix[i][matrix.length-1-j] = temp;\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/RotateList61.java",
    "content": "/**\n * Given a list, rotate the list to the right by k places, where k is non-negative.\n *\n * For example:\n * Given 1->2->3->4->5->NULL and k = 2,\n * return 4->5->1->2->3->NULL.\n */\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\n\npublic class RotateList61 {\n    public ListNode rotateRight(ListNode head, int k) {\n        if (head == null || k == 0) return head;\n\n        ListNode first = head;\n        ListNode second = head;\n\n        int i = 0;\n        while (i < k && first.next != null) {\n            first = first.next;\n            i++;\n        }\n\n        if (first.next == null && i < k) {\n            return rotateRight(head, k%(i+1));\n        }\n\n        while (first.next != null) {\n            first = first.next;\n            second = second.next;\n        }\n\n        ListNode returned = second.next;\n        first.next = head;\n        second.next = null;\n\n        return returned;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/2861/share-my-java-solution-with-explanation\n     */\n    public ListNode rotateRight2(ListNode head, int n) {\n        if (head==null||head.next==null) return head;\n        ListNode dummy=new ListNode(0);\n        dummy.next=head;\n        ListNode fast=dummy,slow=dummy;\n\n        int i;\n        for (i=0;fast.next!=null;i++)//Get the total length\n        \tfast=fast.next;\n\n        for (int j=i-n%i;j>0;j--) //Get the i-n%i th node\n        \tslow=slow.next;\n\n        fast.next=dummy.next; //Do the rotation\n        dummy.next=slow.next;\n        slow.next=null;\n\n        return dummy.next;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/26364/clean-java-solution-with-brief-explanation\n     */\n    public ListNode rotateRight3(ListNode head, int k) {\n        if (head == null)\n            return head;\n\n        ListNode copyHead = head;\n\n        int len = 1;\n        while (copyHead.next != null) {\n            copyHead = copyHead.next;\n            len++;\n        }\n\n        copyHead.next = head;\n\n        for (int i = len - k % len; i > 1; i--)\n            head = head.next;\n\n        copyHead = head.next;\n        head.next = null;\n\n        return copyHead;\n\n    }\n\n}\n"
  },
  {
    "path": "src/RussianDollEnvelopes354.java",
    "content": "/**\n * You have a number of envelopes with widths and heights given as a pair of\n * integers (w, h). One envelope can fit into another if and only if both the\n * width and height of one envelope is greater than the width and height of\n * the other envelope.\n * \n * What is the maximum number of envelopes can you Russian doll? (put one inside other)\n * \n * Note:\n * Rotation is not allowed.\n * \n * Example:\n * Input: [[5,4],[6,4],[6,7],[2,3]]\n * Output: 3 \n * Explanation: The maximum number of envelopes you can Russian doll\n * is 3 ([2,3] => [5,4] => [6,7]).\n */\n\npublic class RussianDollEnvelopes354 {\n    public int maxEnvelopes(int[][] envelopes) {\n        if (envelopes == null || envelopes.length == 0) return 0;\n        Comparator<int[]> comp = new Comparator<int[]>() {\n            @Override\n            public int compare(int[] e1, int[] e2) {\n                int wDiff = Integer.compare(e2[0], e1[0]);\n                if (wDiff != 0) return wDiff;\n                return -Integer.compare(e2[1], e1[1]);\n            }\n        };\n\n        Arrays.sort(envelopes, comp);\n        int N = envelopes.length;\n        int[] dp = new int[N];\n        int res = 1;\n        for (int i=0; i<N; i++) {\n            dp[i] = 1;\n            for (int j=0; j<i; j++) {\n                if (isLarger(envelopes[j], envelopes[i]) && dp[j] + 1 > dp[i]) {\n                    dp[i] = dp[j] + 1;\n                }\n            }\n            if (dp[i] > res) res = dp[i];\n        }\n        return res;\n    }\n\n    private boolean isLarger(int[] e1, int[] e2) {\n        return e1[0] > e2[0] && e1[1] > e2[1];\n    }\n\n\n    public int maxEnvelopes2(int[][] envelopes) {\n        if (envelopes == null || envelopes.length == 0) return 0;\n        Comparator<int[]> comp = new Comparator<int[]>() {\n            @Override\n            public int compare(int[] e1, int[] e2) {\n                int wDiff = Integer.compare(e1[0], e2[0]);\n                if (wDiff != 0) return wDiff;\n                return Integer.compare(e2[1], e1[1]);\n            }\n        };\n\n        Arrays.sort(envelopes, comp);\n        int N = envelopes.length;\n        int[] dp = new int[N];\n        int res = 0;\n        for (int i=0; i<N; i++) {\n            int index = Arrays.binarySearch(dp, 0, res, envelopes[i][1]);\n            if (index < 0) index = - index - 1;\n            dp[index] = envelopes[i][1];\n            if (index == res) res++;\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/SameTree100.java",
    "content": "/**\n * Given two binary trees, write a function to check if they are the same or not.\n *\n * Two binary trees are considered the same if they are structurally identical\n * and the nodes have the same value.\n *\n * Example 1:\n *\n * Input:     1         1\n *           / \\       / \\\n *          2   3     2   3\n *\n *         [1,2,3],   [1,2,3]\n *\n * Output: true\n *\n * Example 2:\n *\n * Input:     1         1\n *           /           \\\n *          2             2\n *\n *         [1,2],     [1,null,2]\n *\n * Output: false\n *\n * Example 3:\n *\n * Input:     1         1\n *           / \\       / \\\n *          2   1     1   2\n *\n *         [1,2,1],   [1,1,2]\n *\n * Output: false\n *\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class SameTree100 {\n    public boolean isSameTree(TreeNode p, TreeNode q) {\n        if (p == null && q == null) return true;\n        if (p == null || q == null || p.val != q.val) return false;\n        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/same-tree/discuss/32684/My-non-recursive-method\n     */\n    public boolean isSameTree2(TreeNode p, TreeNode q) {\n        Stack<TreeNode> stack_p = new Stack <> ();\n        Stack<TreeNode> stack_q = new Stack <> ();\n        if (p != null) stack_p.push( p ) ;\n        if (q != null) stack_q.push( q ) ;\n        while (!stack_p.isEmpty() && !stack_q.isEmpty()) {\n          TreeNode pn = stack_p.pop() ;\n          TreeNode qn = stack_q.pop() ;\n          if (pn.val != qn.val) return false ;\n          if (pn.right != null) stack_p.push(pn.right) ;\n          if (qn.right != null) stack_q.push(qn.right) ;\n          if (stack_p.size() != stack_q.size()) return false ;\n          if (pn.left != null) stack_p.push(pn.left) ;\n          if (qn.left != null) stack_q.push(qn.left) ;\n          if (stack_p.size() != stack_q.size()) return false ;\n        }\n        return stack_p.size() == stack_q.size() ;\n    }\n\n}\n"
  },
  {
    "path": "src/SearchA2DMatrix74.java",
    "content": "/**\n * Write an efficient algorithm that searches for a value in an m x n matrix.\n * This matrix has the following properties:\n * \n * Integers in each row are sorted from left to right.\n * The first integer of each row is greater than the last integer of the previous row.\n * \n * Example 1:\n * Input:\n * matrix = [\n *   [1,   3,  5,  7],\n *   [10, 11, 16, 20],\n *   [23, 30, 34, 50]\n * ]\n * target = 3\n * Output: true\n * \n * Example 2:\n * Input:\n * matrix = [\n *   [1,   3,  5,  7],\n *   [10, 11, 16, 20],\n *   [23, 30, 34, 50]\n * ]\n * target = 13\n * Output: false\n */\n\npublic class SearchA2DMatrix74 {\n    public boolean searchMatrix(int[][] matrix, int target) {\n        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return false;\n        int start = 0;\n        int end = matrix.length - 1;\n        while (start < end) {\n            int mid = start + (end - start + 1) / 2;\n            if (matrix[mid][0] == target) return true;\n            if (matrix[mid][0] < target) {\n                start = mid;\n            } else {\n                end = mid - 1;;\n            }\n        }\n        int row = start;\n        start = 0;\n        end = matrix[0].length - 1;\n        while (start < end) {\n            int mid = start + (end - start) / 2;\n            if (matrix[row][mid] == target) return true;\n            if (matrix[row][mid] > target) {\n                end = mid - 1;\n            } else {\n                start = mid + 1;\n            }\n        }\n        return matrix[row][start] == target;\n    }\n\n\n    public boolean searchMatrix2(int[][] matrix, int target) {\n        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return false;\n        int start = 0;\n        int end = matrix.length - 1;\n        while (start + 1 < end) {\n            int mid = start + (end - start) / 2;\n            if (matrix[mid][0] == target) return true;\n            if (matrix[mid][0] < target) {\n                start = mid;\n            } else {\n                end = mid - 1;;\n            }\n        }\n        int row = target >= matrix[end][0] ? end : start;\n        start = 0;\n        end = matrix[0].length - 1;\n        while (start < end) {\n            int mid = start + (end - start) / 2;\n            if (matrix[row][mid] == target) return true;\n            if (matrix[row][mid] > target) {\n                end = mid - 1;\n            } else {\n                start = mid + 1;\n            }\n        }\n        return matrix[row][start] == target;\n    }\n\n\n    public boolean searchMatrix3(int[][] matrix, int target) {\n        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return false;\n        int M = matrix.length;\n        int N = matrix[0].length;\n        int start = 0;\n        int end = M * N - 1;\n        while (start < end) {\n            int mid = start + (end - start) / 2;\n            int midVal = matrix[mid / N][mid % N];\n            if (midVal == target) return true;\n            if (midVal < target) {\n                start = mid + 1;\n            } else {\n                end = mid - 1;\n            }\n        }\n        return matrix[start / N][start % N] == target;\n    }\n\n}\n"
  },
  {
    "path": "src/SearchA2DMatrixII240.java",
    "content": "/**\n * Write an efficient algorithm that searches for a value in an m x n matrix.\n * This matrix has the following properties:\n *\n * Integers in each row are sorted in ascending from left to right.\n * Integers in each column are sorted in ascending from top to bottom.\n *\n * For example,\n *\n * Consider the following matrix:\n *\n * [\n *   [1,   4,  7, 11, 15],\n *   [2,   5,  8, 12, 19],\n *   [3,   6,  9, 16, 22],\n *   [10, 13, 14, 17, 24],\n *   [18, 21, 23, 26, 30]\n * ]\n *\n * Given target = 5, return true.\n * Given target = 20, return false.\n *\n */\n\npublic class SearchA2DMatrixII240 {\n    public boolean searchMatrix(int[][] matrix, int target) {\n        for (int i=0; i<matrix.length; i++) {\n            for (int j=0; j<matrix[0].length ; j++) {\n                if (matrix[i][j] == target) return true;\n                if (matrix[i][j] > target) break;\n            }\n        }\n        return false;\n    }\n\n    public boolean searchMatrix2(int[][] matrix, int target) {\n        int ye = matrix.length-1;\n        if (ye == -1) return false;\n        int xe = matrix[0].length-1;\n        if (xe == -1) return false;\n\n        return searchMatrix(matrix, target, 0, xe, 0, ye);\n    }\n\n    public boolean searchMatrix(int[][] matrix, int target, int xs, int xe, int ys, int ye) {\n        if (xs < 0 || ys < 0 || xs > xe || ys > ye) return false;\n\n        int midx = (xe - xs)/2 + xs;\n        int midy = (ye - ys)/2 + ys;\n\n        int now = matrix[midy][midx];\n        if (now == target) {\n            return true;\n        }\n        if (now > target) {\n            return searchMatrix(matrix, target, xs, xe, ys, midy-1) ||\n                searchMatrix(matrix, target, xs, midx-1, midy, ye);\n        }\n        return searchMatrix(matrix, target, midx+1, xe, ys, ye) ||\n            searchMatrix(matrix, target, xs, midx, midy+1, ye);\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/20064/my-concise-o-m-n-java-solution\n     */\n    public boolean searchMatrix3(int[][] matrix, int target) {\n        if(matrix == null || matrix.length < 1 || matrix[0].length <1) {\n            return false;\n        }\n        int col = matrix[0].length-1;\n        int row = 0;\n        while(col >= 0 && row <= matrix.length-1) {\n            if(target == matrix[row][col]) {\n                return true;\n            } else if(target < matrix[row][col]) {\n                col--;\n            } else if(target > matrix[row][col]) {\n                row++;\n            }\n        }\n        return false;\n    }\n\n\n    public boolean searchMatrix4(int[][] matrix, int target) {\n        if (matrix == null) return false;\n        if (matrix.length == 0 || matrix[0].length == 0) return false; \n        return searchMatrix(0, 0, matrix.length-1, matrix[0].length-1, matrix, target);\n    }\n    \n    public boolean searchMatrix(int loi, int loj, int hii, int hij, int[][] matrix, int target) {\n        if (loi > hii || loj > hij) return false;\n        if (matrix[loi][loj] > target|| matrix[hii][hij] < target) return false;\n        \n        int midi = (loi + hii) / 2;\n        int midj = (loj + hij) / 2;\n        if (matrix[midi][midj] == target) return true;\n        if (searchMatrix(loi, midj+1, midi, hij, matrix, target) ||\n            searchMatrix(midi+1, loj, hii, midj, matrix, target)) return true;\n        if (matrix[midi][midj] > target) return searchMatrix(loi, loj, midi, midj, matrix, target);\n        return searchMatrix(midi+1, midj+1, hii, hij, matrix, target);\n    }\n\n}\n"
  },
  {
    "path": "src/SearchForARange34.java",
    "content": "/**\n * Given an array of integers sorted in ascending order, find the starting and\n * ending position of a given target value.\n *\n * Your algorithm's runtime complexity must be in the order of O(log n).\n *\n * If the target is not found in the array, return [-1, -1].\n *\n * For example,\n * Given [5, 7, 7, 8, 8, 10] and target value 8,\n * return [3, 4].\n */\n\n\n\npublic class SearchForARange34 {\n    public int[] searchRange(int[] nums, int target) {\n\n        int start = 0;\n        int end = nums.length - 1;\n\n        while (start <= end) {\n            if (nums[start] < target) {\n                start++;\n            } else if (nums[end] > target) {\n                end--;\n            } else {\n                break;\n            }\n        }\n\n        if (start > nums.length - 1 || end < 0 || start > end) {\n            return new int[]{-1, -1};\n        }\n\n        return new int[]{start, end};\n    }\n\n\n\n    public int[] searchRange2(int[] nums, int target) {\n\n        int start = 0;\n        int end = nums.length - 1;\n        int mid = (end - start) >> 1 + start;\n\n        while (start <= end) {\n            if (nums[mid] < target) {\n                start = mid + 1;\n            } else if (nums[mid] > target) {\n                end = mid - 1;\n            } else {\n                break;\n            }\n\n            mid = (end - start) / 2 + start;\n        }\n\n        while (start <= end) {\n            if (nums[start] < target) {\n                start++;\n            } else if (nums[end] > target) {\n                end--;\n            } else {\n                break;\n            }\n        }\n\n        if (start > nums.length - 1 || end < 0 || start > end) {\n            return new int[]{-1, -1};\n        }\n\n        return new int[]{start, end};\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/6327/a-very-simple-java-solution-with-only-one-binary-search-algorithm\n     */\n    public int[] searchRange3(int[] A, int target) {\n  \t\tint start = Solution.firstGreaterEqual(A, target);\n  \t\tif (start == A.length || A[start] != target) {\n  \t\t\treturn new int[]{-1, -1};\n  \t\t}\n  \t\treturn new int[]{start, Solution.firstGreaterEqual(A, target + 1) - 1};\n  \t}\n\n  \t//find the first number that is greater than or equal to target.\n  \t//could return A.length if target is greater than A[A.length-1].\n  \t//actually this is the same as lower_bound in C++ STL.\n  \tprivate static int firstGreaterEqual(int[] A, int target) {\n  \t\tint low = 0, high = A.length;\n  \t\twhile (low < high) {\n  \t\t\tint mid = low + ((high - low) >> 1);\n  \t\t\t//low <= mid < high\n  \t\t\tif (A[mid] < target) {\n  \t\t\t\tlow = mid + 1;\n  \t\t\t} else {\n  \t\t\t\t//should not be mid-1 when A[mid]==target.\n  \t\t\t\t//could be mid even if A[mid]>target because mid<high.\n  \t\t\t\thigh = mid;\n  \t\t\t}\n  \t\t}\n  \t\treturn low;\n  \t}\n\n\n    /**\n     * https://discuss.leetcode.com/topic/10692/simple-and-strict-o-logn-solution-in-java-using-recursion\n     */\n    public int[] searchRange4(int[] A, int target) {\n        int[] range = {A.length, -1};\n        searchRange(A, target, 0, A.length - 1, range);\n        if (range[0] > range[1]) range[0] = -1;\n        return range;\n    }\n\n    public void searchRange(int[] A, int target, int left, int right, int[] range) {\n        if (left > right) return;\n        int mid = left + (right - left) / 2;\n        if (A[mid] == target) {\n            if (mid < range[0]) {\n                range[0] = mid;\n                searchRange(A, target, left, mid - 1, range);\n            }\n            if (mid > range[1]) {\n                range[1] = mid;\n                searchRange(A, target, mid + 1, right, range);\n            }\n        } else if (A[mid] < target) {\n            searchRange(A, target, mid + 1, right, range);\n        } else {\n            searchRange(A, target, left, mid - 1, range);\n        }\n    }\n\n\n    public int[] searchRange5(int[] nums, int target) {\n        if (nums == null || nums.length == 0) return new int[]{-1, -1};\n        return searchRange(nums, target, 0, nums.length-1);\n    }\n\n    public int[] searchRange(int[] nums, int target, int lo, int hi) {\n        if (lo > hi) return new int[]{-1, -1};\n\n        int mid = (lo + hi) / 2;\n        if (nums[mid] > target) {\n            return searchRange(nums, target, lo, mid-1);\n        } else if (nums[mid] < target) {\n            return searchRange(nums, target, mid+1, hi);\n        } else {\n            int[] res = new int[]{mid, mid};\n            int[] left = searchRange(nums, target, lo, mid-1);\n            int[] right = searchRange(nums, target, mid+1, hi);\n            if (left[0] != -1) res[0] = left[0];\n            if (right[1] != -1) res[1] = right[1];\n            return res;\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/search-for-a-range/solution/\n     */\n    // returns leftmost (or rightmost) index at which `target` should be\n    // inserted in sorted array `nums` via binary search.\n    private int extremeInsertionIndex(int[] nums, int target, boolean left) {\n        int lo = 0;\n        int hi = nums.length;\n\n        while (lo < hi) {\n            int mid = (lo+hi)/2;\n            if (nums[mid] > target || (left && target == nums[mid])) {\n                hi = mid;\n            }\n            else {\n                lo = mid+1;\n            }\n        }\n\n        return lo;\n    }\n\n    public int[] searchRange6(int[] nums, int target) {\n        int[] targetRange = {-1, -1};\n\n        int leftIdx = extremeInsertionIndex(nums, target, true);\n\n        // assert that `leftIdx` is within the array bounds and that `target`\n        // is actually in `nums`.\n        if (leftIdx == nums.length || nums[leftIdx] != target) {\n            return targetRange;\n        }\n\n        targetRange[0] = leftIdx;\n        targetRange[1] = extremeInsertionIndex(nums, target, false)-1;\n\n        return targetRange;\n    }\n\n}\n"
  },
  {
    "path": "src/SearchInASortedArrayOfUnknownSize702.java",
    "content": "/**\n * Given an integer array sorted in ascending order, write a function to search\n * target in nums.  If target exists, then return its index, otherwise\n * return -1. However, the array size is unknown to you. You may only access\n * the array using an ArrayReader interface, where ArrayReader.get(k) returns\n * the element of the array at index k (0-indexed).\n * \n * You may assume all integers in the array are less than 10000, and if you\n * access the array out of bounds, ArrayReader.get will return 2147483647.\n * \n * Example 1:\n * Input: array = [-1,0,3,5,9,12], target = 9\n * Output: 4\n * Explanation: 9 exists in nums and its index is 4\n * \n * Example 2:\n * Input: array = [-1,0,3,5,9,12], target = 2\n * Output: -1\n * Explanation: 2 does not exist in nums so return -1\n * \n * Note:\n * You may assume that all elements in the array are unique.\n * The value of each element in the array will be in the range [-9999, 9999].\n */\n\npublic class SearchInASortedArrayOfUnknownSize702 {\n    public int search(ArrayReader reader, int target) {\n        return search(reader, target, 0, 10000);\n    }\n\n    private int search(ArrayReader reader, int target, int i, int j) {\n        if (i >= j) return reader.get(i) == target ? i : -1;\n        int mid = (i + j) / 2;\n        int val = reader.get(mid);\n        if (val == target) return mid;\n        if (val > target) {\n            return search(reader, target, i, mid-1);\n        } else {\n            return search(reader, target, mid+1, j);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/search-in-a-sorted-array-of-unknown-size/discuss/151685/Shortest-and-cleanest-Java-solution-so-far...\n     */\n    public int search2(ArrayReader reader, int target) {\n        int hi = 1;\n        while (reader.get(hi) < target) {\n            hi = hi << 1;\n        }\n        int low = hi >> 1;\n        while (low <= hi) {\n            int mid = low+(hi-low)/2;\n            if (reader.get(mid) > target) {\n                hi = mid-1;\n            } else if (reader.get(mid) < target) {\n                low = mid+1;\n            } else {\n                return mid;\n            }\n        }\n        return -1;\n    }\n\n\n    public int search3(ArrayReader reader, int target) {\n        int lo = 0;\n        int hi = 20000;\n        while (lo < hi) {\n            int mid = lo + (hi - lo) / 2;\n            int midVal = reader.get(mid);\n            if (midVal == target) return mid;\n            if (midVal == Integer.MAX_VALUE || midVal > target) {\n                hi = mid - 1;\n            } else {\n                lo = mid + 1;\n            }\n        }\n        \n        return reader.get(lo) == target ? lo : -1;\n    }\n\n}\n"
  },
  {
    "path": "src/SearchInRotatedSortedArray33.java",
    "content": "/**\n * Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.\n *\n * (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).\n *\n * You are given a target value to search. If found in the array return its index, otherwise return -1.\n *\n * You may assume no duplicate exists in the array.\n */\n\n\npublic class SearchInRotatedSortedArray33 {\n    public int search(int[] nums, int target) {\n        int L = nums.length;\n        if (L == 0) return -1;\n\n        return searchHelper(nums, target, 0, L-1);\n    }\n\n    private int searchHelper(int[] nums, int target, int s, int e) {\n        if (s > e) return -1;\n\n        int mid = (e-s)/2 + s;\n        if (nums[mid] == target) {\n            return mid;\n        }\n\n        if (nums[s] < nums[e] && (nums[s] > target || nums[e] < target)) {\n            return -1;\n        }\n\n        if (nums[s] > nums[e] && target < nums[s] && nums[e] < target) {\n            return -1;\n        }\n\n        int left = searchHelper(nums, target, s, mid-1);\n        if (left != -1) return left;\n\n        return searchHelper(nums, target, mid+1, e);\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/7711/revised-binary-search\n     */\n    public int search2(int[] A, int target) {\n        int lo = 0;\n        int hi = A.length - 1;\n        if (hi == -1) return -1;\n        while (lo < hi) {\n            int mid = (lo + hi) / 2;\n            if (A[mid] == target) return mid;\n\n            if (A[lo] <= A[mid]) {\n                if (target >= A[lo] && target < A[mid]) {\n                    hi = mid - 1;\n                } else {\n                    lo = mid + 1;\n                }\n            } else {\n                if (target > A[mid] && target <= A[hi]) {\n                    lo = mid + 1;\n                } else {\n                    hi = mid - 1;\n                }\n            }\n        }\n        return A[lo] == target ? lo : -1;\n    }\n\n\n    public int search3(int[] nums, int target) {\n        int L = nums.length;\n        if (L == 0) return -1;\n        return searchHelper2(nums, target, 0, L-1);\n    }\n\n    private int searchHelper2(int[] nums, int target, int s, int e) {\n        if (s > e) return -1;\n\n        int mid = (e+s)/2;\n        if (nums[mid] == target) {\n            return mid;\n        }\n\n        if (nums[s] <= nums[mid]) {\n            if (target >= nums[s] && target <= nums[mid]) {\n                return searchHelper2(nums, target, s, mid-1);\n            } else {\n                return searchHelper2(nums, target, mid+1, e);\n            }\n        }\n        if (target >= nums[mid] && target <= nums[e]) {\n            return searchHelper2(nums, target, mid+1, e);\n        }\n\n        return searchHelper2(nums, target, s, mid-1);\n    }\n\n\n}\n"
  },
  {
    "path": "src/SearchInRotatedSortedArrayII81.java",
    "content": "/**\n * Would this affect the run-time complexity? How and why?\n *\n * Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.\n *\n * (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).\n *\n * Write a function to determine if a given target is in the array.\n *\n * The array may contain duplicates.\n *\n * Follow up for \"Search in Rotated Sorted Array\":\n * What if duplicates are allowed?\n */\n\n\npublic class SearchInRotatedSortedArrayII81 {\n    public boolean search(int[] nums, int target) {\n        System.out.println(Arrays.toString(nums));\n        int L = nums.length;\n        if (L == 0) return false;\n        int mid = L/2;\n\n        if (nums[mid] == target) {\n            return true;\n        }\n\n        return (search(Arrays.copyOfRange(nums, 0, mid), target) ||\n            search(Arrays.copyOfRange(nums, mid+1, L), target));\n    }\n\n\n    // now, let's truncate it, and do not use array copy\n    // public boolean search(int[] nums, int target) {\n    //     int L = nums.length;\n    //     if (L == 0) return false;\n    //\n    //     if (nums[0] < nums[L-1] && (nums[0] > target || nums[L-1] < target)) {\n    //         return false;\n    //     }\n    //\n    //     if (nums[0] > nums[L-1] && target < nums[0] && nums[L-1] < target) {\n    //         return false;\n    //     }\n    //\n    //     int mid = L/2;\n    //     if (nums[mid] == target) {\n    //         return true;\n    //     }\n    //\n    //     return (search(Arrays.copyOfRange(nums, 0, mid), target) ||\n    //         search(Arrays.copyOfRange(nums, mid+1, L), target));\n    // }\n\n\n    //now, let's truncate it, and do not use array copy\n    public boolean search2(int[] nums, int target) {\n        int L = nums.length;\n        if (L == 0) return false;\n\n        return searchHelper(nums, target, 0, L-1);\n    }\n\n    private boolean searchHelper(int[] nums, int target, int s, int e) {\n        if (s > e) return false;\n\n        int mid = (e-s)/2 + s;\n        if (nums[mid] == target) {\n            return true;\n        }\n\n        if (nums[s] < nums[e] && (nums[s] > target || nums[e] < target)) {\n            return false;\n        }\n\n        if (nums[s] > nums[e] && target < nums[s] && nums[e] < target) {\n            return false;\n        }\n\n        return (searchHelper(nums, target, s, mid-1) || searchHelper(nums, target, mid+1, e));\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/25487/neat-java-solution-using-binary-search\n     */\n     public boolean search3(int[] nums, int target) {\n         int start  = 0, end = nums.length - 1;\n\n         //check each num so we will check start == end\n         //We always get a sorted part and a half part\n         //we can check sorted part to decide where to go next\n         while(start <= end){\n             int mid = start + (end - start)/2;\n             if(nums[mid] == target) return true;\n\n             //if left part is sorted\n             if(nums[start] < nums[mid]){\n                 if(target < nums[start] || target > nums[mid]){\n                     //target is in rotated part\n                     start = mid + 1;\n                 }else{\n                     end = mid - 1;\n                 }\n             }else if(nums[start] > nums[mid]){\n                 //right part is sorted\n\n                 //target is in rotated part\n                 if(target < nums[mid] || target > nums[end]){\n                     end = mid -1;\n                 }else{\n                     start = mid + 1;\n                 }\n             }else{\n                 //duplicates, we know nums[mid] != target, so nums[start] != target\n                 //based on current information, we can only move left pointer to skip one cell\n                 //thus in the worest case, we would have target: 2, and array like 11111111, then\n                 //the running time would be O(n)\n                 start ++;\n             }\n         }\n\n         return false;\n     }\n\n\n     public boolean search4(int[] nums, int target) {\n         int L = nums.length;\n         if (L == 0) return false;\n         return searchHelper2(nums, target, 0, L-1);\n     }\n\n     private boolean searchHelper2(int[] nums, int target, int s, int e) {\n         if (s > e) return false;\n\n         int mid = (e+s)/2;\n         if (nums[mid] == target) {\n             return true;\n         }\n\n         if (nums[s] < nums[mid]) {\n             if (target >= nums[s] && target <= nums[mid]) {\n                 return searchHelper2(nums, target, s, mid-1);\n             } else {\n                 return searchHelper2(nums, target, mid+1, e);\n             }\n         } else if (nums[s] > nums[mid]) {\n             if (target >= nums[mid] && target <= nums[e]) {\n                 return searchHelper2(nums, target, mid+1, e);\n             } else {\n                 return searchHelper2(nums, target, s, mid-1);\n             }\n         } else {\n             return searchHelper2(nums, target, s+1, e);\n         }\n     }\n\n\n     /**\n      * https://leetcode.com/problems/search-in-rotated-sorted-array-ii/discuss/28212/When-there-are-duplicates-the-worst-case-is-O(n).-Could-we-do-better\n      */\n     public boolean search5(int A[], int key) {\n         int l = 0, r = A.length - 1;\n         while (l <= r) {\n             int m = l + (r - l)/2;\n             if (A[m] == key) return true; //return m in Search in Rotated Array I\n             if (A[l] < A[m]) { //left half is sorted\n                 if (A[l] <= key && key < A[m])\n                     r = m - 1;\n                 else\n                     l = m + 1;\n             } else if (A[l] > A[m]) { //right half is sorted\n                 if (A[m] < key && key <= A[r])\n                     l = m + 1;\n                 else\n                     r = m - 1;\n             } else l++;\n         }\n         return false;\n     }\n\n\n     public boolean search6(int[] nums, int target) {\n        if (nums == null || nums.length == 0) return false;\n        int start = 0;\n        int end = nums.length - 1;\n        \n        while (start < end) {\n            int mid = start + (end - start) / 2;\n            int midVal = nums[mid];\n            if (midVal == target) return true;\n            if (midVal > nums[start]) {\n                if (target >= nums[start] && target < midVal) {\n                    end = mid -1;\n                } else {\n                    start = mid + 1;\n                }\n            } else if (midVal < nums[end]) {\n                if (target > midVal && target <= nums[end]) {\n                    start = mid + 1;\n                } else {\n                    end= mid - 1;\n                }\n            } else {\n                if (midVal == nums[start]) {\n                    start++;\n                }\n                if (midVal == nums[end]) {\n                    end--;\n                }\n            }\n        }\n\n        return nums[start] == target;\n    }\n\n}\n"
  },
  {
    "path": "src/SearchInsertPosition35.java",
    "content": "/**\n * Given a sorted array and a target value, return the index if the target is\n * found. If not, return the index where it would be if it were inserted in\n * order.\n *\n * You may assume no duplicates in the array.\n *\n * Here are few examples.\n * [1,3,5,6], 5 → 2\n * [1,3,5,6], 2 → 1\n * [1,3,5,6], 7 → 4\n * [1,3,5,6], 0 → 0\n */\n\n\npublic class SearchInsertPosition35 {\n    public int searchInsert(int[] nums, int target) {\n        for (int i = 0; i < nums.length; i++) {\n            if (nums[i] >= target) {\n                return i;\n            }\n        }\n        return nums.length;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/7874/my-8-line-java-solution\n     */\n    public int searchInsert2(int[] A, int target) {\n        int low = 0, high = A.length-1;\n        while(low <= high){\n            int mid = (low + high) / 2;\n            if(A[mid] == target) return mid;\n            else if(A[mid] > target) high = mid-1;\n            else low = mid+1;\n        }\n        return low;\n    }\n\n\n    public int searchInsert3(int[] nums, int target) {\n        if (nums.length == 0) return 0;\n        if (target > nums[nums.length-1]) return nums.length;\n        int l = 0;\n        int r = nums.length-1;\n        \n        while (l < r) {\n            int mid = (r - l) / 2 + l;\n            if (nums[mid] == target) return mid;\n            else if (nums[mid] < target) {\n                l = mid + 1;\n            } else {\n                r = mid;\n            }\n        }\n        return l;\n    }\n\n}\n"
  },
  {
    "path": "src/SecondMinimumNodeInABinaryTree671.java",
    "content": "/**\n * Given a non-empty special binary tree consisting of nodes with the\n * non-negative value, where each node in this tree has exactly two or zero\n * sub-node. If the node has two sub-nodes, then this node's value is the\n * smaller value among its two sub-nodes.\n * \n * Given such a binary tree, you need to output the second minimum value in the\n * set made of all the nodes' value in the whole tree.\n * \n * If no such second minimum value exists, output -1 instead.\n * \n * Example 1:\n * Input: \n *     2\n *    / \\\n *   2   5\n *      / \\\n *     5   7\n * \n * Output: 5\n * Explanation: The smallest value is 2, the second smallest value is 5.\n * \n * Example 2:\n * Input: \n *     2\n *    / \\\n *   2   2\n * \n * Output: -1\n * Explanation: The smallest value is 2, but there isn't any second smallest\n * value.\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class SecondMinimumNodeInABinaryTree671 {\n    public int findSecondMinimumValue(TreeNode root) {\n        if (root == null) return -1;\n        int[] cache = new int[]{-1, -1};\n        dfs(root, cache, root.val);\n        if (cache[0] == -1 || cache[1] == -1) return -1;\n        return Math.max(Math.max(cache[0], -1), cache[1]);\n    }\n\n    private void dfs(TreeNode root, int[] cache, int min) {\n        if (root == null) return;\n        int val = root.val;\n        if (cache[0] != val && cache[1] != val) {\n            if (cache[0] == -1) {\n                cache[0] = val;\n            } else if (cache[1] == -1) {\n                cache[1] = val;\n            } else {\n                if (cache[0] > val) {\n                    cache[0] = val;\n                } else if (cache[1] > val) {\n                    cache[1] = val;\n                }\n            }\n        }\n        if (val > min) return;\n        \n        dfs(root.left, cache, min);\n        dfs(root.right, cache, min);\n    }\n\n}\n\n"
  },
  {
    "path": "src/SentenceScreenFitting418.java",
    "content": "/**\n * Given a rows x cols screen and a sentence represented by a list of non-empty\n * words, find how many times the given sentence can be fitted on the screen.\n * \n * Note:\n * A word cannot be split into two lines.\n * The order of words in the sentence must remain unchanged.\n * Two consecutive words in a line must be separated by a single space.\n * Total words in the sentence won't exceed 100.\n * Length of each word is greater than 0 and won't exceed 10.\n * 1 ≤ rows, cols ≤ 20,000.\n * \n * Example 1:\n * Input:\n * rows = 2, cols = 8, sentence = [\"hello\", \"world\"]\n * Output: 1\n * Explanation:\n * hello---\n * world---\n * The character '-' signifies an empty space on the screen.\n * \n * Example 2:\n * Input:\n * rows = 3, cols = 6, sentence = [\"a\", \"bcd\", \"e\"]\n * Output: 2\n * Explanation:\n * a-bcd- \n * e-a---\n * bcd-e-\n * The character '-' signifies an empty space on the screen.\n * \n * Example 3:\n * Input:\n * rows = 4, cols = 5, sentence = [\"I\", \"had\", \"apple\", \"pie\"]\n * Output: 1\n * Explanation:\n * I-had\n * apple\n * pie-I\n * had--\n * The character '-' signifies an empty space on the screen.\n */\n\npublic class SentenceScreenFitting418 {\n    /**\n     * https://leetcode.com/problems/sentence-screen-fitting/discuss/90845/21ms-18-lines-Java-solution\n     */\n    public int wordsTyping(String[] sentence, int rows, int cols) {\n        String s = String.join(\" \", sentence) + \" \";\n        int start = 0, l = s.length();\n        for (int i = 0; i < rows; i++) {\n            start += cols;\n            if (s.charAt(start % l) == ' ') {\n                start++;\n            } else {\n                while (start > 0 && s.charAt((start-1) % l) != ' ') {\n                    start--;\n                }\n            }\n        }\n        \n        return start / s.length();\n    }\n\n\n    /**\n     * https://leetcode.com/problems/sentence-screen-fitting/discuss/90846/JAVA-optimized-solution-17ms\n     */\n    public int wordsTyping2(String[] sentence, int rows, int cols) {\n        int[] nextIndex = new int[sentence.length];\n        int[] times = new int[sentence.length];\n        for(int i=0;i<sentence.length;i++) {\n            int curLen = 0;\n            int cur = i;\n            int time = 0;\n            while(curLen + sentence[cur].length() <= cols) {\n                curLen += sentence[cur++].length()+1;\n                if(cur==sentence.length) {\n                    cur = 0;\n                    time ++;\n                }\n            }\n            nextIndex[i] = cur;\n            times[i] = time;\n        }\n        int ans = 0;\n        int cur = 0;\n        for(int i=0; i<rows; i++) {\n            ans += times[cur];\n            cur = nextIndex[cur];\n        }\n        return ans;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/sentence-screen-fitting/discuss/90874/12ms-Java-solution-using-DP\n     */\n    public int wordsTyping3(String[] sentence, int rows, int cols) {\n        int[] dp = new int[sentence.length];\n        int n = sentence.length;\n        for(int i = 0, prev = 0, len = 0; i < sentence.length; ++i) {\n            // remove the length of previous word and space\n            if(i != 0 && len > 0) len -= sentence[i - 1].length() + 1;\n            // calculate the start of next line.\n            // it's OK the index is beyond the length of array so that \n            // we can use it to count how many words one row has.\n            while(len + sentence[prev % n].length() <= cols) len += sentence[prev++ % n].length() + 1;\n            dp[i] = prev;\n        }\n        int count = 0;\n        for(int i = 0, k = 0; i < rows; ++i) {\n            // count how many words one row has and move to start of next row.\n            // It's better to check if d[k] == k but I find there is no test case on it. \n            // if(dp[k] == k) return 0;\n            count += dp[k] - k;\n            k = dp[k] % n;\n        }\n        // divide by the number of words in sentence\n        return count / n;\n    }\n\n\n    public int wordsTyping4(String[] sentence, int rows, int cols) {\n        char[] words = (String.join(\" \", sentence) + \" \").toCharArray();\n        int len = words.length;\n        int[] marks = new int[len];\n        int j = 0;\n        for (int i=0; i<len; i++) {\n            if (words[i] == ' ') j = i + 1;\n            marks[i] = j;\n        }\n        int row = 0;\n        int idx = 0;\n        while (row < rows) {\n            idx += cols;\n            idx = (idx / len) * len + marks[idx % len];\n            row++;\n        }\n        return idx / len;\n    }\n\n}\n"
  },
  {
    "path": "src/SentenceSimilarity734.java",
    "content": "/**\n * Given two sentences words1, words2 (each represented as an array of\n * strings), and a list of similar word pairs pairs, determine if two sentences\n * are similar.\n * \n * For example, \"great acting skills\" and \"fine drama talent\" are similar, if\n * the similar word pairs are pairs = [[\"great\", \"fine\"], [\"acting\",\"drama\"],\n * [\"skills\",\"talent\"]].\n * \n * Note that the similarity relation is not transitive. For example, if\n * \"great\" and \"fine\" are similar, and \"fine\" and \"good\" are similar, \"great\"\n * and \"good\" are not necessarily similar.\n * \n * However, similarity is symmetric. For example, \"great\" and \"fine\" being\n * similar is the same as \"fine\" and \"great\" being similar.\n * \n * Also, a word is always similar with itself. For example, the sentences\n * words1 = [\"great\"], words2 = [\"great\"], pairs = [] are similar, even though\n * there are no specified similar word pairs.\n * \n * Finally, sentences can only be similar if they have the same number of\n * words. So a sentence like words1 = [\"great\"] can never be similar to\n * words2 = [\"doubleplus\",\"good\"].\n * \n * Note:\n * The length of words1 and words2 will not exceed 1000.\n * The length of pairs will not exceed 2000.\n * The length of each pairs[i] will be 2.\n * The length of each words[i] and pairs[i][j] will be in the range [1, 20].\n */\n\n\npublic class SentenceSimilarity734 {\n    public boolean areSentencesSimilar(String[] words1, String[] words2, String[][] pairs) {\n        if (words1.length != words2.length) return false;\n        Map<String, Set<String>> similarity = new HashMap<>();\n        for (String[] pair: pairs) {\n            if (!similarity.containsKey(pair[0])) similarity.put(pair[0], new HashSet<>());\n            if (!similarity.containsKey(pair[1])) similarity.put(pair[1], new HashSet<>());\n            similarity.get(pair[0]).add(pair[1]);\n            similarity.get(pair[1]).add(pair[0]);\n        }\n        int len = words1.length;\n        for (int i=0; i<len; i++) {\n            String w1 = words1[i];\n            String w2 = words2[i];\n            if (w1.equals(w2)) continue;\n            if (!similarity.containsKey(w1) || !similarity.get(w1).contains(w2)) return false;\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/SentenceSimilarityII737.java",
    "content": "/**\n * Given two sentences words1, words2 (each represented as an array of strings),\n * and a list of similar word pairs pairs, determine if two sentences are similar.\n * \n * For example, words1 = [\"great\", \"acting\", \"skills\"] and\n * words2 = [\"fine\", \"drama\", \"talent\"] are similar, if the similar word pairs\n * are pairs = [[\"great\", \"good\"], [\"fine\", \"good\"], [\"acting\",\"drama\"],\n * [\"skills\",\"talent\"]].\n * \n * Note that the similarity relation is transitive. For example, if \"great\"\n * and \"good\" are similar, and \"fine\" and \"good\" are similar, then \"great\" and\n * \"fine\" are similar.\n * \n * Similarity is also symmetric. For example, \"great\" and \"fine\" being similar\n * is the same as \"fine\" and \"great\" being similar.\n * \n * Also, a word is always similar with itself. For example, the sentences\n * words1 = [\"great\"], words2 = [\"great\"], pairs = [] are similar, even though\n * there are no specified similar word pairs.\n * \n * Finally, sentences can only be similar if they have the same number of words.\n * So a sentence like words1 = [\"great\"] can never be similar to\n * words2 = [\"doubleplus\",\"good\"].\n * \n * Note:\n * The length of words1 and words2 will not exceed 1000.\n * The length of pairs will not exceed 2000.\n * The length of each pairs[i] will be 2.\n * The length of each words[i] and pairs[i][j] will be in the range [1, 20].\n */\n\npublic class SentenceSimilarityII737 {\n    public boolean areSentencesSimilarTwo(String[] words1, String[] words2, String[][] pairs) {\n        if (words1.length != words2.length) return false;\n        DisjointSet djs = new DisjointSet(pairs);\n        \n        int len = words1.length;\n        for (int i=0; i<len; i++) {\n            String w1 = words1[i];\n            String w2 = words2[i];\n            if (w1.equals(w2)) continue;\n            String p1 = djs.find(w1);\n            String p2 = djs.find(w2);\n            if (p1 == null || p2 == null || !p1.equals(p2)) return false;\n        }\n        return true;\n        \n    }\n\n    class DisjointSet {\n        Map<String, String> parent = new HashMap<>();\n        Map<String, Integer> rank = new HashMap<>();\n        \n        public DisjointSet(String[][] pairs) {\n            for (String[] pair: pairs) {\n                if (!parent.containsKey(pair[0])) {\n                    parent.put(pair[0], pair[0]);\n                    rank.put(pair[0], 0);\n                }\n                if (!parent.containsKey(pair[1])) {\n                    parent.put(pair[1], pair[1]);\n                    rank.put(pair[1], 0);\n                }\n                union(pair[0], pair[1]);\n            }\n        }\n\n        public String find(String word) {\n            if (parent.containsKey(word) && !parent.get(word).equals(word)) {\n                parent.put(word, find(parent.get(word)));\n            }\n            return parent.get(word);\n        }\n        \n        public void union(String w1, String w2) {\n            String p1 = find(w1);\n            String p2 = find(w2);\n            \n            int r1 = rank.get(p1);\n            int r2 = rank.get(p2);\n            if (r1 > r2) {\n                parent.put(p2, p1);\n            } else if (r1 < r2) {\n                parent.put(p1, p2);\n            } else {\n                parent.put(p1, p2);\n                rank.put(p2, r2+1);\n            }\n        }\n        \n    }\n\n\n    /**\n     * https://leetcode.com/problems/sentence-similarity-ii/solution/\n     */\n    public boolean areSentencesSimilarTwo2(String[] words1, String[] words2, String[][] pairs) {\n        if (words1.length != words2.length) return false;\n        Map<String, Integer> index = new HashMap();\n        int count = 0;\n        DSU dsu = new DSU(2 * pairs.length);\n        for (String[] pair: pairs) {\n            for (String p: pair) if (!index.containsKey(p)) {\n                index.put(p, count++);\n            }\n            dsu.union(index.get(pair[0]), index.get(pair[1]));\n        }\n\n        for (int i = 0; i < words1.length; ++i) {\n            String w1 = words1[i], w2 = words2[i];\n            if (w1.equals(w2)) continue;\n            if (!index.containsKey(w1) || !index.containsKey(w2) ||\n                    dsu.find(index.get(w1)) != dsu.find(index.get(w2)))\n                return false;\n        }\n        return true;\n    }\n\n    class DSU {\n        int[] parent;\n        public DSU(int N) {\n            parent = new int[N];\n            for (int i = 0; i < N; ++i)\n                parent[i] = i;\n        }\n        public int find(int x) {\n            if (parent[x] != x) parent[x] = find(parent[x]);\n            return parent[x];\n        }\n        public void union(int x, int y) {\n            parent[find(x)] = find(y);\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/SerializeAndDeserializeBST449.java",
    "content": "/**\n * Serialization is the process of converting a data structure or object into a\n * sequence of bits so that it can be stored in a file or memory buffer, or\n * transmitted across a network connection link to be reconstructed later in\n * the same or another computer environment.\n * \n * Design an algorithm to serialize and deserialize a binary search tree. There\n * is no restriction on how your serialization/deserialization algorithm should\n * work. You just need to ensure that a binary search tree can be serialized to\n * a string and this string can be deserialized to the original tree structure.\n * \n * The encoded string should be as compact as possible.\n * \n * Note: Do not use class member/global/static variables to store states. Your\n * serialize and deserialize algorithms should be stateless.\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class SerializeAndDeserializeBST449 {\n    // Level-Order, BFS, Iteratively\n    class Codec {\n        // Encodes a tree to a single string.\n        public String serialize(TreeNode root) {\n            Queue<TreeNode> q = new LinkedList<>();\n            StringBuilder sb = new StringBuilder();\n            q.add(root);\n            while (!q.isEmpty()) {\n                TreeNode curr = q.poll();\n                if (curr == null) {\n                    sb.append(\"#,\");\n                } else {\n                    sb.append(curr.val + \",\");\n                    q.add(curr.left);\n                    q.add(curr.right);\n                }\n            }\n            return sb.substring(0, sb.length()-1).toString();\n        }\n\n        // Decodes your encoded data to tree.\n        public TreeNode deserialize(String data) {\n            String[] strs = data.split(\",\");\n            TreeNode root = strs[0].equals(\"#\") ? null : new TreeNode(Integer.valueOf(strs[0]));\n            Queue<TreeNode> q = new LinkedList<>();\n            q.add(root);\n            int i = 1;\n            while (i<=strs.length-2) {\n                TreeNode p = q.poll();\n                if (p != null) {\n                    TreeNode left = strs[i].equals(\"#\") ? null : new TreeNode(Integer.valueOf(strs[i]));\n                    TreeNode right = strs[i+1].equals(\"#\") ? null : new TreeNode(Integer.valueOf(strs[i+1]));\n                    p.left = left;\n                    p.right = right;\n                    q.add(left);\n                    q.add(right);\n                    i += 2;\n                }\n            }\n            return root;\n        }\n    }\n\n    // Pre-Order, DFS, Resursively\n    class Codec2 {\n        // Encodes a tree to a single string.\n        public String serialize2(TreeNode root) {\n            if (root == null) return \"\";\n            StringBuilder sb = new StringBuilder();\n            serialize(root, sb);\n            return sb.substring(0, sb.length()-1).toString();\n        }\n\n        private void serialize(TreeNode root, StringBuilder sb) {\n            if (root == null) return;\n            sb.append(root.val + \",\");\n            serialize(root.left, sb);\n            serialize(root.right, sb);\n        }\n\n        // Decodes your encoded data to tree.\n        public TreeNode deserialize2(String data) {\n            String[] strs = data.split(\",\");\n            if (strs.length == 0 || strs[0].equals(\"\")) return null;\n            return deserialize(strs, 0, strs.length-1);\n        }\n        \n        private TreeNode deserialize(String[] strs, int lo, int hi) {\n            if (lo > hi) return null;\n            if (lo == hi) return new TreeNode(Integer.valueOf(strs[lo]));\n            int rootVal = Integer.valueOf(strs[lo]);\n            TreeNode root = new TreeNode(Integer.valueOf(strs[lo]));\n            int rightIdx = rightStart(strs, lo+1, hi, rootVal);\n            root.left = deserialize(strs, lo+1, rightIdx-1);\n            root.right = deserialize(strs, rightIdx, hi);\n            return root;\n        }\n\n        private int rightStart(String[] strs, int lo, int hi, int rootVal) {\n            for (int i=lo; i<=hi; i++) {\n                if (Integer.valueOf(strs[i]) > rootVal) return i;\n            }\n            return hi+1;\n        }\n    }\n\n    // https://leetcode.com/problems/serialize-and-deserialize-bst/discuss/93175/Java-PreOrder-+-Queue-solution\n    // Pre-Order, DFS, Iteratively\n    class Codec3 {\n        private static final String SEP = \",\";\n        private static final String NULL = \"null\";\n        // Encodes a tree to a single string.\n        public String serialize(TreeNode root) {\n            StringBuilder sb = new StringBuilder();\n            if (root == null) return NULL;\n            //traverse it recursively if you want to, I am doing it iteratively here\n            Stack<TreeNode> st = new Stack<>();\n            st.push(root);\n            while (!st.empty()) {\n                root = st.pop();\n                sb.append(root.val).append(SEP);\n                if (root.right != null) st.push(root.right);\n                if (root.left != null) st.push(root.left);\n            }\n            return sb.toString();\n        }\n    \n        // Decodes your encoded data to tree.\n        // pre-order traversal\n        public TreeNode deserialize(String data) {\n            if (data.equals(NULL)) return null;\n            String[] strs = data.split(SEP);\n            Queue<Integer> q = new LinkedList<>();\n            for (String e : strs) {\n                q.offer(Integer.parseInt(e));\n            }\n            return getNode(q);\n        }\n        \n        // some notes:\n        //   5\n        //  3 6\n        // 2   7\n        private TreeNode getNode(Queue<Integer> q) { //q: 5,3,2,6,7\n            if (q.isEmpty()) return null;\n            TreeNode root = new TreeNode(q.poll());//root (5)\n            Queue<Integer> samllerQueue = new LinkedList<>();\n            while (!q.isEmpty() && q.peek() < root.val) {\n                samllerQueue.offer(q.poll());\n            }\n            //smallerQueue : 3,2   storing elements smaller than 5 (root)\n            root.left = getNode(samllerQueue);\n            //q: 6,7   storing elements bigger than 5 (root)\n            root.right = getNode(q);\n            return root;\n        }\n        \n    }\n\n    // https://leetcode.com/problems/serialize-and-deserialize-bst/discuss/93170/pre-or-post-order-with-only-keeping-one-bound(beat-98-and-95)\n    // Pre-Order, DFS, Resursively\n    class Codec4 {\n\n        // Encodes a tree to a single string.\n        public String serialize(TreeNode root) {\n            if (root == null) {\n                return null;\n            }\n            StringBuilder sb = new StringBuilder();\n            serialize(root, sb);\n            return sb.toString();\n        }\n        \n        private void serialize(TreeNode root, StringBuilder sb) {\n            if (root == null) {\n                return;\n            }\n            sb.append(root.val).append(\" \");\n            serialize(root.left, sb);\n            serialize(root.right, sb);\n        }\n        \n        // Decodes your encoded data to tree.\n        public TreeNode deserialize(String data) {\n            if (data == null || data.length() == 0) {\n                return null;\n            }\n            String[] nodes = data.split(\" \");\n            int[] index = new int[] {0};\n            return deserialize(nodes, index, Integer.MAX_VALUE);\n        }\n        \n        private TreeNode deserialize(String[] nodes, int[] index, int max) {\n            if (index[0] >= nodes.length || Integer.valueOf(nodes[index[0]]) >= max) {\n                return null;\n            }\n            TreeNode root = new TreeNode(Integer.valueOf(nodes[index[0]++]));\n            root.left = deserialize(nodes, index, root.val);\n            root.right = deserialize(nodes, index, max);\n            return root;\n        }\n    }\n\n    // https://leetcode.com/problems/serialize-and-deserialize-bst/discuss/93170/pre-or-post-order-with-only-keeping-one-bound(beat-98-and-95)\n    // Post-Order, DFS, Resursively\n    class Codec5 {\n\n        // Encodes a tree to a single string.\n        public String serialize(TreeNode root) {\n            if (root == null) {\n                return null;\n            }\n            StringBuilder sb = new StringBuilder();\n            serialize(root, sb);\n            return sb.toString();\n        }\n        \n        private void serialize(TreeNode root, StringBuilder sb) {\n            if (root == null) {\n                return;\n            }\n            serialize(root.left, sb);\n            serialize(root.right, sb);\n            sb.append(Integer.valueOf(root.val)).append(\" \");\n        }\n        \n        // Decodes your encoded data to tree.\n        public TreeNode deserialize(String data) {\n            if (data == null || data.length() == 0) {\n                return null;\n            }\n            String[] nodes = data.split(\" \");\n            int[] index = new int[] {nodes.length - 1};\n            return deserialize(nodes, index, Integer.MIN_VALUE);\n        }\n        \n        private TreeNode deserialize(String[] nodes, int[] index, int min) {\n            if (index[0] < 0 || Integer.valueOf(nodes[index[0]]) <= min) {\n                return null;\n            }\n            TreeNode root = new TreeNode(Integer.valueOf(nodes[index[0]--]));\n            root.right = deserialize(nodes, index, root.val);\n            root.left = deserialize(nodes, index, min);\n            return root;\n        }\n    }\n\n    // Your Codec object will be instantiated and called as such:\n    // Codec codec = new Codec();\n    // codec.deserialize(codec.serialize(root));\n\n}\n\n\n"
  },
  {
    "path": "src/SerializeAndDeserializeBinaryTree297.java",
    "content": "/**\n * Serialization is the process of converting a data structure or object into a\n * sequence of bits so that it can be stored in a file or memory buffer, or\n * transmitted across a network connection link to be reconstructed later in the\n * same or another computer environment.\n *\n * Design an algorithm to serialize and deserialize a binary tree. There is no\n * restriction on how your serialization/deserialization algorithm should work.\n * You just need to ensure that a binary tree can be serialized to a string and\n * this string can be deserialized to the original tree structure.\n *\n * For example, you may serialize the following tree\n *\n *     1\n *    / \\\n *   2   3\n *      / \\\n *     4   5\n * as \"[1,2,3,null,null,4,5]\", just the same as how LeetCode OJ serializes a\n * binary tree (https://leetcode.com/faq/#binary-tree). You do not necessarily\n * need to follow this format, so please be creative and come up with different\n * approaches yourself.\n *\n * Note: Do not use class member/global/static variables to store states. Your\n * serialize and deserialize algorithms should be stateless.\n *\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class SerializeAndDeserializeBinaryTree297 {\n    class Codec {\n        // Encodes a tree to a single string.\n        public String serialize(TreeNode root) {\n            if (root == null) return \"[]\";\n            StringBuilder sb = new StringBuilder();\n            sb.append('[');\n\n            Queue<TreeNode> q = new LinkedList<>();\n            q.add(root);\n            int nulls = 0;\n            while (!q.isEmpty()) {\n                TreeNode n = q.remove();\n                if (n == null) {\n                    nulls++;\n                    sb.append(\"null,\");\n                } else {\n                    nulls = 0;\n                    sb.append(n.val + \",\");\n                    q.add(n.left);\n                    q.add(n.right);\n                }\n            }\n\n            while (nulls > 0) {\n                sb.delete(sb.length()-5, sb.length());\n                nulls--;\n            }\n\n            sb.setCharAt(sb.length()-1, ']');\n            return sb.toString();\n        }\n\n        // Decodes your encoded data to tree.\n        public TreeNode deserialize(String data) {\n            String[] nums = data.substring(1, data.length()-1).split(\",\");\n            if (nums.length <= 0 || nums[0].equals(\"\")) return null;\n            TreeNode res = new TreeNode(Integer.valueOf(nums[0]));\n\n            Queue<TreeNode> q = new LinkedList<>();\n            q.add(res);\n            int i = 1;\n            while (i < nums.length) {\n                int add = 1;\n                TreeNode parent = q.remove();\n                TreeNode left = null;\n                if (!nums[i].equals(\"null\")) {\n                    left = new TreeNode(Integer.valueOf(nums[i]));\n                    q.add(left);\n                }\n\n                TreeNode right = null;\n                if (i+1 < nums.length) {\n                    add++;\n                    if (!nums[i+1].equals(\"null\")) {\n                        right = new TreeNode(Integer.valueOf(nums[i+1]));\n                        q.add(right);\n                    }\n                }\n\n                parent.left = left;\n                parent.right = right;\n                i += add;\n            }\n\n            return res;\n        }\n    }\n}\n\n// Your Codec object will be instantiated and called as such:\n// Codec codec = new Codec();\n// codec.deserialize(codec.serialize(root));\n\n\n\n// // preorder, DFS\n// public class Codec {\n//\n//     // Encodes a tree to a single string.\n//     public String serialize(TreeNode root) {\n//         StringBuilder sb = new StringBuilder();\n//         serialize(root, sb);\n//         System.out.println(sb.toString());\n//         return sb.toString();\n//     }\n//\n//     private void serialize(TreeNode root, StringBuilder sb) {\n//         if (root == null) {\n//             sb.append('N').append(',');\n//         } else {\n//             sb.append(root.val).append(',');\n//             serialize(root.left, sb);\n//             serialize(root.right, sb);\n//         }\n//     }\n//\n//     // Decodes your encoded data to tree.\n//     public TreeNode deserialize(String data) {\n//         return deserialize(data.split(\",\"), new int[]{0});\n//     }\n//\n//     public TreeNode deserialize(String[] data, int[] is) {\n//         if (is[0] >= data.length) return null;\n//         String val = data[is[0]];\n//         is[0]++;\n//         if (val.equals(\"N\")) {\n//             return null;\n//         } else {\n//             TreeNode node = new TreeNode(Integer.valueOf(val));\n//             node.left = deserialize(data, is);\n//             node.right = deserialize(data, is);\n//             return node;\n//         }\n//     }\n// }\n"
  },
  {
    "path": "src/SetMatrixZeroes73.java",
    "content": "/**\n * Given a m x n matrix, if an element is 0, set its entire row and column\n * to 0. Do it in place.\n *\n * Follow up:\n * Did you use extra space?\n * A straight forward solution using O(mn) space is probably a bad idea.\n * A simple improvement uses O(m + n) space, but still not the best solution.\n * Could you devise a constant space solution?\n */\n\npublic class SetMatrixZeroes73 {\n    public void setZeroes(int[][] matrix) {\n        boolean[] rows = new boolean[matrix.length];\n        boolean[] cols = new boolean[matrix[0].length];\n\n        for (int i=0; i<matrix.length; i++) {\n            for (int j=0; j<matrix[0].length; j++) {\n                if (matrix[i][j] == 0) {\n                    rows[i] = true;\n                    cols[j] = true;\n                }\n            }\n        }\n\n        for (int i=0; i<matrix.length; i++) {\n            for (int j=0; j<matrix[0].length; j++) {\n                if (rows[i] || cols[j]) matrix[i][j] = 0;\n            }\n        }\n\n    }\n\n    /**\n     * https://leetcode.com/problems/set-matrix-zeroes/discuss/26008/My-AC-java-O(1)-solution-(easy-to-read)\n     */\n    public void setZeroes2(int[][] matrix) {\n        boolean fr = false,fc = false;\n        for(int i = 0; i < matrix.length; i++) {\n            for(int j = 0; j < matrix[0].length; j++) {\n                if(matrix[i][j] == 0) {\n                    if(i == 0) fr = true;\n                    if(j == 0) fc = true;\n                    matrix[0][j] = 0;\n                    matrix[i][0] = 0;\n                }\n            }\n        }\n        for(int i = 1; i < matrix.length; i++) {\n            for(int j = 1; j < matrix[0].length; j++) {\n                if(matrix[i][0] == 0 || matrix[0][j] == 0) {\n                    matrix[i][j] = 0;\n                }\n            }\n        }\n        if(fr) {\n            for(int j = 0; j < matrix[0].length; j++) {\n                matrix[0][j] = 0;\n            }\n        }\n        if(fc) {\n            for(int i = 0; i < matrix.length; i++) {\n                matrix[i][0] = 0;\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/ShortestBridge934.java",
    "content": "/**\n * In a given 2D binary array A, there are two islands.  (An island is a 4-directionally\n * connected group of 1s not connected to any other 1s.)\n * \n * Now, we may change 0s to 1s so as to connect the two islands together to form 1 island.\n * \n * Return the smallest number of 0s that must be flipped.  (It is guaranteed that the answer is at least 1.)\n * \n * Example 1:\n * Input: [[0,1],[1,0]]\n * Output: 1\n * \n * Example 2:\n * Input: [[0,1,0],[0,0,0],[0,0,1]]\n * Output: 2\n * \n * Example 3:\n * Input: [[1,1,1,1,1],[1,0,0,0,1],[1,0,1,0,1],[1,0,0,0,1],[1,1,1,1,1]]\n * Output: 1\n * \n * Note:\n * 1 <= A.length = A[0].length <= 100\n * A[i][j] == 0 or A[i][j] == 1\n */\n\npublic class ShortestBridge934 {\n    private int[][] DIR = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};\n    public int shortestBridge(int[][] A) {\n        int m = A.length;\n        int n = A[0].length;\n        boolean[][] visited = new boolean[m][n];\n        Queue<int[]> edge = findOneIslandEdge(A, visited);\n        int res = 0;\n        while (!edge.isEmpty()) {\n            int len = edge.size();\n            for (int i=0; i<len; i++) {\n                int[] curr = edge.remove();\n                for (int k=0; k<4; k++) {\n                    int ii = curr[0] + DIR[k][0];\n                    int jj = curr[1] + DIR[k][1];\n                    if (ii >= 0 && ii < m && jj >= 0 && jj < n && !visited[ii][jj]) {\n                        if (A[ii][jj] == 0) {\n                            edge.add(new int[]{ii, jj});\n                            visited[ii][jj] = true;\n                        } else {\n                            return res;\n                        }\n                    }\n                }\n            }\n            res++;\n        }\n        return res;\n    }\n    \n    private Queue<int[]> findOneIslandEdge(int[][] A, boolean[][] visited) {\n        int m = A.length;\n        int n = A[0].length;\n        for (int i=0; i<m; i++) {\n            for (int j=0; j<n; j++) {\n                if (A[i][j] == 1) {\n                    return collectEdge(A, i, j, visited);\n                }\n            }\n        }\n        return null;\n    }\n    \n    private Queue<int[]> collectEdge(int[][] A, int si, int sj, boolean[][] visited) {\n        Queue<int[]> edge = new LinkedList<>();\n        Queue<int[]> q = new LinkedList<>();\n        int m = A.length;\n        int n = A[0].length;\n        visited[si][sj] = true;\n        q.add(new int[]{si, sj});\n        while (!q.isEmpty()) {\n            int[] curr = q.remove();\n            boolean isEdge = false;\n            for (int k=0; k<4; k++) {\n                int ii = curr[0] + DIR[k][0];\n                int jj = curr[1] + DIR[k][1];\n                if (ii >= 0 && ii < m && jj >= 0 && jj < n && !visited[ii][jj]) {\n                    if (A[ii][jj] == 0) {\n                        isEdge = true;\n                    } else {\n                        q.add(new int[]{ii, jj});\n                        visited[ii][jj] = true;\n                    }\n                }\n            }\n            if (isEdge) {\n                edge.add(curr);\n            }\n        }\n        return edge;\n    }\n}\n"
  },
  {
    "path": "src/ShortestCompletingWord748.java",
    "content": "/**\n * Find the minimum length word from a given dictionary words, which has all\n * the letters from the string licensePlate. Such a word is said to complete\n * the given string licensePlate\n * \n * Here, for letters we ignore case. For example, \"P\" on the licensePlate still \n * matches \"p\" on the word.\n * \n * It is guaranteed an answer exists. If there are multiple answers, return the\n * one that occurs first in the array.\n * \n * The license plate might have the same letter occurring multiple times. For\n * example, given a licensePlate of \"PP\", the word \"pair\" does not complete the\n * licensePlate, but the word \"supper\" does.\n * \n * Example 1:\n * Input: licensePlate = \"1s3 PSt\", words = [\"step\", \"steps\", \"stripe\", \"stepple\"]\n * Output: \"steps\"\n * Explanation: The smallest length word that contains the letters \"S\", \"P\",\n * \"S\", and \"T\".\n * Note that the answer is not \"step\", because the letter \"s\" must occur in the\n * word twice. Also note that we ignored case for the purposes of comparin\n * whether a letter exists in the word.\n * \n * Example 2:\n * Input: licensePlate = \"1s3 456\", words = [\"looks\", \"pest\", \"stew\", \"show\"]\n * Output: \"pest\"\n * Explanation: There are 3 smallest length words that contains the letters \"s\".\n * We return the one that occurred first.\n * \n * Note:\n * licensePlate will be a string with length in range [1, 7].\n * licensePlate will contain digits, spaces, or letters (uppercase or lowercase).\n * words will have a length in the range [10, 1000].\n * Every words[i] will consist of lowercase letters, and have length in range [1, 15].\n */\n\nclass ShortestCompletingWord748 {\n  public String shortestCompletingWord(String licensePlate, String[] words) {\n      int[] charMap = new int[26];\n      for (char c: licensePlate.toCharArray()) {\n          if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {\n              char lowerC = Character.toLowerCase(c);\n              charMap[lowerC - 'a'] += 1;\n          }\n      }\n\n      String res = \"\";\n      int len = Integer.MAX_VALUE;\n      for (String word: words) {\n          int[] map = new int[26];\n          for (char c: word.toCharArray()) map[c - 'a'] += 1;\n          boolean match = true;\n          for (int i=0; i<26; i++) {\n              if (map[i] < charMap[i]) {\n                  match = false;\n                  break;\n              }\n          }\n          if (match && word.length() < len) {\n              res = word;\n              len = word.length();\n          }\n      }\n\n      return res;\n  }\n}"
  },
  {
    "path": "src/ShortestDistanceFromAllBuildings317.java",
    "content": "/**\n * You want to build a house on an empty land which reaches all buildings in\n * the shortest amount of distance. You can only move up, down, left and right.\n * You are given a 2D grid of values 0, 1 or 2, where:\n * \n * Each 0 marks an empty land which you can pass by freely.\n * Each 1 marks a building which you cannot pass through.\n * Each 2 marks an obstacle which you cannot pass through.\n * \n * Example:\n * \n * Input: [[1,0,2,0,1],[0,0,0,0,0],[0,0,1,0,0]]\n * \n * 1 - 0 - 2 - 0 - 1\n * |   |   |   |   |\n * 0 - 0 - 0 - 0 - 0\n * |   |   |   |   |\n * 0 - 0 - 1 - 0 - 0\n * \n * Output: 7 \n * \n * Explanation: Given three buildings at (0,0), (0,4), (2,2), and an obstacle\n *    at (0,2), the point (1,2) is an ideal empty land to build a house, as\n *    the total travel distance of 3+3+1=7 is minimal. So return 7.\n * \n * Note:\n * There will be at least one building. If it is not possible to build such\n * house according to the above rules, return -1.\n */\n\n\npublic class ShortestDistanceFromAllBuildings317 {\n    private int[][] dirs = new int[][]{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};\n\n    public int shortestDistance(int[][] grid) {\n        if (grid == null) return -1;\n        int m = grid.length;\n        int n = grid[0].length;\n        if (m == 0 || n == 0 || (m == 1 && n == 1)) return -1;\n\n        int numBuildings = 0;\n        int[][] reached = new int[m][n];\n        int[][] allDists = new int[m][n];\n        for (int i=0; i<m; i++) {\n            for (int j=0; j<n; j++) {\n                if (grid[i][j] == 1) {\n                    numBuildings++;\n                    int[][] dist = new int[m][n];\n                    boolean[][] visited = new boolean[m][n];\n                    dfs(grid, dist, allDists, visited, reached, 0, i, j, m, n);\n                }\n            }\n        }\n        if (numBuildings == 0) return -1;\n        int res = Integer.MAX_VALUE;\n        for (int i=0; i<m; i++) {\n            for (int j=0; j<n; j++) {\n                if (grid[i][j] == 0 && reached[i][j] == numBuildings) {\n                    res = Math.min(res, allDists[i][j]);\n                }\n            }\n        }\n        \n        \n        return res == Integer.MAX_VALUE ? -1 : res;\n    }\n\n    private void dfs(int[][] grid, int[][] dist, int[][] allDists, boolean[][] visited, int[][] reached, int d, int i, int j, int m, int n) {\n        if (i < 0 || j < 0 || i >= m || j >= n || (grid[i][j] == 1 && d != 0) || grid[i][j] == 2) return;\n        if (visited[i][j] && dist[i][j] <= d) return;\n        if (!visited[i][j]) {\n            reached[i][j]++;\n        } else {\n            allDists[i][j] -= dist[i][j];\n        }\n        allDists[i][j] += d;\n        dist[i][j] = d;\n        visited[i][j] = true;\n        for (int[] dir: dirs) {\n            dfs(grid, dist, allDists, visited, reached, d+1, i+dir[0], j+dir[1], m, n);\n        }\n    }\n\n\n    public int shortestDistance2(int[][] grid) {\n        if (grid == null) return -1;\n        int m = grid.length;\n        int n = grid[0].length;\n        if (m == 0 || n == 0 || (m == 1 && n == 1)) return -1;\n\n        int numBuildings = 0;\n        int[][] reached = new int[m][n];\n        int[][] allDists = new int[m][n];\n        for (int i=0; i<m; i++) {\n            for (int j=0; j<n; j++) {\n                if (grid[i][j] == 1) {\n                    numBuildings++;\n                    bfs(grid, reached, allDists, i, j, m, n);\n                }\n            }\n        }\n        \n        if (numBuildings == 0) return -1;\n        int res = Integer.MAX_VALUE;\n        for (int i=0; i<m; i++) {\n            for (int j=0; j<n; j++) {\n                if (grid[i][j] == 0 && reached[i][j] == numBuildings) {\n                    res = Math.min(res, allDists[i][j]);\n                }\n            }\n        }\n        \n        return res == Integer.MAX_VALUE ? -1 : res;\n    }\n\n    private void bfs(int[][] grid, int[][] reached, int[][] allDists, int x, int y, int m, int n) {\n        boolean[][] added = new boolean[m][n];\n        \n        Queue<Point> q = new LinkedList<>();\n        for (int[] dir: dirs) {\n            int i = x + dir[0];\n            int j = y + dir[1];\n            if (i < 0 || j < 0 || i >= m || j >= n || grid[i][j] == 1 || grid[i][j] == 2) continue;\n            q.add(new Point(i, j));\n            added[i][j] = true;\n        }\n        int d = 0;\n        while (!q.isEmpty()) {\n            d++;\n            int size = q.size();\n            for (int k=0; k<size; k++) {\n                Point p = q.remove();\n                int i = p.x;\n                int j = p.y;\n                allDists[i][j] += d;\n                reached[i][j]++;\n                for (int[] dir: dirs) {\n                    int ii = i + dir[0];\n                    int jj = j + dir[1];\n                    if (ii < 0 || jj < 0 || ii >= m || jj >= n ||\n                        grid[ii][jj] == 1 || grid[ii][jj] == 2 || added[ii][jj]) continue;\n                    q.add(new Point(ii, jj));\n                    added[ii][jj] = true;\n                }\n            }\n        }\n        \n    }\n    \n    class Point {\n        int x;\n        int y;\n        Point(int i, int j) {\n            x = i;\n            y = j;\n        }\n    }\n\n}\n\n"
  },
  {
    "path": "src/ShortestPalindrome214.java",
    "content": "/**\n * Given a string s, you are allowed to convert it to a palindrome by adding\n * characters in front of it. Find and return the shortest palindrome you can\n * find by performing this transformation.\n * \n * Example 1:\n * Input: \"aacecaaa\"\n * Output: \"aaacecaaa\"\n * \n * Example 2:\n * Input: \"abcd\"\n * Output: \"dcbabcd\"\n */\n\n\npublic class ShortestPalindrome214 {\n    public String shortestPalindrome(String s) {\n        int len = s.length();\n        if (len <= 1) return s;\n        String res = null;\n        char[] chars = s.toCharArray();\n        for (int r=len-1; r>=0; r--) {\n            if (shortestPalindrome(chars, 0, r)) {\n                StringBuilder sb = new StringBuilder();\n                for (int i=len-1; i>r; i--) {\n                    sb.append(chars[i]);\n                }\n                sb.append(chars);\n                return sb.toString();\n            }\n        }\n        return \"\";\n    }\n    \n    private boolean shortestPalindrome(char[] chars, int left, int right) {\n        while (left < right) {\n            if (chars[left] != chars[right]) return false;\n            left++;\n            right--;\n        }\n        return true;\n    }\n\n\n    public String shortestPalindrome2(String s) {\n        int len = s.length();\n        if (len <= 1) return s;\n        String rev = new StringBuilder(s).reverse().toString();\n        char[] chars = (s + \"#\" + rev).toCharArray();\n        int[] prefix = prefix(chars);\n        return  rev.substring(0, len - prefix[prefix.length - 1]) + s;\n    }\n    \n    private int[] prefix(char[] chars) {\n        int len = chars.length;\n        int[] res = new int[len];\n        res[0] = 0;\n        for (int i=1; i<len; i++) {\n            int j = res[i-1];\n            while (j > 0 && chars[i] != chars[j]) {\n                j = res[j-1];\n            }\n            if (chars[i] == chars[j]) {\n                j++;\n            }\n            res[i] = j;\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/ShortestPathToGetAllKeys864.java",
    "content": "/**\n * We are given a 2-dimensional grid. \".\" is an empty cell, \"#\" is a wall, \"@\"\n * is the starting point, (\"a\", \"b\", ...) are keys, and (\"A\", \"B\", ...) are\n * locks.\n * \n * We start at the starting point, and one move consists of walking one space\n * in one of the 4 cardinal directions.  We cannot walk outside the grid, or\n * walk into a wall.  If we walk over a key, we pick it up.  We can't walk over\n * a lock unless we have the corresponding key.\n * \n * For some 1 <= K <= 6, there is exactly one lowercase and one uppercase\n * letter of the first K letters of the English alphabet in the grid. This\n * means that there is exactly one key for each lock, and one lock for each\n * key; and also that the letters used to represent the keys and locks were\n * chosen in the same order as the English alphabet.\n * \n * Return the lowest number of moves to acquire all keys.\n * If it's impossible, return -1.\n * \n * Example 1:\n * Input: [\"@.a.#\",\"###.#\",\"b.A.B\"]\n * Output: 8\n * \n * Example 2:\n * Input: [\"@..aA\",\"..B#.\",\"....b\"]\n * Output: 6\n * \n * Note:\n * 1 <= grid.length <= 30\n * 1 <= grid[0].length <= 30\n * grid[i][j] contains only '.', '#', '@', 'a'-'f' and 'A'-'F'\n * The number of keys is in [1, 6].\n * Each key has a different letter and opens exactly one lock.\n */\n\npublic class ShortestPathToGetAllKeys864 {\n    private int[][] directions = new int[][]{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};\n\n    public int shortestPathAllKeys(String[] grid) {\n        int M = grid.length;\n        int N = grid[0].length();\n        char[][] maze = new char[M][N];\n        int numKeys = 0;\n        int[] start = new int[2];\n        for (int i=0; i<M; i++) {\n            char[] row = grid[i].toCharArray();\n            for (int j=0; j<N; j++) {\n                maze[i][j] = row[j];\n                if (row[j] == '@') {\n                    start[0] = i;\n                    start[1] = j;\n                } else if (row[j] >= 'a' && row[j] <= 'f') {\n                    numKeys++;\n                }\n            }\n        }\n\n        int[] res = new int[]{Integer.MAX_VALUE};\n        Set<Character> keySet = new HashSet<>();\n        helper(maze, start, numKeys, keySet, 0, M, N, res);\n        return res[0] == Integer.MAX_VALUE ? -1 : res[0];\n    }\n\n    public void helper(char[][] maze, int[] start, int numKeys, Set<Character> keySet, int steps, int M, int N, int[] res) {\n        if (numKeys == keySet.size()) {\n            res[0] = Math.min(res[0], steps);\n            return;\n        }\n        boolean[][] visited = new boolean[M][N];\n        Queue<int[]> q = new LinkedList<>();\n        q.add(start);\n        visited[start[0]][start[1]] = true;\n        Set<int[]> newKeys = new HashSet<>();\n        int level = 1;\n        while (!q.isEmpty() && steps + level < res[0]) {\n            int size = q.size();\n            for (int i=0; i<size; i++) {\n                int[] curr = q.poll();\n                for (int[] dir: directions) {\n                    int x = curr[0] + dir[0];\n                    int y = curr[1] + dir[1];\n                    if (x < 0 || y < 0 || x >= M || y >= N) continue;\n                    char next = maze[x][y];\n                    if (next == '#' || visited[x][y]) continue;\n                    if (next == '@' || next == '.') {\n                        q.add(new int[]{x, y});\n                        visited[x][y] = true;\n                    } else if (next >= 'a' && next <= 'f') {\n                        if (!keySet.contains(next)) {\n                            newKeys.add(new int[]{x, y, level});\n                        } else {\n                            q.add(new int[]{x, y});\n                            visited[x][y] = true;\n                        }\n                    } else if (next >= 'A' && next <= 'F') {\n                        if (keySet.contains(Character.toLowerCase(next))) {\n                            q.add(new int[]{x, y});\n                            visited[x][y] = true;\n                        }\n                    }\n                }\n            }\n            level++;\n        }\n\n        if (!newKeys.isEmpty()) {\n            for (int[] newKey: newKeys) {\n                int[] newKeyPos = new int[]{newKey[0], newKey[1]};\n                char key = maze[newKey[0]][newKey[1]];\n                keySet.add(key);\n                helper(maze, newKeyPos, numKeys, keySet, steps + newKey[2], M, N, res);\n                keySet.remove(key);\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/ShortestSubarrayWithSumAtLeastK862.java",
    "content": "/**\n * Return the length of the shortest, non-empty, contiguous subarray of A with\n * sum at least K.\n * \n * If there is no non-empty subarray with sum at least K, return -1.\n *\n * Example 1:\n * Input: A = [1], K = 1\n * Output: 1\n * \n * Example 2:\n * Input: A = [1,2], K = 4\n * Output: -1\n * \n * Example 3:\n * Input: A = [2,-1,2], K = 3\n * Output: 3\n * \n * Note:\n * 1 <= A.length <= 50000\n * -10 ^ 5 <= A[i] <= 10 ^ 5\n * 1 <= K <= 10 ^ 9\n */\n\npublic class ShortestSubarrayWithSumAtLeastK862 {\n    public int shortestSubarray(int[] A, int K) {\n        int res = Integer.MAX_VALUE;\n        int sum = 0;\n        Map<Integer, Integer> map = new HashMap<>();\n        List<Integer> list = new ArrayList<>();\n        list.add(0);\n        map.put(0, -1);\n        for (int i=0; i<A.length; i++) {\n            sum += A[i];\n            int remain = sum - K;\n            int idx = Collections.binarySearch(list, remain);\n            if (idx < 0) idx = - (idx + 1) - 1;\n            if (idx >= 0) {\n                int val = list.get(idx);\n                if (sum - val >= K && i - map.get(val) < res) {\n                    res = i - map.get(val);\n                }\n            }\n            \n            while (!list.isEmpty() && list.get(list.size() - 1) >= sum) {\n                int val = list.remove(list.size()-1);\n            }\n            list.add(sum);\n            map.put(sum, i);\n        }\n        return res == Integer.MAX_VALUE ? -1 : res;\n    }\n\n\n    public int shortestSubarray2(int[] A, int K) {\n        int res = Integer.MAX_VALUE;\n        int sum = 0;\n        Map<Integer, Integer> map = new HashMap<>();\n        LinkedList<Integer> list = new LinkedList<>();\n        list.add(0);\n        map.put(0, -1);\n        for (int i=0; i<A.length; i++) {\n            sum += A[i];\n            int remain = sum - K;\n            \n            while (!list.isEmpty() && sum - list.getFirst() >= K) {\n                int val = list.removeFirst();\n                if (i - map.get(val) < res) {\n                    res = i - map.get(val);\n                }\n                map.remove(val);\n            }\n            \n            while (!list.isEmpty() && list.getLast() >= sum) {\n                int val = list.removeLast();\n                map.remove(val);\n            }\n            list.add(sum);\n            map.put(sum, i);\n        }\n        return res == Integer.MAX_VALUE ? -1 : res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/shortest-subarray-with-sum-at-least-k/solution/\n     */\n    public int shortestSubarray3(int[] A, int K) {\n        int N = A.length;\n        long[] P = new long[N+1];\n        for (int i = 0; i < N; ++i)\n            P[i+1] = P[i] + (long) A[i];\n\n        // Want smallest y-x with P[y] - P[x] >= K\n        int ans = N+1; // N+1 is impossible\n        Deque<Integer> monoq = new LinkedList(); //opt(y) candidates, as indices of P\n\n        for (int y = 0; y < P.length; ++y) {\n            // Want opt(y) = largest x with P[x] <= P[y] - K;\n            while (!monoq.isEmpty() && P[y] <= P[monoq.getLast()])\n                monoq.removeLast();\n            while (!monoq.isEmpty() && P[y] >= P[monoq.getFirst()] + K)\n                ans = Math.min(ans, y - monoq.removeFirst());\n\n            monoq.addLast(y);\n        }\n\n        return ans < N+1 ? ans : -1;\n    }\n\n\n}\n"
  },
  {
    "path": "src/ShortestWordDistance243.java",
    "content": "/**\n * Given a list of words and two words word1 and word2, return the shortest\n * distance between these two words in the list.\n * \n * Example:\n * Assume that words = [\"practice\", \"makes\", \"perfect\", \"coding\", \"makes\"].\n * \n * Input: word1 = “coding”, word2 = “practice”\n * Output: 3\n * \n * Input: word1 = \"makes\", word2 = \"coding\"\n * Output: 1\n * \n * Note:\n * You may assume that word1 does not equal to word2, and word1 and word2 are\n * both in the list.\n */\n\npublic class ShortestWordDistance243 {\n    public int shortestDistance(String[] words, String word1, String word2) {\n        int last1 = -1;\n        int last2 = -1;\n        int res = Integer.MAX_VALUE;\n        for (int i=0; i<words.length; i++) {\n            if (words[i].equals(word1)) {\n                if (last2 != -1) {\n                    res = Math.min(res, i - last2);\n                }\n                last1 = i;\n            } else if (words[i].equals(word2)) {\n                if (last1 != -1) {\n                    res = Math.min(res, i - last1);\n                }\n                last2 = i;\n            }\n        }\n        return res;\n    }\n}\n"
  },
  {
    "path": "src/ShuffleAnArray384.java",
    "content": "/**\n * Shuffle a set of numbers without duplicates.\n * \n * Example:\n * \n * // Init an array with set 1, 2, and 3.\n * int[] nums = {1,2,3};\n * Solution solution = new Solution(nums);\n * \n * // Shuffle the array [1,2,3] and return its result. Any permutation of\n * [1,2,3] must equally likely to be returned.\n * solution.shuffle();\n * \n * // Resets the array back to its original configuration [1,2,3].\n * solution.reset();\n * \n * // Returns the random shuffling of array [1,2,3].\n * solution.shuffle();\n */\n\npublic class ShuffleAnArray384 {\n\n    class Solution {\n        private int[] nums;\n        private Random rand = new Random();\n\n        public Solution(int[] nums) {\n            this.nums = nums;\n        }\n\n        /** Resets the array to its original configuration and return it. */\n        public int[] reset() {\n            return this.nums;\n        }\n\n        /** Returns a random shuffling of the array. */\n        public int[] shuffle() {\n            int[] randomed = this.nums.clone();\n            for (int i=randomed.length-1; i>0; i--) {\n                int idx = rand.nextInt(i+1);\n                swap(randomed, idx, i);\n            }\n            return randomed;\n        }\n\n        private void swap(int[] arr, int i, int j) {\n            int tmp = arr[i];\n            arr[i] = arr[j];\n            arr[j] = tmp;\n        }\n    }\n\n/**\n * Your Solution object will be instantiated and called as such:\n * Solution obj = new Solution(nums);\n * int[] param_1 = obj.reset();\n * int[] param_2 = obj.shuffle();\n */\n\n}\n"
  },
  {
    "path": "src/SimplifyPath71.java",
    "content": "/**\n * Given an absolute path for a file (Unix-style), simplify it.\n *\n * For example,\n * path = \"/home/\", => \"/home\"\n * path = \"/a/./b/../../c/\", => \"/c\"\n *\n * Corner Cases:\n *     - Did you consider the case where path = \"/../\"?\n *       In this case, you should return \"/\".\n *     - Another corner case is the path might contain multiple slashes '/' together, such as \"/home//foo/\".\n *       In this case, you should ignore redundant slashes and return \"/home/foo\".\n */\n\n\npublic class SimplifyPath71 {\n    public String simplifyPath(String path) {\n        String[] parts = path.split(\"/\", -1);\n\n        List<String> result = new ArrayList<>();\n        for (String p: parts) {\n            if (p.equals(\".\") || p.equals(\"\")) {\n                continue;\n            }\n\n            if (p.equals(\"..\")) {\n                if (result.size() > 0) {\n                    result.remove(result.size() - 1);\n                }\n                continue;\n            }\n\n            result.add(p);\n        }\n\n        return \"/\" + String.join(\"/\", result.toArray(new String[result.size()]));\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/7675/java-10-lines-solution-with-stack\n     */\n\n    public String simplifyPath2(String path) {\n        Deque<String> stack = new LinkedList<>();\n        Set<String> skip = new HashSet<>(Arrays.asList(\"..\",\".\",\"\"));\n        for (String dir : path.split(\"/\")) {\n            if (dir.equals(\"..\") && !stack.isEmpty()) stack.pop();\n            else if (!skip.contains(dir)) stack.push(dir);\n        }\n        String res = \"\";\n        for (String dir : stack) res = \"/\" + dir + res;\n        return res.isEmpty() ? \"/\" : res;\n    }\n\n}\n"
  },
  {
    "path": "src/SingleElementInASortedArray540.java",
    "content": "/**\n * Given a sorted array consisting of only integers where every element appears\n * twice except for one element which appears once. Find this single element\n * that appears only once.\n * \n * Example 1:\n * Input: [1,1,2,3,3,4,4,8,8]\n * Output: 2\n * \n * Example 2:\n * Input: [3,3,7,7,10,11,11]\n * Output: 10\n * \n * Note: Your solution should run in O(log n) time and O(1) space.\n */\n\npublic class SingleElementInASortedArray540 {\n    public int singleNonDuplicate(int[] nums) {\n        if (nums.length == 1) return nums[0];\n        return singleNonDuplicate(nums, 0, nums.length-1);\n    }\n\n    private int singleNonDuplicate(int[] nums, int lo, int hi) {\n        if (lo == hi) return nums[lo]; \n        int mid = (lo + hi) / 2;\n        boolean b = (mid - lo) % 2 == 0;\n        if (nums[mid] != nums[mid-1] && nums[mid] != nums[mid+1]) {\n            return nums[mid];\n        }\n        if (nums[mid] != nums[mid-1]) {\n            if (b) {\n                return singleNonDuplicate(nums, mid, hi);\n            } else {\n                return singleNonDuplicate(nums, lo, mid-1);\n            }\n            \n        }\n        \n        if (b) {\n            return singleNonDuplicate(nums, lo, mid);\n        } else {\n            return singleNonDuplicate(nums, mid+1, hi);\n        }\n    }\n\n\n    private int singleNonDuplicate2(int[] nums, int lo, int hi) {\n        if (lo == hi) return nums[lo]; \n        int mid = (lo + hi) / 2;\n        boolean b = (mid - lo) % 2 == 0;\n        if (nums[mid] != nums[mid-1] && nums[mid] != nums[mid+1]) {\n            return nums[mid];\n        }\n\n        if ((nums[mid] == nums[mid-1]) == b) {\n            if (nums[mid] != nums[mid-1]) mid--;\n            return singleNonDuplicate2(nums, lo, mid);\n        }\n\n        if (nums[mid] == nums[mid-1]) mid++;\n        return singleNonDuplicate2(nums, mid, hi);\n    }\n\n\n    private int singleNonDuplicate3(int[] nums, int lo, int hi) {\n        if (lo == hi) return nums[lo]; \n        int mid = (lo + hi) / 2;\n        if (nums[mid] != nums[mid-1] && nums[mid] != nums[mid+1]) return nums[mid];\n        if (mid % 2 == 1) mid--;\n        if (nums[mid] != nums[mid+1]) return singleNonDuplicate3(nums, lo, mid);\n        return singleNonDuplicate3(nums, mid+2, hi);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/single-element-in-a-sorted-array/discuss/100754/Java-Binary-Search-short-(7l)-O(log(n))-w-explanations\n     */\n    public static int singleNonDuplicate2(int[] nums) {\n        int start = 0, end = nums.length - 1;\n\n        while (start < end) {\n            // We want the first element of the middle pair,\n            // which should be at an even index if the left part is sorted.\n            // Example:\n            // Index: 0 1 2 3 4 5 6\n            // Array: 1 1 3 3 4 8 8\n            //            ^\n            int mid = (start + end) / 2;\n            if (mid % 2 == 1) mid--;\n\n            // We didn't find a pair. The single element must be on the left.\n            // (pipes mean start & end)\n            // Example: |0 1 1 3 3 6 6|\n            //               ^ ^\n            // Next:    |0 1 1|3 3 6 6\n            if (nums[mid] != nums[mid + 1]) end = mid;\n\n            // We found a pair. The single element must be on the right.\n            // Example: |1 1 3 3 5 6 6|\n            //               ^ ^\n            // Next:     1 1 3 3|5 6 6|\n            else start = mid + 2;\n        }\n\n        // 'start' should always be at the beginning of a pair.\n        // When 'start > end', start must be the single element.\n        return nums[start];\n    }\n\n}\n\n\n"
  },
  {
    "path": "src/SingleNumber136.java",
    "content": "/**\n * Given an array of integers, every element appears twice except for one.\n * Find that single one.\n *\n * Note:\n * Your algorithm should have a linear runtime complexity. Could you implement\n * it without using extra memory?\n */\n\npublic class SingleNumber136 {\n    public int singleNumber(int[] nums) {\n        Arrays.sort(nums);\n        for (int i=0; i<nums.length; i++) {\n            int n = nums[i];\n            if ((i > 0 && n == nums[i-1]) || (i < nums.length-1 && n == nums[i+1])) continue;\n            return nums[i];\n        }\n        return -1;\n    }\n\n    public int singleNumber2(int[] nums) {\n        Set<Integer> set = new HashSet<>();\n        for (int i=0; i<nums.length; i++) {\n            if (set.contains(nums[i])) {\n                set.remove(nums[i]);\n            } else {\n                set.add(nums[i]);\n            }\n        }\n        return set.iterator().next();\n    }\n\n    /**\n     * https://leetcode.com/problems/single-number/discuss/42997/My-O(n)-solution-using-XOR\n     */\n    public int singleNumber3(int[] nums) {\n        int result = 0;\n        for (int i = 0; i<nums.length; i++) {\n            result ^= nums[i];\n        }\n        return result;\n    }\n\n}\n"
  },
  {
    "path": "src/SingleNumberII137.java",
    "content": "/**\n * Given an array of integers, every element appears three times except for\n * one, which appears exactly once. Find that single one.\n *\n * Note:\n * Your algorithm should have a linear runtime complexity. Could you implement\n * it without using extra memory?\n */\n\npublic class SingleNumberII137 {\n    /**\n     * https://leetcode.com/problems/single-number-ii/discuss/43294/Challenge-me-thx\n     * https://leetcode.com/problems/single-number-ii/discuss/43295/Detailed-explanation-and-generalization-of-the-bitwise-operation-method-for-single-numbers\n     */\n    public int singleNumber(int[] A) {\n        int ones = 0, twos = 0;\n        for(int i = 0; i < A.length; i++){\n            ones = (ones ^ A[i]) & ~twos;\n            twos = (twos ^ A[i]) & ~ones;\n        }\n        return ones;\n    }\n\n    /**\n     * https://leetcode.com/problems/single-number-ii/discuss/43363/JAVA-Easy-Version-To-UnderStand!!!!!!!!!!!!!!!!!!!\n     */\n    public int singleNumber2(int[] nums) {\n        int len = nums.length, result = 0;\n        for (int i = 0; i < 32; i++) {\n            int sum = 0;\n            for (int j = 0; j < len; j++) {\n                sum += (nums[j] >> i) & 1;\n            }\n            result |= (sum % 3) << i;\n        }\n        return result;\n    }\n\n}\n"
  },
  {
    "path": "src/SlidingWindowMaximum239.java",
    "content": "/**\n * Given an array nums, there is a sliding window of size k which is moving\n * from the very left of the array to the very right. You can only see the k\n * numbers in the window. Each time the sliding window moves right by one\n * position. Return the max sliding window.\n * \n * Example:\n * \n * Input: nums = [1,3,-1,-3,5,3,6,7], and k = 3\n * Output: [3,3,5,5,6,7] \n * Explanation: \n * \n * Window position                Max\n * ---------------               -----\n * [1  3  -1] -3  5  3  6  7       3\n *  1 [3  -1  -3] 5  3  6  7       3\n *  1  3 [-1  -3  5] 3  6  7       5\n *  1  3  -1 [-3  5  3] 6  7       5\n *  1  3  -1  -3 [5  3  6] 7       6\n *  1  3  -1  -3  5 [3  6  7]      7\n * \n * Note: \n * You may assume k is always valid, 1 ≤ k ≤ input array's size for\n * non-empty array.\n * \n * Follow up:\n * Could you solve it in linear time?\n */\n\n\npublic class SlidingWindowMaximum239 {\n    public int[] maxSlidingWindow(int[] nums, int k) {\n        if (nums == null || nums.length == 0) return new int[0];\n        PriorityQueue<Integer> pq = new PriorityQueue<>(k, (i1, i2) -> Integer.compare(i2, i1));\n        for (int i=0; i<k; i++) pq.add(nums[i]);\n        int[] res = new int[nums.length - k + 1];\n        for (int i=k; i<nums.length; i++) {\n            res[i-k] = pq.peek();\n            pq.remove(nums[i-k]);\n            pq.add(nums[i]);\n        }\n        res[res.length-1] = pq.peek();\n        return res;\n    }\n\n\n    public int[] maxSlidingWindow2(int[] nums, int k) {\n        if (nums == null || nums.length == 0) return new int[0];\n        LinkedList<int[]> ll = new LinkedList<int[]>();\n        for (int i=0; i<k; i++) {\n            if (ll.isEmpty()) {\n                ll.addLast(new int[]{i, nums[i]});\n            } else {\n                while (!ll.isEmpty() && ll.getLast()[1] <= nums[i]) {\n                    ll.removeLast();\n                }\n                ll.addLast(new int[]{i, nums[i]});\n            }\n        }\n        int[] res = new int[nums.length - k + 1];\n        for (int i=k; i<nums.length; i++) {\n            int[] head = ll.getFirst();\n            res[i-k] = head[1];\n            if (head[0] <= i - k) {\n                ll.removeFirst();\n            }\n            while (!ll.isEmpty() && ll.getLast()[1] <= nums[i]) {\n                ll.removeLast();\n            }\n            ll.addLast(new int[]{i, nums[i]});\n        }\n        res[res.length-1] = ll.getFirst()[1];\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/sliding-window-maximum/discuss/65881/O(n)-solution-in-Java-with-two-simple-pass-in-the-array\n     */\n    public int[] maxSlidingWindow3(int[] in, int w) {\n        if (in == null || in.length == 0) return new int[0];\n        int[] max_left = new int[in.length];\n        int[] max_right = new int[in.length];\n    \n        max_left[0] = in[0];\n        max_right[in.length - 1] = in[in.length - 1];\n    \n        for (int i = 1; i < in.length; i++) {\n            max_left[i] = (i % w == 0) ? in[i] : Math.max(max_left[i - 1], in[i]);\n    \n            int j = in.length - i - 1;\n            max_right[j] = (j % w == 0) ? in[j] : Math.max(max_right[j + 1], in[j]);\n        }\n    \n        int[] sliding_max = new int[in.length - w + 1];\n        for (int i = 0, j = 0; i + w <= in.length; i++) {\n            sliding_max[j++] = Math.max(max_right[i], max_left[i + w - 1]);\n        }\n    \n        return sliding_max;\n    }\n\n}\n"
  },
  {
    "path": "src/SlidingWindowMedian480.java",
    "content": "/**\n * Median is the middle value in an ordered integer list.\n * If the size of the list is even, there is no middle value.\n * So the median is the mean of the two middle value.\n *\n * Examples:\n * [2,3,4] , the median is 3\n * [2,3], the median is (2 + 3) / 2 = 2.5\n *\n * Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right.\n * You can only see the k numbers in the window. Each time the sliding window moves right by one position.\n * Your job is to output the median array for each window in the original array.\n *\n * For example,\n * Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.\n *\n * Window position                Median\n * ---------------               -----\n * [1  3  -1] -3  5  3  6  7       1\n *  1 [3  -1  -3] 5  3  6  7       -1\n *  1  3 [-1  -3  5] 3  6  7       -1\n *  1  3  -1 [-3  5  3] 6  7       3\n *  1  3  -1  -3 [5  3  6] 7       5\n *  1  3  -1  -3  5 [3  6  7]      6\n *\n *  Therefore, return the median sliding window as [1,-1,-1,3,5,6].\n *\n *  Note:\n *  You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array.\n */\n\n\nimport java.util.Arrays;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Collections;\n\n\npublic class SlidingWindowMedian480 {\n    public double[] medianSlidingWindow(int[] nums, int k) {\n        int len = nums.length;\n        int mid = k / 2;\n        List<Integer> window = new ArrayList<>();\n        for (int j = 0; j < k; j++) {\n            window.add(nums[j]);\n        }\n        Collections.sort(window);\n\n        if ((k & 1) == 0) {\n            int lenNew = len - 2 * mid + 1;\n            double[] returned = new double[lenNew];\n            for (int i = 0; i < lenNew - 1; i++) {\n                returned[i] = findMedianFromEven(window, mid);\n                int idx = window.indexOf(nums[i]);\n                int newValue = nums[i + k];\n                updateWindow(window, newValue, idx, k);\n            }\n            returned[lenNew - 1] = findMedianFromEven(window, mid);\n            return returned;\n        } else {\n            int lenNew = len - 2 * mid;\n            double[] returned = new double[lenNew];\n            for (int i = 0; i < lenNew - 1; i++) {\n                returned[i] = findMedianFromOdd(window, mid);\n                int idx = window.indexOf(nums[i]);\n                int newValue = nums[i + k];\n                updateWindow(window, newValue, idx, k);\n            }\n            returned[lenNew - 1] = findMedianFromOdd(window, mid);\n            return returned;\n        }\n    }\n\n    private double findMedianFromEven(List<Integer> window, int mid) {\n        return ((long)window.get(mid - 1) + (long)window.get(mid)) / 2.0;\n    }\n\n    private double findMedianFromOdd(List<Integer> window, int mid) {\n        return window.get(mid);\n    }\n\n    private void updateWindow(List<Integer> window, int newValue, int idx, int k) {\n        while(0 <= idx && idx < k) {\n            if (idx > 0 && window.get(idx - 1) > newValue) {\n                window.set(idx, window.get(idx - 1));\n                idx -= 1;\n            } else if (idx < k - 1 && window.get(idx + 1) < newValue) {\n                window.set(idx, window.get(idx + 1));\n                idx += 1;\n            } else {\n                window.set(idx, newValue);\n                return;\n            }\n        }\n        window.set(idx, newValue);\n    }\n\n\n\n    public double[] medianSlidingWindow2(int[] nums, int k) {\n        Comparator<Pair> comp = new Comparator<Pair>(){\n            public int compare(Pair p1, Pair p2) {\n                int diff = Integer.compare(p1.value, p2.value);\n                if (diff != 0) return diff;\n                return Integer.compare(p1.index, p2.index);  \n            }\n        };\n        TreeSet<Pair> left = new TreeSet<>(comp);\n        TreeSet<Pair> right = new TreeSet<>(comp);\n        boolean isOdd = k % 2 == 1;\n        for (int i=0; i<k; i++) {\n            addNew(i, nums[i], left, right);\n        }\n\n        int len = nums.length;\n        double[] res = new double[len - k + 1];\n        for (int i=0; i<=len-k; i++) {\n            res[i] = left.size() == right.size() ? ((double) left.last().value + (double) right.first().value) / 2.0 : (double) left.last().value;\n            if (i == len-k) break;\n            Pair oldP = new Pair(i, nums[i]);\n            boolean inLeft = left.remove(oldP);\n            if (!inLeft) right.remove(oldP);\n            addNew(i+k, nums[i+k], left, right);\n        }\n        return res;\n    }\n    \n    private void addNew(int index, int value, TreeSet<Pair> left, TreeSet<Pair> right) {\n        Pair p = new Pair(index, value);\n        if (right.size() != 0 && value > right.first().value) {\n            right.add(p);\n        } else {\n            left.add(p);\n        }\n        balance(left, right);\n    }\n    \n    private void balance(TreeSet<Pair> left, TreeSet<Pair> right) {\n        while (left.size() > right.size() + 1) {\n            Pair topLeft = left.pollLast();\n            right.add(topLeft);\n        }\n        while (left.size() < right.size()) {\n            Pair bottomRight = right.pollFirst();\n            left.add(bottomRight);\n        }\n    }\n\n    class Pair {\n        int index;\n        int value;\n        Pair(int i, int v) {\n            index = i;\n            value = v;\n        }\n    }\n\n\n    public double[] medianSlidingWindow3(int[] nums, int k) {\n        Comparator<Integer> comp = (i1, i2) -> Integer.compare(i2, i1);\n        PriorityQueue<Integer> left = new PriorityQueue<>(comp);\n        PriorityQueue<Integer> right = new PriorityQueue<>();\n\n        for (int i=0; i<k; i++) {\n            if (left.isEmpty() || nums[i] <= left.peek()) {\n                left.add(nums[i]);\n            } else {\n                right.add(nums[i]);\n            }\n            if (left.size() < right.size()) {\n                left.add(right.poll());\n            } else if (left.size() > right.size() + 1) {\n                right.add(left.poll());\n            }\n        }\n\n        int N = nums.length;\n        double[] res = new double[N-k+1];\n        for (int i=k; i<=N; i++) {\n            if (left.size() == right.size() + 1) {\n                res[i-k] = left.peek() * 1.0;\n            } else {\n                res[i-k] = ((long)left.peek() + (long)right.peek()) / 2.0;\n            }\n            if (i == N) break; \n            int toPop = nums[i-k];\n            int toAdd = nums[i];\n            \n            if (toAdd <= left.peek()) {\n                left.add(toAdd);\n            } else {\n                right.add(toAdd);\n            }\n            \n            if (left.peek() >= toPop) {\n                left.remove(toPop);\n            } else {\n                right.remove(toPop);\n            }\n\n            if (left.size() < right.size()) {\n                left.add(right.poll());\n            } else if (left.size() > right.size() + 1) {\n                right.add(left.poll());\n            }\n        }\n        return res;\n    }\n\n    public static void main(String[] args) {\n        SlidingWindowMedian480 swm = new SlidingWindowMedian480();\n\n        int [] nums = {1, 3, -1, -3, 5,  3,  6,  7};\n        int [] twos = {2147483647, 2147483647};\n\n        System.out.println(Arrays.toString(swm.medianSlidingWindow(nums, 3)));\n        System.out.println(Arrays.toString(swm.medianSlidingWindow(nums, 4)));\n        System.out.println(Arrays.toString(swm.medianSlidingWindow(twos, 2)));\n\n    }\n}\n"
  },
  {
    "path": "src/SmallestRange632.java",
    "content": "/**\n * You have k lists of sorted integers in ascending order. Find the smallest\n * range that includes at least one number from each of the k lists.\n *\n * We define the range [a,b] is smaller than range [c,d] if b-a < d-c or a < c if b-a == d-c.\n *\n * Example 1:\n *    Input:[[4,10,15,24,26], [0,9,12,20], [5,18,22,30]]\n *    Output: [20,24]\n *    Explanation:\n *      List 1: [4, 10, 15, 24,26], 24 is in range [20,24].\n *      List 2: [0, 9, 12, 20], 20 is in range [20,24].\n *      List 3: [5, 18, 22, 30], 22 is in range [20,24].\n *\n * Note:\n *    - The given list may contain duplicates, so ascending order means >= here.\n *    - 1 <= k <= 3500\n *    - 105 <= value of elements <= 105.\n *    - For Java users, please note that the input type has been changed to\n *      List<List<Integer>>. And after you reset the code template, you'll see\n *      this point.\n *\n */\n\n\npublic class SmallestRange632 {\n    /**\n     * https://leetcode.com/problems/smallest-range/solution/\n     */\n    public int[] smallestRange(List<List<Integer>> nums) {\n        int minx = 0, miny = Integer.MAX_VALUE, max = Integer.MIN_VALUE;\n        int[] next = new int[nums.size()];\n        boolean flag = true;\n        PriorityQueue<Integer> min_queue = new PriorityQueue<>((i, j) -> nums.get(i).get(next[i]) - nums.get(j).get(next[j]));\n        for (int i = 0; i < nums.size(); i++) {\n            min_queue.offer(i);\n            max = Math.max(max, nums.get(i).get(0));\n        }\n        for (int i = 0; i < nums.size() && flag; i++) {\n            for (int j = 0; j < nums.get(i).size() && flag; j++) {\n                int min_i = min_queue.poll();\n                if (miny - minx > max - nums.get(min_i).get(next[min_i])) {\n                    minx = nums.get(min_i).get(next[min_i]);\n                    miny = max;\n                }\n                next[min_i]++;\n                if (next[min_i] == nums.get(min_i).size()) {\n                    flag = false;\n                    break;\n                }\n                min_queue.offer(min_i);\n                max = Math.max(max, nums.get(min_i).get(next[min_i]));\n            }\n        }\n        return new int[] {minx, miny};\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/94445/java-code-using-priorityqueue-similar-to-merge-k-array\n     */\n    public int[] smallestRange2(List<List<Integer>> nums) {\n    \t\tPriorityQueue<Element> pq = new PriorityQueue<Element>(new Comparator<Element>() {\n      \t\t\tpublic int compare(Element a, Element b) {\n      \t\t\t\t    return a.val - b.val;\n      \t\t\t}\n    \t\t});\n    \t\tint min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;\n    \t\tfor (int i = 0; i < nums.size(); i++) {\n            int value = nums.get(i).get(0);\n      \t\t\tElement e = new Element(i, 0, value);\n      \t\t\tpq.offer(e);\n      \t\t\tmax = Math.max(max, value);\n    \t\t}\n    \t\tint range = Integer.MAX_VALUE;\n    \t\tint start = -1, end = -1;\n    \t\twhile (pq.size() == nums.size()) {\n      \t\t\tElement curr = pq.poll();\n      \t\t\tif (max - curr.val < range) {\n        \t\t\t\trange = max - curr.val;\n        \t\t\t\tstart = curr.val;\n        \t\t\t\tend = max;\n      \t\t\t}\n      \t\t\tif (curr.idx + 1 < nums.get(curr.row).size()) {\n        \t\t\t\tcurr.idx = curr.idx + 1;\n        \t\t\t\tcurr.val = nums.get(curr.row).get(curr.idx);\n        \t\t\t\tpq.offer(curr);\n        \t\t\t\tif (curr.val > max) {\n        \t\t\t\t\t  max = curr.val;\n        \t\t\t\t}\n      \t\t\t}\n    \t\t}\n\n    \t\treturn new int[] { start, end };\n  \t}\n\n    class Element {\n    \t\tint val;\n    \t\tint idx;\n    \t\tint row;\n\n    \t\tpublic Element(int r, int i, int v) {\n      \t\t\tval = v;\n      \t\t\tidx = i;\n      \t\t\trow = r;\n    \t\t}\n  \t}\n\n\n    // Time Limit Exceeded\n    public int[] smallestRange3(List<List<Integer>> nums) {\n        int minx = 0, miny = Integer.MAX_VALUE;\n        int[] next = new int[nums.size()];\n        while (true) {\n            int min_i = 0, max_i = 0;\n            for (int k = 0; k < nums.size(); k++) {\n                if (nums.get(min_i).get(next[min_i]) > nums.get(k).get(next[k]))\n                    min_i = k;\n                if (nums.get(max_i).get(next[max_i]) < nums.get(k).get(next[k]))\n                    max_i = k;\n            }\n            if (miny - minx > nums.get(max_i).get(next[max_i]) - nums.get(min_i).get(next[min_i])) {\n                miny = nums.get(max_i).get(next[max_i]);\n                minx = nums.get(min_i).get(next[min_i]);\n            }\n            next[min_i]++;\n            if (next[min_i] == nums.get(min_i).size()) break;\n        }\n        return new int[] {minx, miny};\n    }\n\n    /**\n     * https://leetcode.com/problems/smallest-range/solution/\n     */\n    public int[] smallestRange4(List<List<Integer>> nums) {\n        int minx = 0, miny = Integer.MAX_VALUE, max = Integer.MIN_VALUE;\n        int[] next = new int[nums.size()];\n        PriorityQueue<Integer> q = new PriorityQueue<Integer>(\n            (i, j) -> nums.get(i).get(next[i]) - nums.get(j).get(next[j])\n        );\n        for (int i = 0; i < nums.size(); i++) {\n            q.offer(i);\n            max = Math.max(max, nums.get(i).get(0));\n        }\n        while (true) {\n            int min_i = q.poll();\n            if (miny - minx > max - nums.get(min_i).get(next[min_i])) {\n                miny = max;\n                minx = nums.get(min_i).get(next[min_i]);\n            }\n            next[min_i]++;\n            if (next[min_i] == nums.get(min_i).size()) {\n                // flag = false;\n                break;\n            }\n            q.offer(min_i);\n            max = Math.max(max, nums.get(min_i).get(next[min_i]));\n        }\n        return new int[] {minx, miny};\n    }\n\n\n\n\n\n\n\n\n}\n"
  },
  {
    "path": "src/SolveTheEquation640.java",
    "content": "/**\n * Solve a given equation and return the value of x in the form of string\n * \"x=#value\". The equation contains only '+', '-' operation, the variable x\n * and its coefficient.\n * \n * If there is no solution for the equation, return \"No solution\".\n * \n * If there are infinite solutions for the equation, return \"Infinite solutions\".\n * \n * If there is exactly one solution for the equation, we ensure that the value\n * of x is an integer.\n * \n * Example 1:\n * Input: \"x+5-3+x=6+x-2\"\n * Output: \"x=2\"\n * \n * Example 2:\n * Input: \"x=x\"\n * Output: \"Infinite solutions\"\n * \n * Example 3:\n * Input: \"2x=x\"\n * Output: \"x=0\"\n * \n * Example 4:\n * Input: \"2x+3x-6x=x+2\"\n * Output: \"x=-1\"\n * \n * Example 5:\n * Input: \"x=x+2\"\n * Output: \"No solution\"\n */\n\npublic class SolveTheEquation640 {\n    public String solveEquation(String equation) {\n        char[] chars = equation.toCharArray();\n        int N = chars.length;\n        int a = 0;\n        int b = 0;\n        int curr = 0;\n        int sign = 1;\n        int i = 0;\n        while (chars[i] != '=') {\n            if (Character.isDigit(chars[i])) {\n                curr = curr * 10 + (int)(chars[i] - '0');\n                if (chars[i+1] == '=') {\n                    i += 2;\n                    break;\n                }\n            } else if (chars[i] == '+') {\n                b += sign * curr;\n                curr = 0;\n                sign = 1;\n            } else if (chars[i] == '-') {\n                b += sign * curr;\n                curr = 0;\n                sign = -1;\n            } else {\n                if (i == 0 || chars[i-1] != '0') {\n                    a += sign * (curr == 0 ? 1 : curr);\n                }\n                curr = 0;\n                i++;\n                if (chars[i] != '=') {\n                    sign = chars[i] == '+' ? 1 : -1;\n                } else {\n                    sign = 0;\n                    i++;\n                    break;\n                }\n            }\n            i++;\n        }\n        if (sign != 0) {\n            b += sign * curr;\n        }\n\n        curr = 0;\n        sign = 1;\n        while (i < N) {\n            if (Character.isDigit(chars[i])) {\n                curr = curr * 10 + (int)(chars[i] - '0');\n            } else if (chars[i] == '+') {\n                b -= sign * curr;\n                curr = 0;\n                sign = 1;\n            } else if (chars[i] == '-') {\n                b -= sign * curr;\n                curr = 0;\n                sign = -1;\n            } else {\n                if (i == 0 || chars[i-1] != '0') {\n                    a -= sign * (curr == 0 ? 1 : curr);\n                }\n                curr = 0;\n                i++;\n                if (i != N) {\n                    sign = chars[i] == '+' ? 1 : -1;\n                }\n            }\n            i++;\n        }\n        b -= sign * curr;\n\n        if (a == 0) {\n            return b == 0 ? \"Infinite solutions\" : \"No solution\";\n        } else {\n            return \"x=\" + (- b / a);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/solve-the-equation/discuss/105311/Concise-Java-Solution\n     */\n    public String solveEquation2(String equation) {\n        int[] res = evaluateExpression(equation.split(\"=\")[0]);\n        int[] res2 = evaluateExpression(equation.split(\"=\")[1]);\n        res[0] -= res2[0];\n        res[1] = res2[1] - res[1];\n        if (res[0] == 0 && res[1] == 0) return \"Infinite solutions\";\n        if (res[0] == 0) return \"No solution\";\n        return \"x=\" + res[1]/res[0];\n    }  \n\n    public int[] evaluateExpression(String exp) {\n        String[] tokens = exp.split(\"(?=[-+])\"); \n        int[] res =  new int[2];\n        for (String token : tokens) {\n            if (token.equals(\"+x\") || token.equals(\"x\")) res[0] += 1;\n            else if (token.equals(\"-x\")) res[0] -= 1;\n            else if (token.contains(\"x\")) res[0] += Integer.parseInt(token.substring(0, token.indexOf(\"x\")));\n            else res[1] += Integer.parseInt(token);\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/SortArrayByParityII922.java",
    "content": "/**\n * Given an array A of non-negative integers, half of the integers in A are odd, and half of the integers are even.\n * \n * Sort the array so that whenever A[i] is odd, i is odd; and whenever A[i] is even, i is even.\n * \n * You may return any answer array that satisfies this condition.\n * \n * Example 1:\n * Input: [4,2,5,7]\n * Output: [4,5,2,7]\n * \n * Explanation: [4,7,2,5], [2,5,4,7], [2,7,4,5] would also have been accepted.\n * \n * Note:\n * 2 <= A.length <= 20000\n * A.length % 2 == 0\n * 0 <= A[i] <= 1000\n */\npublic class SortArrayByParityII922 {\n    public int[] sortArrayByParityII(int[] A) {\n        int i = 0;\n        int j = 1;\n        int k = 0;\n        int len = A.length;\n        int[] B = new int[len];\n        while (k < len) {\n            if (isOdd(A[k])) {\n                B[j] = A[k];\n                j += 2;\n            } else {\n                B[i] = A[k];\n                i += 2;\n            }\n            k++;\n        }\n        return B;\n    }\n\n    private boolean isOdd(int num) {\n        return (num & 1) == 1;\n    }\n}\n"
  },
  {
    "path": "src/SortCharactersByFrequency451.java",
    "content": "/**\n * Given a string, sort it in decreasing order based on the frequency of characters.\n * \n * Example 1:\n * \n * Input:\n * \"tree\"\n * \n * Output:\n * \"eert\"\n * \n * Explanation:\n * 'e' appears twice while 'r' and 't' both appear once.\n * So 'e' must appear before both 'r' and 't'. Therefore \"eetr\" is also a valid answer.\n * \n * \n * Example 2:\n * \n * Input:\n * \"cccaaa\"\n * \n * Output:\n * \"cccaaa\"\n * \n * Explanation:\n * Both 'c' and 'a' appear three times, so \"aaaccc\" is also a valid answer.\n * Note that \"cacaca\" is incorrect, as the same characters must be together.\n * \n * \n * Example 3:\n * \n * Input:\n * \"Aabb\"\n * \n * Output:\n * \"bbAa\"\n * \n * Explanation:\n * \"bbaA\" is also a valid answer, but \"Aabb\" is incorrect.\n * Note that 'A' and 'a' are treated as two different characters.\n */\n\n\npublic class SortCharactersByFrequency451 {\n    public String frequencySort(String s) {\n        int[] map = new int[256];\n        for (char c: s.toCharArray()) map[c]++;\n        List<Character>[] bucket = new List[s.length() + 1];\n        for (int i=0; i<256; i++) {\n            int freq = map[i];\n            if (freq != 0) {\n                if (bucket[freq] == null) bucket[freq] = new LinkedList<>();\n                bucket[freq].add((char) i);\n            }\n        }\n        \n        StringBuilder sb = new StringBuilder();\n        for (int i=bucket.length-1; i>=0; i--) {\n            List<Character> list = bucket[i];\n            if (list != null) {\n                for (Character c: list) {\n                    char[] chars = new char[i];\n                    Arrays.fill(chars, c);\n                    sb.append(chars);\n                }\n            }\n        }\n        \n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "src/SortColors75.java",
    "content": "/**\n * Given an array with n objects colored red, white or blue, sort them so that\n * objects of the same color are adjacent, with the colors in the order red,\n * white and blue.\n *\n * Here, we will use the integers 0, 1, and 2 to represent the color red, white,\n * and blue respectively.\n *\n * Note:\n * You are not suppose to use the library's sort function for this problem.\n *\n * Follow up:\n * A rather straight forward solution is a two-pass algorithm using counting sort.\n * First, iterate the array counting number of 0's, 1's, and 2's, then overwrite\n * array with total number of 0's, then 1's and followed by 2's.\n *\n * Could you come up with an one-pass algorithm using only constant space?\n */\n\n\nimport java.util.Arrays;\n\n\npublic class SortColors75 {\n    public void sortColors(int[] nums) {\n        int L = nums.length;\n        if (L == 0 || L == 1) {\n            return;\n        }\n\n        helper(0, L - 1, nums);\n    }\n\n    private void helper(int left, int right, int[] nums) {\n        if (left == right) {\n            return;\n        }\n\n        int mid = (left + right) / 2;\n        helper(left, mid, nums);\n        helper(mid + 1, right, nums);\n        merge(left, mid, right, nums);\n    }\n\n    private void merge(int left, int mid, int right, int[] nums) {\n        int l = 0;\n        int r = 0;\n        int i = left;\n        int[] la = Arrays.copyOfRange(nums, left, mid+1);\n        int[] ra = Arrays.copyOfRange(nums, mid+1, right+1);\n        while (l <= mid - left && r <= right - mid - 1) {\n            if (la[l] <= ra[r]) {\n                nums[i] = la[l];\n                l++;\n            } else {\n                nums[i] = ra[r];\n                r++;\n            }\n            i++;\n        }\n        while (l <= mid - left) {\n            nums[i] = la[l];\n            l++;\n            i++;\n        }\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/6968/four-different-solutions\n     */\n    // two pass O(m+n) space\n    public void sortColors2(int A[]) {\n        int num0 = 0, num1 = 0, num2 = 0;\n\n        for(int i = 0; i < A.length; i++) {\n            if (A[i] == 0) ++num0;\n            else if (A[i] == 1) ++num1;\n            else if (A[i] == 2) ++num2;\n        }\n\n        for(int i = 0; i < num0; ++i) A[i] = 0;\n        for(int i = 0; i < num1; ++i) A[num0+i] = 1;\n        for(int i = 0; i < num2; ++i) A[num0+num1+i] = 2;\n    }\n\n    // one pass in place solution\n    public void sortColors3(int A[]) {\n        int n0 = -1, n1 = -1, n2 = -1;\n        for (int i = 0; i < A.length; ++i) {\n            if (A[i] == 0)\n            {\n                A[++n2] = 2; A[++n1] = 1; A[++n0] = 0;\n            }\n            else if (A[i] == 1)\n            {\n                A[++n2] = 2; A[++n1] = 1;\n            }\n            else if (A[i] == 2)\n            {\n                A[++n2] = 2;\n            }\n        }\n    }\n\n    // one pass in place solution\n    public void sortColors4(int A[]) {\n        int j = 0, k = A.length - 1;\n        for (int i = 0; i <= k; ++i){\n            if (A[i] == 0 && i != j)\n                swap(A, i--, j++);\n            else if (A[i] == 2 && i != k)\n                swap(A, i--, k--);\n        }\n    }\n\n\n    // one pass in place solution\n    public void sortColors5(int A[], int n) {\n        int j = 0, k = n-1;\n        for (int i=0; i <= k; i++) {\n            if (A[i] == 0)\n                swap(A, i, j++);\n            else if (A[i] == 2)\n                swap(A, i--, k--);\n        }\n    }\n\n    // bucket sort\n    public void sortColors6(int[] nums) {\n        int[] buckets = new int[3];\n\n        for (int i=0; i<nums.length; i++) {\n            buckets[nums[i]]++;\n        }\n\n        int idx = 0;\n        for (int i=0; i<3; i++) {\n            int count = buckets[i];\n            for (int j=0; j<count; j++) {\n                nums[idx++] = i;\n            }\n        }\n\n    }\n\n    public void sortColors7(int[] nums) {\n        if (nums == null || nums.length <= 1) return;\n        int left = 0;\n        int right = nums.length - 1;\n        int i = left;\n        while (i <= right) {\n            if (nums[i] == 0) {\n                swap(nums, i++, left++);\n            } else if (nums[i] == 2) {\n                swap(nums, i, right--);\n            } else {\n                i++;\n            }\n        }\n    }\n\n    private void swap(int[] nums, int i, int j) {\n        int tmp = nums[i];\n        nums[i] = nums[j];\n        nums[j] = tmp;\n    }\n\n\n    public static void main(String[] args) {\n        SortColors75 sc = new SortColors75();\n\n        int[] nums = new int[]{\n            5, 8, 1, 3, 7, 2, 9, 4, 1, 1, 0\n        };\n\n        System.out.println(Arrays.toString(nums));\n        sc.sortColors(nums);\n        System.out.println(Arrays.toString(nums));\n\n        nums = new int[]{\n            1, 1, 0, 2, 0, 1, 2, 0, 1, 1, 1, 2\n        };\n\n        System.out.println(Arrays.toString(nums));\n        sc.sortColors(nums);\n        System.out.println(Arrays.toString(nums));\n    }\n}\n"
  },
  {
    "path": "src/SortList148.java",
    "content": "/**\n * Sort a linked list in O(n log n) time using constant space complexity.\n */\n\n/**\n * Definition for singly-linked list.\n * public class ListNode {\n *     int val;\n *     ListNode next;\n *     ListNode(int x) { val = x; }\n * }\n */\n\npublic class SortList148 {\n    public ListNode sortList(ListNode head) {\n        if (head == null) return null;\n        if (head.next == null) return head;\n\n        ListNode s = head;\n        ListNode f = head;\n        ListNode pre = s;\n        while (s != null && f != null && f.next != null) {\n            pre = s;\n            s = s.next;\n            f = f.next.next;\n        }\n\n        pre.next = null;\n        ListNode left = sortList(head);\n        ListNode right = sortList(s);\n        return merge(left, right);\n    }\n\n    private ListNode merge(ListNode left, ListNode right) {\n        ListNode res = new ListNode(-1);\n        ListNode p = res;\n        ListNode l = left;\n        ListNode r = right;\n        while (l != null && r != null) {\n            if (l.val <= r.val) {\n                p.next = l;\n                l = l.next;\n            } else {\n                p.next = r;\n                r = r.next;\n            }\n            p = p.next;\n        }\n        if (l != null) p.next = l;\n        if (r != null) p.next = r;\n        return res.next;\n    }\n\n\n}\n"
  },
  {
    "path": "src/SortTransformedArray360.java",
    "content": "/**\n * Given a sorted array of integers nums and integer values a, b and c. Apply\n * a quadratic function of the form f(x) = ax2 + bx + c to each element x in\n * the array.\n * \n * The returned array must be in sorted order.\n * \n * Expected time complexity: O(n)\n * \n * Example:\n * nums = [-4, -2, 2, 4], a = 1, b = 3, c = 5,\n * \n * Result: [3, 9, 15, 33]\n * \n * nums = [-4, -2, 2, 4], a = -1, b = 3, c = 5\n * \n * Result: [-23, -5, 1, 7]\n */\n\npublic class SortTransformedArray360 {\n    public int[] sortTransformedArray(int[] nums, int a, int b, int c) {\n        if (nums == null || nums.length == 0) return new int[0];\n        int n = nums.length;\n        int[] res = new int[n];\n        int i = 0;\n        int j = n - 1;\n        int index = a >= 0 ? n - 1 : 0;\n        while (i <= j) {\n            int ii = result(nums[i], a, b, c);\n            int jj = result(nums[j], a, b, c);\n            if (a >= 0) {\n                if (ii >= jj) {\n                    res[index] = ii;\n                    i++;\n                } else {\n                    res[index] = jj;\n                    j--;\n                }\n                index--;\n            } else {\n                if (ii >= jj) {\n                    res[index] = jj;\n                    j--;\n                } else {\n                    res[index] = ii;\n                    i++;\n                }\n                index++;\n            }\n        }\n        return res;\n    }\n\n    private int result(int x, int a, int b, int c) {\n        return a * x * x + b * x + c;\n    }\n\n\n    public int[] sortTransformedArray2(int[] nums, int a, int b, int c) {\n        PriorityQueue<Integer> pq = new PriorityQueue<>();\n        for (int x: nums) {\n            pq.add(transfer(x, a, b, c));\n        }\n        int[] res = new int[nums.length];\n        int i = 0;\n        while (!pq.isEmpty()) {\n            res[i++] = pq.poll();\n        }\n        return res;\n    }\n\n    private int transfer(int x, int a, int b, int c) {\n        return a * x * x + b * x + c;\n    }\n\n}\n"
  },
  {
    "path": "src/SparseMatrixMultiplication311.java",
    "content": "/**\n * Given two sparse matrices A and B, return the result of AB.\n *\n * You may assume that A's column number is equal to B's row number.\n *\n * Example:\n *\n * A = [\n *   [ 1, 0, 0],\n *   [-1, 0, 3]\n * ]\n *\n * B = [\n *   [ 7, 0, 0 ],\n *   [ 0, 0, 0 ],\n *   [ 0, 0, 1 ]\n * ]\n *\n *\n *      |  1 0 0 |   | 7 0 0 |   |  7 0 0 |\n * AB = | -1 0 3 | x | 0 0 0 | = | -7 0 3 |\n *                   | 0 0 1 |\n *\n */\n\n\npublic class SparseMatrixMultiplication311 {\n    // brutal force\n    // public int[][] multiply(int[][] A, int[][] B) {\n    //     int ax = A.length;\n    //     int by = B[0].length;\n    //     int len = B.length;\n    //     int[][] res = new int[ax][by];\n    //\n    //     for (int i=0; i<ax; i++) {\n    //         for (int j=0; j<by; j++) {\n    //             for (int k=0; k<len; k++) {\n    //                 res[i][j] += A[i][k] * B[k][j];\n    //             }\n    //         }\n    //     }\n    //\n    //     return res;\n    // }\n\n\n    // change order, add zero check\n    public int[][] multiply(int[][] A, int[][] B) {\n        int ax = A.length;\n        int by = B[0].length;\n        int len = B.length;\n        int[][] res = new int[ax][by];\n\n        for (int i=0; i<ax; i++) {\n            for (int k=0; k<len; k++) {\n                if (A[i][k] == 0) continue;\n                for (int j=0; j<by; j++) {\n                    if (B[k][j] == 0) continue;\n                    res[i][j] += A[i][k] * B[k][j];\n                }\n            }\n        }\n\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/SpiralMatrix54.java",
    "content": "/**\n * Given a matrix of m x n elements (m rows, n columns), return all elements\n * of the matrix in spiral order.\n * \n * Example 1:\n * \n * Input:\n * [\n *  [ 1, 2, 3 ],\n *  [ 4, 5, 6 ],\n *  [ 7, 8, 9 ]\n * ]\n * Output: [1,2,3,6,9,8,7,4,5]\n * \n * \n * Example 2:\n * \n * Input:\n * [\n *   [1, 2, 3, 4],\n *   [5, 6, 7, 8],\n *   [9,10,11,12]\n * ]\n * Output: [1,2,3,4,8,12,11,10,9,5,6,7]\n */\n\n\npublic class SpiralMatrix54 {\n    public List<Integer> spiralOrder(int[][] matrix) {\n        List<Integer> res = new ArrayList<>();\n        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return res;\n        helper(matrix, 0, 0, matrix.length - 1, matrix[0].length - 1, res);\n        return res;\n    }\n\n\n    private void helper(int[][] matrix, int x0, int y0, int x1, int y1, List<Integer> res) {\n        if (x0 > x1 || y0 > y1) return;\n        if (x0 == x1) {\n            for (int i=y0; i<=y1; i++) res.add(matrix[x0][i]);\n            return;\n        }\n        if (y0 == y1) {\n            for (int i=x0; i<=x1; i++) res.add(matrix[i][y0]);\n            return;\n        }\n        for (int i=y0; i<y1; i++) res.add(matrix[x0][i]);\n        for (int i=x0; i<x1; i++) res.add(matrix[i][y1]);\n        for (int i=y1; i>y0; i--) res.add(matrix[x1][i]);\n        for (int i=x1; i>x0; i--) res.add(matrix[i][y0]);\n\n        helper(matrix, x0 + 1, y0 + 1, x1 - 1, y1 - 1, res);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/spiral-matrix/solution/\n     */\n    public List < Integer > spiralOrder2(int[][] matrix) {\n        List ans = new ArrayList();\n        if (matrix.length == 0)\n            return ans;\n        int r1 = 0, r2 = matrix.length - 1;\n        int c1 = 0, c2 = matrix[0].length - 1;\n        while (r1 <= r2 && c1 <= c2) {\n            for (int c = c1; c <= c2; c++) ans.add(matrix[r1][c]);\n            for (int r = r1 + 1; r <= r2; r++) ans.add(matrix[r][c2]);\n            if (r1 < r2 && c1 < c2) {\n                for (int c = c2 - 1; c > c1; c--) ans.add(matrix[r2][c]);\n                for (int r = r2; r > r1; r--) ans.add(matrix[r][c1]);\n            }\n            r1++;\n            r2--;\n            c1++;\n            c2--;\n        }\n        return ans;\n    }\n\n    /**\n     * https://leetcode.com/problems/spiral-matrix/solution/\n     */\n    public List<Integer> spiralOrder3(int[][] matrix) {\n        List ans = new ArrayList();\n        if (matrix.length == 0) return ans;\n        int R = matrix.length, C = matrix[0].length;\n        boolean[][] seen = new boolean[R][C];\n        int[] dr = {0, 1, 0, -1};\n        int[] dc = {1, 0, -1, 0};\n        int r = 0, c = 0, di = 0;\n        for (int i = 0; i < R * C; i++) {\n            ans.add(matrix[r][c]);\n            seen[r][c] = true;\n            int cr = r + dr[di];\n            int cc = c + dc[di];\n            if (0 <= cr && cr < R && 0 <= cc && cc < C && !seen[cr][cc]){\n                r = cr;\n                c = cc;\n            } else {\n                di = (di + 1) % 4;\n                r += dr[di];\n                c += dc[di];\n            }\n        }\n        return ans;\n    }\n\n\n    public List<Integer> spiralOrder4(int[][] matrix) {\n        List<Integer> res = new ArrayList<>();\n        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return res;\n        int M = matrix.length;\n        int N = matrix[0].length;\n        int mid = Math.min((M+1)/2, (N+1)/2);\n        for (int c=0; c<mid; c++) {\n            for (int j=c; j<=N-c-1; j++) res.add(matrix[c][j]);\n            for (int i=c+1; i<=M-c-1; i++) res.add(matrix[i][N-c-1]);\n            if (M-c-1 > c) for (int j=N-c-2; j>=c; j--) res.add(matrix[M-c-1][j]);\n            if (N-c-1 > c) for (int i=M-c-2; i>=c+1; i--) res.add(matrix[i][c]);\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/SpiralMatrixII59.java",
    "content": "/**\n * Given a positive integer n, generate a square matrix filled with elements\n * from 1 to n2 in spiral order.\n * \n * Example:\n * \n * Input: 3\n * Output:\n * [\n *  [ 1, 2, 3 ],\n *  [ 8, 9, 4 ],\n *  [ 7, 6, 5 ]\n * ]\n */\n\n\npublic class SpiralMatrixII59 {\n    private int[][] directions = new int[][]{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};\n    public int[][] generateMatrix(int n) {\n        int[][] res = new int[n][n];\n        int i = 1;\n        int d = 0;\n        int x = 0;\n        int y = 0;\n        int END = n * n;\n        while (i <= END) {\n            res[x][y] = i;\n            int nx = x + directions[d][0];\n            int ny = y + directions[d][1];\n            if (nx < 0 || ny < 0 || nx >= n || ny >= n || res[nx][ny] != 0) {\n                d = (d + 1) % 4;\n                nx = x + directions[d][0];\n                ny = y + directions[d][1];\n            }\n            x = nx;\n            y = ny;\n            i++;\n        }\n        return res;\n    }\n\n    public int[][] generateMatrix2(int n) {\n        if (n == 0) return new int[0][0];\n        int[][] matrix = new int[n][n];\n        boolean[][] filled = new boolean[n][n];\n        int[] dx = new int[]{0, 1, 0, -1};\n        int[] dy = new int[]{1, 0, -1, 0};\n        int x = 0;\n        int y = 0;\n        int d = 0;\n        for (int i=1; i<=n*n; i++) {\n            matrix[x][y] = i;\n            filled[x][y] = true;\n            int xx = x + dx[d];\n            int yy = y + dy[d];\n            if (xx >= 0 && xx < n && yy >= 0 && yy < n && !filled[xx][yy]) {\n                x = xx;\n                y = yy;\n            } else {\n                d = (d + 1) % 4;\n                x += dx[d];\n                y += dy[d];\n            }\n        }\n        return matrix;\n    }\n\n}\n"
  },
  {
    "path": "src/SplitArrayIntoConsecutiveSubsequences659.java",
    "content": "/**\n * You are given an integer array sorted in ascending order (may contain\n * duplicates), you need to split them into several subsequences, where each\n * subsequences consist of at least 3 consecutive integers. Return whether you\n * can make such a split.\n * \n * Example 1:\n * Input: [1,2,3,3,4,5]\n * Output: True\n * Explanation:\n * You can split them into two consecutive subsequences : \n * 1, 2, 3\n * 3, 4, 5\n * \n *  Example 2:\n * Input: [1,2,3,3,4,4,5,5]\n * Output: True\n * Explanation:\n * You can split them into two consecutive subsequences : \n * 1, 2, 3, 4, 5\n * 3, 4, 5\n * \n * Example 3:\n * Input: [1,2,3,4,4,5]\n * Output: False\n * \n * Note:\n * The length of the input is in range of [1, 10000]\n *\n */\n\n\npublic class SplitArrayIntoConsecutiveSubsequences659 {\n    // too slow\n    // public boolean isPossible(int[] nums) {\n    //     if (nums == null || nums.length < 3) return false;\n\n    //     Map<Integer, Integer> sizes = new HashMap<>();\n    //     Map<Integer, Integer> lasts = new HashMap<>();\n    //     for (int i=0; i<nums.length; i++) {\n    //         int s1Index = -1;\n    //         int s2Index = -1;\n    //         for (int si=0; si<sizes.size(); si++) {\n    //             if (lasts.get(si) + 1 != nums[i]) continue;\n    //             // System.out.println(s1Index + \", \" + s2Index);\n    //             if (s1Index == -1) {\n    //                 s1Index = si;\n    //             }\n    //             if (sizes.get(si) < 3) {\n    //                 s2Index = si;\n    //                 break;\n    //             }\n    //         }\n    //         // System.out.println(s1Index + \", \" + s2Index + \"; \" + nums[i]);\n    //         int idx = (s2Index == -1) ? s1Index : s2Index;\n    //         if (idx != -1) {\n    //             lasts.put(idx, nums[i]);\n    //             sizes.put(idx, sizes.get(idx)+1);\n    //         } else {\n    //             int newSub = sizes.size();\n    //             lasts.put(newSub, nums[i]);\n    //             sizes.put(newSub, 1);\n    //         }\n    //     }\n        \n    //     // return whether each stack is having at least 3 elements\n    //     for (Integer sz: sizes.values()) {\n    //         if (sz < 3) return false;\n    //     }\n    //     return true;\n    // }\n\n\n    /**\n     * https://leetcode.com/problems/split-array-into-consecutive-subsequences/discuss/106496/Java-O(n)-Time-O(n)-Space\n     * \n     * - We iterate through the array once to get the frequency of all the\n     *      elements in the array\n     * - We iterate through the array once more and for each element we either\n     *      see if it can be appended to a previously constructed consecutive\n     *      sequence or if it can be the start of a new consecutive sequence.\n     *      If neither are true, then we return false.\n     */\n    public boolean isPossible(int[] nums) {\n        Map<Integer, Integer> freq = new HashMap<>(), appendfreq = new HashMap<>();\n        for (int i : nums) freq.put(i, freq.getOrDefault(i,0) + 1);\n        for (int i : nums) {\n            if (freq.get(i) == 0) continue;\n            else if (appendfreq.getOrDefault(i,0) > 0) {\n                appendfreq.put(i, appendfreq.get(i) - 1);\n                appendfreq.put(i+1, appendfreq.getOrDefault(i+1,0) + 1);\n            }   \n            else if (freq.getOrDefault(i+1,0) > 0 && freq.getOrDefault(i+2,0) > 0) {\n                freq.put(i+1, freq.get(i+1) - 1);\n                freq.put(i+2, freq.get(i+2) - 1);\n                appendfreq.put(i+3, appendfreq.getOrDefault(i+3,0) + 1);\n            }\n            else return false;\n            freq.put(i, freq.get(i) - 1);\n        }\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/split-array-into-consecutive-subsequences/discuss/106495/Java-O(n)-time-and-O(1)-space-solution-greedily-extending-shorter-subsequence\n     */\n    public boolean isPossible2(int[] nums) {\n        int pre = Integer.MIN_VALUE, p1 = 0, p2 = 0, p3 = 0;\n        int cur = 0, cnt = 0, c1 = 0, c2 = 0, c3 = 0;\n            \n        for (int i = 0; i < nums.length; pre = cur, p1 = c1, p2 = c2, p3 = c3) {\n            for (cur = nums[i], cnt = 0; i < nums.length && cur == nums[i]; cnt++, i++);\n                \n            if (cur != pre + 1) {\n                if (p1 != 0 || p2 != 0) return false;\n                c1 = cnt; c2 = 0; c3 = 0;\n                \n            } else {\n                if (cnt < p1 + p2) return false;\n                c1 = Math.max(0, cnt - (p1 + p2 + p3));\n                c2 = p1;\n                c3 = p2 + Math.min(p3, cnt - (p1 + p2));\n            }\n        }\n        \n        return (p1 == 0 && p2 == 0);\n    }\n\n\n    public boolean isPossible3(int[] nums) {\n        int pre = Integer.MIN_VALUE;\n        int p1 = 0;\n        int p2 = 0;\n        int p3 = 0;\n        \n        int i = 0;\n        while (i < nums.length) {\n            int cur = nums[i];\n            int count = 0;\n            while (i < nums.length && nums[i] == cur) {\n                i++;\n                count++;\n            }\n            \n            int c1 = 0;\n            int c2 = 0;\n            int c3 = 0;\n            if (cur == pre + 1) {\n                if (count < p1 + p2) return false;\n                c1 = Math.max(0, count - (p1 + p2 + p3));\n                c2 = p1;\n                c3 = p2 + Math.min(p3, count - (p1 + p2));\n            } else {\n                if (p1 != 0 || p2 != 0) return false;\n                c1 = count;\n                c2 = 0;\n                c3 = 0;\n            }\n            \n            pre = cur;\n            p1 = c1;\n            p2 = c2;\n            p3 = c3;\n        }\n        \n        return (p1 == 0 && p2 == 0);\n    }\n\n}\n"
  },
  {
    "path": "src/SplitArrayIntoFibonacciSequence842.java",
    "content": "/**\n * Given a string S of digits, such as S = \"123456579\", we can split it into a\n * Fibonacci-like sequence [123, 456, 579].\n * \n * Formally, a Fibonacci-like sequence is a list F of non-negative integers such that:\n * 0 <= F[i] <= 2^31 - 1, (that is, each integer fits a 32-bit signed integer type);\n * F.length >= 3;\n * and F[i] + F[i+1] = F[i+2] for all 0 <= i < F.length - 2.\n * \n * Also, note that when splitting the string into pieces, each piece must not\n * have extra leading zeroes, except if the piece is the number 0 itself.\n * \n * Return any Fibonacci-like sequence split from S, or return [] if it cannot be done.\n * \n * Example 1:\n * Input: \"123456579\"\n * Output: [123,456,579]\n * \n * Example 2:\n * Input: \"11235813\"\n * Output: [1,1,2,3,5,8,13]\n * \n * Example 3:\n * Input: \"112358130\"\n * Output: []\n * Explanation: The task is impossible.\n * \n * Example 4:\n * Input: \"0123\"\n * Output: []\n * Explanation: Leading zeroes are not allowed, so \"01\", \"2\", \"3\" is not valid.\n * \n * Example 5:\n * Input: \"1101111\"\n * Output: [110, 1, 111]\n * Explanation: The output [11, 0, 11, 11] would also be accepted.\n * \n * Note:\n * 1 <= S.length <= 200\n * S contains only digits.\n */\n\npublic class SplitArrayIntoFibonacciSequence842 {\n    public List<Integer> splitIntoFibonacci(String S) {\n        int N = S.length();\n        List<Integer> res = new ArrayList<>();\n        if (N <= 2) return res;\n        for (int i=0; i<Math.min(N-2, 10); i++) {\n            res = new ArrayList<>();\n            try {\n                int a = Integer.parseInt(S.substring(0, i+1));\n                if (S.charAt(0) == '0' && a != 0) return new ArrayList<>();\n                res.add(a);\n                for (int j=i+1; j<Math.min(N-1, 10); j++) {\n                    int b = Integer.parseInt(S.substring(i+1, j+1));\n                    if (S.charAt(i+1) == '0' && b != 0) continue;\n                    res.add(b);\n                    if (helper(res, a, b, j+1, N, S)) return res;\n                    res = res.subList(0, 1);\n                }\n            } catch (NumberFormatException e) {\n                return new ArrayList<>();\n            }\n        }\n        return new ArrayList<>();\n    }\n\n    public boolean helper(List<Integer> res, int a, int b, int k, int N, String S) {\n        int x = a;\n        int y = b;\n        int idx = k;\n        int next = x + y;\n        while (idx < N) {\n            String n = Integer.toString(next);\n            if (!S.startsWith(n, idx)) return false;\n            res.add(next);\n            x = y;\n            y = next;\n            next = x + y;\n            idx += n.length();\n        }\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "src/SplitArrayLargestSum410.java",
    "content": "/**\n * Given an array which consists of non-negative integers and an integer m, you\n * can split the array into m non-empty continuous subarrays. Write an\n * algorithm to minimize the largest sum among these m subarrays.\n * \n * Note:\n * If n is the length of array, assume the following constraints are satisfied:\n * 1 ≤ n ≤ 1000\n * 1 ≤ m ≤ min(50, n)\n * \n * Examples:\n * Input:\n * nums = [7,2,5,10,8]\n * m = 2\n * \n * Output:\n * 18\n * \n * Explanation:\n * There are four ways to split nums into two subarrays.\n * The best way is to split it into [7,2,5] and [10,8],\n * where the largest sum among the two subarrays is only 18.\n */\n\npublic class SplitArrayLargestSum410 {\n    // DP 1\n    public int splitArray(int[] nums, int m) {\n        int n = nums.length;\n        int[] sum = new int[n+1];\n        for (int j=1; j<=n; j++) sum[j] += sum[j-1]  + nums[j-1];\n\n        int[][] dp = new int[m][n];\n        for (int j=0; j<n; j++) {\n            dp[0][j] = sum[j+1];\n        }\n        for (int i=1; i<m; i++) {\n            for (int j=i; j<n; j++) {\n                int s = Integer.MAX_VALUE;\n                for (int k=0; k<j; k++) {\n                    s = Math.min(s, Math.max(dp[i-1][k], sum[j+1] - sum[k+1]));\n                }\n                dp[i][j] = s;\n            }\n        }\n        return dp[m-1][n-1];\n    }\n\n    // DP 2\n    public int splitArray2(int[] nums, int m) {\n        int n = nums.length;\n        int[] sum = new int[n+1];\n        for (int j=1; j<=n; j++) sum[j] += sum[j-1]  + nums[j-1];\n\n        int[] dp = new int[n];\n        for (int j=0; j<n; j++) {\n            dp[j] = sum[j+1];\n        }\n        for (int i=1; i<m; i++) {\n            int[] tmp = new int[n];\n            for (int j=0; j<n; j++) tmp[j] = dp[j];\n            for (int j=i; j<n; j++) {\n                int s = Integer.MAX_VALUE;\n                for (int k=0; k<j; k++) {\n                    s = Math.min(s, Math.max(tmp[k], sum[j+1] - sum[k+1]));\n                }\n                dp[j] = s;\n            }\n        }\n        return dp[n-1];\n    }\n\n    // DP 3\n    public int splitArray3(int[] nums, int m) {\n        int n = nums.length;\n        int[] sum = new int[n+1];\n        for (int j=1; j<=n; j++) sum[j] += sum[j-1]  + nums[j-1];\n\n        int[][] dp = new int[2][n];\n        for (int j=0; j<n; j++) {\n            dp[0][j] = sum[j+1];\n        }\n        for (int i=1; i<m; i++) {\n            for (int j=i; j<n; j++) {\n                int s = Integer.MAX_VALUE;\n                for (int k=0; k<j; k++) {\n                    s = Math.min(s, Math.max(dp[(i+1)%2][k], sum[j+1] - sum[k+1]));\n                }\n                dp[i%2][j] = s;\n            }\n        }\n        return dp[(m+1)%2][n-1];\n    }\n\n\n    // Binary Search on Value Range\n    public int splitArray4(int[] nums, int m) {\n        int n = nums.length;\n        long l = Long.MIN_VALUE;\n        long r = 0;\n        for (int j=0; j<n; j++) {\n            l = Math.max(l, nums[j]);\n            r += nums[j];\n        }\n        while (l < r) {\n            long mid = (l + r) / 2;\n            int cnt = count(nums, m, mid);\n            if (cnt > m) {\n                l = mid + 1;\n            } else {\n                r = mid;\n            }\n        }\n        return (int) l;\n    }\n\n    private int count(int[] nums, int m, long mid) {\n        int res = 0;\n        long sum = 0;\n        for (int n: nums) {\n            sum += n;\n            if (sum > mid) {\n                res++;\n                sum = n;\n            }\n        }\n        return res+1;\n    }\n\n}\n"
  },
  {
    "path": "src/SqrtX69.java",
    "content": "/**\n * Implement int sqrt(int x).\n *\n * Compute and return the square root of x.\n */\n\n\n\npublic class SqrtX69 {\n    public int mySqrt(int x) {\n        return (int)Math.sqrt(x);\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/8680/a-binary-search-solution\n     */\n    public int mySqrt2(int x) {\n        if (x == 0)\n            return 0;\n        int left = 1, right = Integer.MAX_VALUE;\n        while (true) {\n            int mid = left + (right - left)/2;\n            if (mid > x/mid) {\n                right = mid - 1;\n            } else {\n                if (mid + 1 > x/(mid + 1))\n                    return mid;\n                left = mid + 1;\n            }\n        }\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/24532/3-4-short-lines-integer-newton-every-language\n     */\n    public int mySqrt3(int x) {\n        long r = x;\n        while (r*r > x)\n            r = (r + x/r) / 2;\n        return (int) r;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/2671/share-my-o-log-n-solution-using-bit-manipulation/26\n     */\n    public int mySqrt(int x) {\n        if(x==0)\n            return 0;\n        int h=0;\n        while((long)(1<<h)*(long)(1<<h)<=x) // firstly, find the most significant bit\n            h++;\n        h--;\n        int b=h-1;\n        int res=(1<<h);\n        while(b>=0){  // find the remaining bits\n            if((long)(res | (1<<b))*(long)(res |(1<<b))<=x)\n                res|=(1<<b);\n            b--;\n        }\n        return res;\n    }\n\n\n}\n"
  },
  {
    "path": "src/StoneGame877.java",
    "content": "/**\n * Alex and Lee play a game with piles of stones.  There are an even number of\n * piles arranged in a row, and each pile has a positive integer number of\n * stones piles[i].\n * \n * The objective of the game is to end with the most stones.  The total number\n * of stones is odd, so there are no ties.\n * \n * Alex and Lee take turns, with Alex starting first.  Each turn, a player\n * takes the entire pile of stones from either the beginning or the end of the\n * row.  This continues until there are no more piles left, at which point the\n * person with the most stones wins.\n * \n * Assuming Alex and Lee play optimally, return True if and only if Alex wins\n * the game.\n * \n * Example 1:\n * \n * Input: [5,3,4,5]\n * Output: true\n * Explanation: \n * Alex starts first, and can only take the first 5 or the last 5.\n * Say he takes the first 5, so that the row becomes [3, 4, 5].\n * If Lee takes 3, then the board is [4, 5], and Alex takes 5 to win with 10 points.\n * If Lee takes the last 5, then the board is [3, 4], and Alex takes 4 to win with 9 points.\n * This demonstrated that taking the first 5 was a winning move for Alex, so we return true.\n * \n * Note:\n * 2 <= piles.length <= 500\n * piles.length is even.\n * 1 <= piles[i] <= 500\n * sum(piles) is odd.\n */\n\npublic class StoneGame877 {\n    public boolean stoneGame(int[] piles) {\n        int N = piles.length;\n        return stoneGame(piles, 0, N-1, true, 0, 0);\n    }\n\n    public boolean stoneGame(int[] piles, int i, int j, boolean A, int sumA, int sumL) {\n        if (i > j) return sumA > sumL;\n        if (A) {\n            return stoneGame(piles, i+1, j, true, sumA+piles[i], sumL) || stoneGame(piles, i, j-1, true, sumA, sumL+piles[j]);\n        }\n        return stoneGame(piles, i+1, j, true, sumA+piles[i], sumL) && stoneGame(piles, i, j-1, true, sumA, sumL+piles[j]);\n    }\n\n    /**\n     * :D\n     */\n    public boolean stoneGame2(int[] piles) {\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "src/StringCompression443.java",
    "content": "/**\n * Given an array of characters, compress it in-place.\n * \n * The length after compression must always be smaller than or equal to the original array.\n * \n * Every element of the array should be a character (not int) of length 1.\n * \n * After you are done modifying the input array in-place, return the new length of the array.\n * \n * Follow up:\n * Could you solve it using only O(1) extra space?\n * \n * Example 1:\n * Input:\n * [\"a\",\"a\",\"b\",\"b\",\"c\",\"c\",\"c\"]\n * Output:\n * Return 6, and the first 6 characters of the input array should be: [\"a\",\"2\",\"b\",\"2\",\"c\",\"3\"]\n * Explanation:\n * \"aa\" is replaced by \"a2\". \"bb\" is replaced by \"b2\". \"ccc\" is replaced by \"c3\".\n * \n * \n * Example 2:\n * Input:\n * [\"a\"]\n * Output:\n * Return 1, and the first 1 characters of the input array should be: [\"a\"]\n * Explanation:\n * Nothing is replaced.\n * \n * \n * Example 3:\n * Input:\n * [\"a\",\"b\",\"b\",\"b\",\"b\",\"b\",\"b\",\"b\",\"b\",\"b\",\"b\",\"b\",\"b\"]\n * Output:\n * Return 4, and the first 4 characters of the input array should be: [\"a\",\"b\",\"1\",\"2\"].\n * Explanation:\n * Since the character \"a\" does not repeat, it is not compressed. \"bbbbbbbbbbbb\" is replaced by \"b12\".\n * Notice each digit has it's own entry in the array.\n * \n * Note:\n * All characters have an ASCII value in [35, 126].\n * 1 <= len(chars) <= 1000.\n */\n\n\npublic class StringCompression443 {\n    public int compress(char[] chars) {\n        if (chars == null || chars.length <= 0) return 0;\n        if (chars.length == 1) return 1;\n        int i = 1;\n        int j = 1;\n        int count = 1;\n        char pre = chars[0];\n        while (j < chars.length) {\n            if (chars[j] == pre) {\n                count++;\n                j++;\n            } else {\n                if (count != 1) {\n                    char[] nums = Integer.toString(count).toCharArray();\n                    for (char n: nums) {\n                        chars[i++] = n;\n                    }\n                }\n                pre = chars[j];\n                count = 1;\n                j++;\n                chars[i] = pre;\n                i++;\n            }\n        }\n        if (count != 1) {\n            char[] nums = Integer.toString(count).toCharArray();\n            for (char n: nums) {\n                chars[i++] = n;\n            }\n        }\n        return i;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/string-compression/solution/\n     */\n    public int compress2(char[] chars) {\n        int anchor = 0, write = 0;\n        for (int read = 0; read < chars.length; read++) {\n            if (read + 1 == chars.length || chars[read + 1] != chars[read]) {\n                chars[write++] = chars[anchor];\n                if (read > anchor) {\n                    for (char c: (\"\" + (read - anchor + 1)).toCharArray()) {\n                        chars[write++] = c;\n                    }\n                }\n                anchor = read + 1;\n            }\n        }\n        return write;\n    }\n\n}\n"
  },
  {
    "path": "src/StringToInteger8.java",
    "content": "/**\n * Implement atoi to convert a string to an integer.\n *\n * Hint: Carefully consider all possible input cases. If you want a challenge,\n * please do not see below and ask yourself what are the possible input cases.\n *\n * Notes: It is intended for this problem to be specified vaguely (ie, no given\n * input specs). You are responsible to gather all the input requirements up front.\n *\n * Requirements for atoi:\n * The function first discards as many whitespace characters as necessary until\n * the first non-whitespace character is found. Then, starting from this\n * character, takes an optional initial plus or minus sign followed by as many\n * numerical digits as possible, and interprets them as a numerical value.\n *\n * The string can contain additional characters after those that form the\n * integral number, which are ignored and have no effect on the behavior of\n * this function.\n *\n * If the first sequence of non-whitespace characters in str is not a valid\n * integral number, or if no such sequence exists because either str is empty\n * or it contains only whitespace characters, no conversion is performed.\n *\n * If no valid conversion could be performed, a zero value is returned. If the\n * correct value is out of the range of representable values,\n * INT_MAX (2147483647) or INT_MIN (-2147483648) is returned.\n *\n */\n\n\n\npublic class StringToInteger8 {\n    public int myAtoi(String str) {\n        if (str == null || str.length() == 0) return 0;\n\n        long res = 0;  // Initialize result\n        int sign = 1;  // Initialize sign as positive\n        int i = 0;  // Initialize index of first digit\n        int L = str.length();\n\n\n        while (i < L && str.charAt(i) == ' ') {\n            i++;\n        }\n\n        // If number is negative, then update sign\n        boolean hasSign = false;\n        while (i < L) {\n            char c = str.charAt(i);\n            if (c == '-') {\n                if (hasSign) {\n                    return 0;\n                } else {\n                    sign = -1;\n                    i++;  // Also update index of first digit\n                    hasSign = true;\n                }\n            } else if (c == '+') {\n                if (hasSign) {\n                    return 0;\n                } else {\n                    i++;  // Also update index of first digit\n                    hasSign = true;\n                }\n            } else if (c == '0') {\n                i++;  // Also update index of first digit\n            } else {\n                break;\n            }\n        }\n\n        // Iterate through all digits of input string and update result\n        for (; i < L; ++i) {\n            if (isNumericChar(str.charAt(i)) == false) break;\n            res = res * 10 + str.charAt(i) - '0';\n            if (res > Integer.MAX_VALUE) break;\n        }\n\n        long r = sign*res;\n\n        if (r > Integer.MAX_VALUE) {\n            return Integer.MAX_VALUE;\n        } else if (r < Integer.MIN_VALUE) {\n            return Integer.MIN_VALUE;\n        }\n\n        return (int)r;\n    }\n\n    // A utility function to check whether x is numeric\n    private boolean isNumericChar(char x) {\n        return (x >= '0' && x <= '9') ? true : false;\n    }\n\n\n\n}\n"
  },
  {
    "path": "src/StrobogrammaticNumber246.java",
    "content": "/**\n * A strobogrammatic number is a number that looks the same when rotated 180\n * degrees (looked at upside down).\n * \n * Write a function to determine if a number is strobogrammatic. The number\n * is represented as a string.\n * \n * Example 1:\n * Input:  \"69\"\n * Output: true\n * \n * Example 2:\n * Input:  \"88\"\n * Output: true\n * \n * Example 3:\n * Input:  \"962\"\n * Output: false\n */\n\n\npublic class StrobogrammaticNumber246 {\n    public boolean isStrobogrammatic(String num) {\n        if (num == null || num.length() == 0) return true;\n        boolean[][] map = new boolean[10][10];\n        map[0][0] = true;\n        map[1][1] = true;\n        map[8][8] = true;\n        map[6][9] = true;\n        map[9][6] = true;\n        int len = num.length();\n        int l = 0;\n        int r = len-1;\n        char[] chars = num.toCharArray();\n        while (l <= r) {\n            if (!map[chars[l++]-'0'][chars[r--]-'0']) return false;\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/StrobogrammaticNumberII247.java",
    "content": "/**\n * A strobogrammatic number is a number that looks the same when rotated 180\n * degrees (looked at upside down).\n * \n * Find all strobogrammatic numbers that are of length = n.\n * \n * Example:\n * Input:  n = 2\n * Output: [\"11\",\"69\",\"88\",\"96\"]\n */\n\npublic class StrobogrammaticNumberII247 {\n    private char[] sames = new char[]{'0', '1', '8'};\n    private char six = '6';\n    private char nine = '9';\n    public List<String> findStrobogrammatic(int n) {\n        List<String> res = new ArrayList<>();\n        if (n == 0) {\n            res.add(\"\");\n            return res;\n        }\n        char[] chars = new char[n];\n        findStrobogrammatic(chars, 0, n-1, res);\n        return res;\n    }\n    \n    public void findStrobogrammatic(char[] chars, int left, int right, List<String> res) {\n        if (left > right) {\n            res.add(new String(chars));\n            return;\n        }\n        if (left == right) {\n            for (char c: sames) {\n                chars[left] = c;\n                res.add(new String(chars));\n            }\n            return;\n        }\n        \n        for (char c: sames) {\n            if (c == '0' && left == 0) continue;\n            chars[left] = c;\n            chars[right] = c;\n            findStrobogrammatic(chars, left+1, right-1, res);\n        }\n        chars[left] = six;\n        chars[right] = nine;\n        findStrobogrammatic(chars, left+1, right-1, res);\n        chars[left] = nine;\n        chars[right] = six;\n        findStrobogrammatic(chars, left+1, right-1, res);\n    }\n  \n}\n"
  },
  {
    "path": "src/SubarrayProductLessThanK713.java",
    "content": "/**\n * Your are given an array of positive integers nums.\n * \n * Count and print the number of (contiguous) subarrays where the product of\n * all the elements in the subarray is less than k.\n * \n * Example 1:\n * Input: nums = [10, 5, 2, 6], k = 100\n * Output: 8\n * Explanation: The 8 subarrays that have product less than 100 are:\n * [10], [5], [2], [6], [10, 5], [5, 2], [2, 6], [5, 2, 6].\n *\n * Note that [10, 5, 2] is not included as the product of 100 is not\n * strictly less than k.\n * \n * Note:\n * 0 < nums.length <= 50000.\n * 0 < nums[i] < 1000.\n * 0 <= k < 10^6.\n */\n\npublic class SubarrayProductLessThanK713 {\n    public int numSubarrayProductLessThanK(int[] nums, int k) {\n        if (nums == null || nums.length == 0 || k == 0) return 0;\n        int left = 0;\n        int right = 0;\n        int prod = 1;\n        int len = nums.length;\n        int res = 0;\n        while (right < len) {\n            prod *= nums[right];\n            while (prod >= k && left <= right) {\n                prod /= nums[left++];\n            }\n            res += right - left + 1;\n            right++;\n        }\n        return res;\n    }\n\n\n    public int numSubarrayProductLessThanK2(int[] nums, int k) {\n        if (nums == null || nums.length == 0 || k == 0) return 0;\n        int prod = 1;\n        int left = 0;\n        int right = 0;\n        int res = 0;\n        while (right < nums.length) {\n            prod *= nums[right];\n            while (left <= right && prod >= k) {\n                res += right - left;\n                prod /= nums[left++];\n            }\n            right++;\n        }\n        while (left < nums.length) {\n            res += right - left;\n            left++;\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/SubarraySumEqualsK560.java",
    "content": "/**\n * Given an array of integers and an integer k, you need to find the total\n * number of continuous subarrays whose sum equals to k.\n *\n * Example 1:\n * Input:nums = [1,1,1], k = 2\n * Output: 2\n *\n * Note:\n * The length of the array is in range [1, 20,000].\n * The range of numbers in the array is [-1000, 1000] and the range of the\n * integer k is [-1e7, 1e7].\n *\n */\n\n\npublic class SubarraySumEqualsK560 {\n    public int subarraySum(int[] nums, int k) {\n        int n = nums.length;\n        int res = 0;\n        int[] dp = new int[n];\n        for (int j=0; j<n; j++) {\n            for (int i=j; i>=0; i--) {\n                int curr = (i == j) ? nums[j] : dp[i] + nums[j];\n                dp[i] = curr;\n                if (curr == k) res++;\n            }\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/subarray-sum-equals-k/solution/\n     */\n    public int subarraySum2(int[] nums, int k) {\n        int count = 0;\n        int[] sum = new int[nums.length + 1];\n        sum[0] = 0;\n        for (int i = 1; i <= nums.length; i++)\n            sum[i] = sum[i - 1] + nums[i - 1];\n        for (int start = 0; start < nums.length; start++) {\n            for (int end = start + 1; end <= nums.length; end++) {\n                if (sum[end] - sum[start] == k)\n                    count++;\n            }\n        }\n        return count;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/subarray-sum-equals-k/solution/\n     */\n    public int subarraySum3(int[] nums, int k) {\n        int count = 0;\n        for (int start = 0; start < nums.length; start++) {\n            int sum=0;\n            for (int end = start; end < nums.length; end++) {\n                sum+=nums[end];\n                if (sum == k)\n                    count++;\n            }\n        }\n        return count;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/subarray-sum-equals-k/solution/\n     */\n    public int subarraySum4(int[] nums, int k) {\n        int count = 0, sum = 0;\n        HashMap < Integer, Integer > map = new HashMap < > ();\n        map.put(0, 1);\n        for (int i = 0; i < nums.length; i++) {\n            sum += nums[i];\n            if (map.containsKey(sum - k))\n                count += map.get(sum - k);\n            map.put(sum, map.getOrDefault(sum, 0) + 1);\n        }\n        return count;\n    }\n\n\n    public int subarraySum5(int[] nums, int k) {\n        Map<Integer, Set<Integer>> map = new HashMap<>();\n        int sum = 0;\n        for (int i=0; i<nums.length; i++) {\n            sum += nums[i];\n            if (!map.containsKey(sum)) {\n                map.put(sum, new HashSet<>());\n            }\n            map.get(sum).add(i);\n        }\n        \n        int res = 0;\n        sum = 0;\n        for (int i=0; i<nums.length; i++) {\n            if (map.containsKey(sum + k)) {\n                for (int idx: map.get(sum + k)) {\n                    if (idx >= i) res++;\n                }\n            }\n            sum += nums[i];\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/Subsequence.java",
    "content": "/**\n * \n */\n\nimport java.util.*;\n\npublic class Subsequence {\n\n    public List<String> subsequences(String target, String[] dict) {\n        List<String> res = new ArrayList<>();\n        for (String word: dict) {\n            if (target.length() <= word.length() && isSubsequence(target, word)) {\n                res.add(word);\n            }\n        }\n        return res;\n    }\n\n    public boolean isSubsequence(String s, String t) {\n        int i = 0;\n        int j = 0;\n        char[] chars = s.toCharArray();\n        char[] chart = t.toCharArray();\n        while (i < chars.length && j < chart.length) {\n            if (chars[i] == chart[j]) {\n                i++;\n                j++;\n            } else {\n                j++;\n            }\n        }\n        return i == chars.length;\n    }\n\n    public static void main(String[] args) {\n        Insertables ins = new Insertables();\n        System.out.println(ins.insertables(\"google\", new String[]{\"goooooogle\", \"ddgoogle\", \"abcd\", \"googles\"}));\n    }\n\n}\n"
  },
  {
    "path": "src/Subsets78.java",
    "content": "/**\n * Given a set of distinct integers, nums, return all possible subsets.\n *\n * Note: The solution set must not contain duplicate subsets.\n *\n * For example,\n * If nums = [1,2,3], a solution is:\n *\n * [\n *   [3],\n *   [1],\n *   [2],\n *   [1,2,3],\n *   [1,3],\n *   [2,3],\n *   [1,2],\n *   []\n * ]\n */\n\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n\npublic class Subsets78 {\n\n    /**\n     * https://discuss.leetcode.com/topic/46159/a-general-approach-to-backtracking-questions-in-java-subsets-permutations-combination-sum-palindrome-partitioning\n     */\n    public List<List<Integer>> subsets(int[] nums) {\n        List<List<Integer>> list = new ArrayList<>();\n        backtrack(list, new ArrayList<>(), nums, 0);\n        return list;\n    }\n\n    private void backtrack(List<List<Integer>> list , List<Integer> tempList, int [] nums, int start){\n        list.add(new ArrayList<>(tempList));\n        for(int i = start; i < nums.length; i++){\n            tempList.add(nums[i]);\n            backtrack(list, tempList, nums, i + 1);\n            tempList.remove(tempList.size() - 1);\n        }\n    }\n\n\n    public List<List<Integer>> subsets2(int[] nums) {\n        List<List<Integer>> res = new ArrayList<>();\n        if (nums == null) return res;\n        \n        res.add(new ArrayList<Integer>());\n        for (Integer n: nums) {\n            int size = res.size();\n            for (int i=0; i<size; i++) { \n                List<Integer> newList = new ArrayList<Integer>(res.get(i));\n                newList.add(n);\n                res.add(newList);\n            }\n        }\n\n        return res;\n    }\n\n\n    public static void main(String[] args) {\n        Subsets78 ss = new Subsets78();\n\n        System.out.println(ss.subsets(new int[]{1, 2, 3, 4}));\n        System.out.println(ss.subsets(new int[]{1, 2, 3}));\n    }\n\n\n}\n"
  },
  {
    "path": "src/SubsetsII90.java",
    "content": "/**\n * Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set).\n *\n * Note: The solution set must not contain duplicate subsets.\n *\n * For example,\n * If nums = [1,2,2], a solution is:\n *\n * [\n *   [2],\n *   [1],\n *   [1,2,2],\n *   [2,2],\n *   [1,2],\n *   []\n * ]\n */\n\n\npublic class SubsetsII90 {\n    public List<List<Integer>> subsetsWithDup(int[] nums) {\n        Set<List<Integer>> res = new HashSet<>();\n        Map<Integer, Integer> co = new HashMap<>();\n        helper(0, nums, co, res);\n        return new ArrayList<List<Integer>>(res);\n    }\n\n\n    public void helper(int pos, int[] nums, Map<Integer, Integer> co, Set<List<Integer>> res) {\n        if (pos >= nums.length) {\n            res.add(mapToList(co));\n            return;\n        }\n        res.add(mapToList(co));\n        helper(pos+1, nums, co, res);\n        co.put(nums[pos], co.getOrDefault(nums[pos], 0) + 1);\n        helper(pos+1, nums, co, res);\n        co.put(nums[pos], co.get(nums[pos]) - 1);\n    }\n\n    public List<Integer> mapToList(Map<Integer, Integer> co) {\n        List<Integer> l = new ArrayList<Integer>();\n        for (Map.Entry<Integer, Integer> e: co.entrySet()) {\n            for (int i=0; i<e.getValue(); i++) {\n                l.add(e.getKey());\n            }\n        }\n        return l;\n    }\n\n\n    public List<List<Integer>> subsetsWithDup2(int[] nums) {\n        Arrays.sort(nums);\n        Set<List<Integer>> res = new HashSet<>();\n        List<Integer> each = new ArrayList<>();\n        helper2(0, nums, each, res);\n        return new ArrayList<List<Integer>>(res);\n    }\n\n    public void helper2(int pos, int[] nums, List<Integer> each, Set<List<Integer>> res) {\n        if (pos >= nums.length) {\n            res.add(new ArrayList<Integer>(each));\n            return;\n        }\n        res.add(new ArrayList<Integer>(each));\n        helper(pos+1, nums, each, res);\n        each.add(nums[pos]);\n        helper(pos+1, nums, each, res);\n        each.remove(each.size()-1);\n    }\n\n\n    public List<List<Integer>> subsetsWithDup3(int[] nums) {\n        Arrays.sort(nums);\n        List<List<Integer>> res = new ArrayList<>();\n        helper3(0, nums, new ArrayList<>(), res);\n        return res;\n    }\n\n    public void helper3(int pos, int[] nums, List<Integer> each, List<List<Integer>> res) {\n        if (pos <= nums.length) res.add(new ArrayList<Integer>(each));\n\n        for(int i=pos; i < nums.length; i++){\n            if(i > pos && nums[i] == nums[i-1]) continue;\n            each.add(nums[i]);\n            helper(i+1, nums, each, res);\n            each.remove(each.size()-1);\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "src/SubtreeOfAnotherTree572.java",
    "content": "/**\n * Given two non-empty binary trees s and t, check whether tree t has exactly\n * the same structure and node values with a subtree of s. A subtree of s is a\n * tree consists of a node in s and all of this node's descendants. The tree s\n * could also be considered as a subtree of itself.\n *\n * Example 1:\n * Given tree s:\n *\n *      3\n *     / \\\n *    4   5\n *   / \\\n *  1   2\n * Given tree t:\n *    4\n *   / \\\n *  1   2\n * Return true, because t has the same structure and node values with a subtree of s.\n *\n * Example 2:\n * Given tree s:\n *\n *      3\n *     / \\\n *    4   5\n *   / \\\n *  1   2\n *     /\n *    0\n * Given tree t:\n *    4\n *   / \\\n *  1   2\n * Return false.\n *\n */\n\n\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class SubtreeOfAnotherTree572 {\n    public boolean isSubtree(TreeNode s, TreeNode t) {\n        if (s == null) return false;\n        if (isSame(s, t)) return true;\n        return isSubtree(s.left, t) || isSubtree(s.right, t);\n    }\n\n    public boolean isSame(TreeNode s, TreeNode t) {\n        if (s == null) return t == null;\n        if (t == null) return s == null;\n        if (s.val != t.val) return false;\n        return isSame(s.left, t.left) && isSame(s.right, t.right);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/subtree-of-another-tree/discuss/102760/Easy-O(n)-java-solution-using-preorder-traversal\n     */\n    public boolean isSubtree2(TreeNode s, TreeNode t) {\n        String spreorder = generatepreorderString(s); \n        String tpreorder = generatepreorderString(t);\n        return spreorder.contains(tpreorder) ;\n    }\n\n    public String generatepreorderString(TreeNode s){\n        StringBuilder sb = new StringBuilder();\n        Stack<TreeNode> stacktree = new Stack();\n        stacktree.push(s);\n        while(!stacktree.isEmpty()){\n           TreeNode popelem = stacktree.pop();\n           if(popelem==null)\n              sb.append(\",#\"); // Appending # inorder to handle same values but not subtree cases\n           else      \n              sb.append(\",\"+popelem.val);\n           if(popelem!=null){\n                stacktree.push(popelem.right);    \n                stacktree.push(popelem.left);  \n           }\n        }\n        return sb.toString();\n    }\n\n\n    /**\n     * https://leetcode.com/problems/subtree-of-another-tree/discuss/102736/Java-Concise-O(n+m)-Time-O(n+m)-Space\n     */\n    public boolean isSubtree3(TreeNode s, TreeNode t) {\n        return serialize(s).contains(serialize(t)); // Java uses a naive contains algorithm so to ensure linear time, \n                                                    // replace with KMP algorithm\n    }\n    \n    public String serialize(TreeNode root) {\n        StringBuilder res = new StringBuilder();\n        serialize(root, res);\n        return res.toString();\n    }\n    \n    private void serialize(TreeNode cur, StringBuilder res) {\n        if (cur == null) {res.append(\",#\"); return;}\n        res.append(\",\" + cur.val);\n        serialize(cur.left, res);\n        serialize(cur.right, res);\n    }\n\n}\n"
  },
  {
    "path": "src/SudokuSolver37.java",
    "content": "/**\n * Write a program to solve a Sudoku puzzle by filling the empty cells.\n *\n * Empty cells are indicated by the character '.'.\n *\n * You may assume that there will be only one unique solution.\n */\n\n\nimport java.util.Arrays;\nimport java.util.Map;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.Stack;\n\n\npublic class SudokuSolver37 {\n    public void solveSudoku(char[][] board) {\n        int L = board.length;\n        Map<Integer, Set<Character>> rows = new HashMap<>();\n        Map<Integer, Set<Character>> cols = new HashMap<>();\n        Map<Integer, Set<Character>> cells = new HashMap<>();\n        for (int l = 0; l < L; l++) {\n            rows.put(l, new HashSet<Character>());\n            cols.put(l, new HashSet<Character>());\n            cells.put(l, new HashSet<Character>());\n        }\n\n        for (int i = 0; i < L; i++) {\n            Set<Character> r = rows.get(i);\n            for (int j = 0; j < L; j++) {\n                char c = board[i][j];\n                if (c != '.') {\n                    Set<Character> co = cols.get(j);\n                    Set<Character> ce = cells.get((i/3) * 3 + j/3);\n                    r.add(c);\n                    co.add(c);\n                    ce.add(c);\n                }\n            }\n        }\n\n        Stack<List<Integer>> st = new Stack<>();\n        int x = 0;\n        int y = 0;\n\n        while (x < L) {\n            // System.out.println(x + \", \" + y);\n            if (board[x][y] == '.') {\n                boolean found = false;\n\n                for (int n = 49; n<=57; n++) {\n                    char c = (char)n;\n                    if (!rows.get(x).contains(c) &&\n                            !cols.get(y).contains(c) &&\n                            !cells.get(cellPos(x, y)).contains(c)) {\n                        board[x][y] = c;\n                        // System.out.println(x + \", \" + y + \",    get: \" + c);\n                        rows.get(x).add(c);\n                        cols.get(y).add(c);\n                        cells.get(cellPos(x, y)).add(c);\n                        st.push(Arrays.asList(x, y));\n                        found = true;\n                        break;\n                    }\n                }\n\n                if (!found) {\n                    char newChar = (char)58;\n                    while ((int)newChar > 57) {\n                        List<Integer> p = st.peek();\n                        x = p.get(0);\n                        y = p.get(1);\n                        char old = board[x][y];\n                        // System.out.println(x + \", \" + y + \",    old: \" + old);\n\n                        while (old == '9') {\n                            rows.get(x).remove(old);\n                            cols.get(y).remove(old);\n                            cells.get(cellPos(x, y)).remove(old);\n                            st.pop();\n                            board[x][y] = '.';\n                            p = st.peek();\n                            x = p.get(0);\n                            y = p.get(1);\n                            old = board[x][y];\n                            // System.out.println(x + \", \" + y + \",    old: \" + old);\n                        }\n                        rows.get(x).remove(old);\n                        cols.get(y).remove(old);\n                        cells.get(cellPos(x, y)).remove(old);\n                        newChar = (char)(old + 1);\n                        // System.out.println(x + \", \" + y + \",    new: \" + newChar);\n                        while ((rows.get(x).contains(newChar) ||\n                                cols.get(y).contains(newChar) ||\n                                cells.get(cellPos(x, y)).contains(newChar)) && (int)newChar <= 57) {\n                            newChar = (char)(newChar + 1);\n                            // System.out.println(x + \", \" + y + \",    new: \" + newChar);\n                        }\n                        if ((int)newChar > 57) {\n                            st.pop();\n                            board[x][y] = '.';\n                        }\n                    }\n                    board[x][y] = newChar;\n                    rows.get(x).add(newChar);\n                    cols.get(y).add(newChar);\n                    cells.get(cellPos(x, y)).add(newChar);\n                    // System.out.println(x + \", \" + y + \",    new: \" + newChar);\n                }\n            }\n\n            if (y < L-1) {\n                y++;\n            } else {\n                y = 0;\n                x++;\n            }\n        }\n\n    }\n\n    private int cellPos(int x, int y) {\n        return (x/3) * 3 + y/3;\n    }\n\n\n    /**\n     * https://leetcode.com/submissions/detail/105414901/\n     */\n    public void solveSudoku2(char[][] board) {\n        if(board == null || board.length == 0)\n            return;\n        solve(board);\n    }\n\n    public boolean solve(char[][] board){\n        for(int i = 0; i < board.length; i++){\n            for(int j = 0; j < board[0].length; j++){\n                if(board[i][j] == '.'){\n                    for(char c = '1'; c <= '9'; c++){//trial. Try 1 through 9\n                        if(isValid(board, i, j, c)){\n                            board[i][j] = c; //Put c for this cell\n\n                            if(solve(board))\n                                return true; //If it's the solution return true\n                            else\n                                board[i][j] = '.'; //Otherwise go back\n                        }\n                    }\n\n                    return false;\n                }\n            }\n        }\n        return true;\n    }\n\n    private boolean isValid(char[][] board, int row, int col, char c){\n        for(int i = 0; i < 9; i++) {\n            if(board[i][col] != '.' && board[i][col] == c) return false; //check row\n            if(board[row][i] != '.' && board[row][i] == c) return false; //check column\n            if(board[3 * (row / 3) + i / 3][ 3 * (col / 3) + i % 3] != '.' &&\n    board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == c) return false; //check 3*3 block\n        }\n        return true;\n    }\n\n\n    public static void main(String[] args) {\n        SudokuSolver37 ss = new SudokuSolver37();\n\n        char[][] board = new char[][]{\n            {'.', '.', '9', '7', '4', '8', '.', '.', '.'},\n            {'7', '.', '.', '.', '.', '.', '.', '.', '.'},\n            {'.', '2', '.', '1', '.', '9', '.', '.', '.'},\n            {'.', '.', '7', '.', '.', '.', '2', '4', '.'},\n            {'.', '6', '4', '.', '1', '.', '5', '9', '.'},\n            {'.', '9', '8', '.', '.', '.', '3', '.', '.'},\n            {'.', '.', '.', '8', '.', '3', '.', '2', '.'},\n            {'.', '.', '.', '.', '.', '.', '.', '.', '6'},\n            {'.', '.', '.', '2', '7', '5', '9', '.', '.'},\n        };\n\n        for (int i=0; i<9; i++) {\n            System.out.println(Arrays.toString(board[i]));\n        }\n        System.out.println(\"\\n\");\n\n        ss.solveSudoku(board);\n\n        for (int j=0; j<9; j++) {\n            System.out.println(Arrays.toString(board[j]));\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/SumOfSquareNumbers633.java",
    "content": "/**\n * Given a non-negative integer c, your task is to decide whether there're two\n * integers a and b such that a2 + b2 = c.\n * \n * Example 1:\n * Input: 5\n * Output: True\n * Explanation: 1 * 1 + 2 * 2 = 5\n * \n * Example 2:\n * Input: 3\n * Output: False\n */\n\npublic class SumOfSquareNumbers633 {\n    public boolean judgeSquareSum(int c) {\n        if (c < 0) return false;\n        int n = (int) Math.sqrt(c);\n        for (int i=0; i<=n; i++) {\n            int re = c - i * i;\n            int sq = (int) Math.sqrt(re);\n            if (sq * sq == re) return true;\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/SumRootToLeafNumbers129.java",
    "content": "/**\n * Given a binary tree containing digits from 0-9 only, each root-to-leaf path\n * could represent a number.\n *\n * An example is the root-to-leaf path 1->2->3 which represents the number 123.\n *\n * Find the total sum of all root-to-leaf numbers.\n *\n * For example,\n *\n *     1\n *    / \\\n *   2   3\n * The root-to-leaf path 1->2 represents the number 12.\n * The root-to-leaf path 1->3 represents the number 13.\n *\n * Return the sum = 12 + 13 = 25.\n *\n *\n */\n\n\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\n\npublic class SumRootToLeafNumbers129 {\n    public int sumNumbers(TreeNode root) {\n        if (root == null) {\n            return 0;\n        }\n\n        return helper(root, new ArrayList<Integer>(), 0);\n    }\n\n    public int helper(TreeNode node, List<Integer> path, int sum) {\n        if (node == null) {\n            return sum;\n        }\n\n        path.add(node.val);\n        if (node.left == null && node.right == null) {\n            int newSum = 0;\n            for (int i = 0; i < path.size(); i++) {\n                newSum += path.get(i) * (int) Math.pow(10, (path.size() - 1 - i));\n            }\n            path.remove(path.size() - 1);\n            return sum + newSum;\n        }\n\n        sum = helper(node.left, path, sum);\n        sum = helper(node.right, path, sum);\n\n        path.remove(path.size() - 1);\n        return sum;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/6731/short-java-solution-recursion/17\n     */\n    public int sumNumbers(TreeNode root) {\n    \t return sum(root, 0);\n    }\n\n    public int sum(TreeNode n, int s){\n    \t  if (n == null) return 0;\n    \t  if (n.right == null && n.left == null) return s*10 + n.val;\n    \t  return sum(n.left, s*10 + n.val) + sum(n.right, s*10 + n.val);\n    }\n\n\n}\n"
  },
  {
    "path": "src/SummaryRanges228.java",
    "content": "/**\n * Given a sorted integer array without duplicates, return the summary of\n * its ranges.\n * \n * Example 1:\n * Input:  [0,1,2,4,5,7]\n * Output: [\"0->2\",\"4->5\",\"7\"]\n * Explanation: 0,1,2 form a continuous range; 4,5 form a continuous range.\n * \n * Example 2:\n * Input:  [0,2,3,4,6,8,9]\n * Output: [\"0\",\"2->4\",\"6\",\"8->9\"]\n * Explanation: 2,3,4 form a continuous range; 8,9 form a continuous range.\n */\n\npublic class SummaryRanges228 {\n    public List<String> summaryRanges(int[] arr) {\n        List<String> res = new ArrayList<>();\n        if (arr == null || arr.length == 0) return res;\n        if (arr.length == 1) {\n            res.add(Integer.toString(arr[0]));\n            return res;\n        }\n    \n        int len = arr.length;\n        int i = 0;\n        int j = 1;\n        while (j <= len) {\n            if (j == len || arr[j] - arr[j-1] != 1) {\n                if (j-1 <= i) {\n                    res.add(Integer.toString(arr[i]));\n                } else {\n                    res.add(arr[i] + \"->\" + arr[j-1]);\n                }\n                i = j;\n            }\n            j++;\n        }\n    \n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/SuperUglyNumber313.java",
    "content": "/**\n * Write a program to find the nth super ugly number.\n * \n * Super ugly numbers are positive numbers whose all prime factors are in the\n * given prime list primes of size k.\n * \n * Example:\n * Input: n = 12, primes = [2,7,13,19]\n * Output: 32 \n * Explanation: [1,2,4,7,8,13,14,16,19,26,28,32] is the sequence of the first 12 \n *              super ugly numbers given primes = [2,7,13,19] of size 4.\n * \n * Note:\n * 1 is a super ugly number for any given primes.\n * The given numbers in primes are in ascending order.\n * 0 < k ≤ 100, 0 < n ≤ 106, 0 < primes[i] < 1000.\n * The nth super ugly number is guaranteed to fit in a 32-bit signed integer.\n */\n\npublic class SuperUglyNumber313 {\n    public int nthSuperUglyNumber(int n, int[] primes) {\n        if (n <= 0) return -1;\n        int[] dp = new int[n];\n        dp[0] = 1;\n        int[] pointers = new int[primes.length];\n        for (int i=1; i<n; i++) {\n            int t = Integer.MAX_VALUE;\n            for (int j=0; j<primes.length; j++) {\n                if (dp[pointers[j]] * primes[j] < t) {\n                    t = dp[pointers[j]] * primes[j];\n                }\n            }\n            for (int j=0; j<primes.length; j++) {\n                if (dp[pointers[j]] * primes[j] == t) pointers[j]++;\n            }\n            dp[i] = t;\n        }\n        return dp[n-1];\n    }\n\n\n    public int nthSuperUglyNumber2(int n, int[] primes) {\n        if (n <= 0) return -1;\n        int[] dp = new int[n];\n        dp[0] = 1;\n        int[] pointers = new int[primes.length];\n        for (int i=1; i<n; i++) {\n            int t = Integer.MAX_VALUE;\n            int idx = -1;\n            for (int j=0; j<primes.length; j++) {\n                int now = dp[pointers[j]] * primes[j];\n                if (now < t) {\n                    t = dp[pointers[j]] * primes[j];\n                    idx = j;\n                } else if (now == t) {\n                    pointers[j]++;\n                }\n            }\n            pointers[idx]++;\n            dp[i] = t;\n        }\n        return dp[n-1];\n    }\n\n}\n"
  },
  {
    "path": "src/SurroundedRegions130.java",
    "content": "/**\n * Given a 2D board containing 'X' and 'O' (the letter O), capture all regions\n * surrounded by 'X'.\n *\n * A region is captured by flipping all 'O's into 'X's in that surrounded region.\n *\n * For example,\n * X X X X\n * X O O X\n * X X O X\n * X O X X\n *\n * After running your function, the board should be:\n * X X X X\n * X X X X\n * X X X X\n * X O X X\n */\n\n\npublic class SurroundedRegions130 {\n    public void solve(char[][] board) {\n        int m = board.length;\n        if (m == 0) {\n            return;\n        }\n        int n = board[0].length;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < n; j++) {\n                if ((i == 0 || j == 0 || i == m - 1 || j == n - 1) && board[i][j] == 'O') {\n                    markBoundary(board, i, j);\n                }\n            }\n        }\n\n\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < n; j++) {\n                if (board[i][j] == 'O') {\n                    board[i][j] = 'X';\n                } else if (board[i][j] == '*') {\n                    board[i][j] = 'O';\n                }\n            }\n        }\n    }\n\n    private void markBoundary(char[][] board, int i, int j) {\n        if (i < 0 || i > board.length-1 || j < 0 || j > board[0].length-1 || board[i][j] != 'O') {\n            return;\n        }\n        board[i][j] = '*';\n\n        if (j < board[0].length - 2)\n            markBoundary(board, i, j+1);\n        if (i < board.length - 2)\n            markBoundary(board, i+1, j);\n        if (j > 1)\n            markBoundary(board, i, j-1);\n        if (i > 1)\n            markBoundary(board, i-1, j);\n    }\n\n    private void markBoundary2(char[][] board, int i, int j) {\n        board[i][j] = '*';\n        int[] dx = {-1, 0, 0, 1};\n        int[] dy = {0, -1, 1, 0};\n\n        for (int k = 0; k < dx.length; k++) {\n            int x = dx[k] + i;\n            int y = dy[k] + j;\n            if (x > 0 && x < board.length - 1 && y > 0 && y < board[0].length - 1 && board[x][y] == 'O') {\n                markBoundary2(board, x, y);\n            }\n        }\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/35191/java-easy-version-to-understand/4\n     */\n    public static void solve2(char[][] board) {\n    \tif (board == null || board.length == 0)\n    \t\treturn;\n    \tint rows = board.length, columns = board[0].length;\n    \tint[][] direction = { { -1, 0 }, { 1, 0 }, { 0, 1 }, { 0, -1 } };\n    \tfor (int i = 0; i < rows; i++)\n    \t\tfor (int j = 0; j < columns; j++) {\n    \t\t\tif ((i == 0 || i == rows - 1 || j == 0 || j == columns - 1) && board[i][j] == 'O') {\n    \t\t\t\tQueue<Point> queue = new LinkedList<>();\n    \t\t\t\tboard[i][j] = 'B';\n    \t\t\t\tqueue.offer(new Point(i, j));\n    \t\t\t\twhile (!queue.isEmpty()) {\n    \t\t\t\t\tPoint point = queue.poll();\n    \t\t\t\t\tfor (int k = 0; k < 4; k++) {\n    \t\t\t\t\t\tint x = direction[k][0] + point.x;\n    \t\t\t\t\t\tint y = direction[k][1] + point.y;\n    \t\t\t\t\t\tif (x >= 0 && x < rows && y >= 0 && y < columns && board[x][y] == 'O') {\n    \t\t\t\t\t\t\tboard[x][y] = 'B';\n    \t\t\t\t\t\t\tqueue.offer(new Point(x, y));\n    \t\t\t\t\t\t}\n    \t\t\t\t\t}\n    \t\t\t\t}\n    \t\t\t}\n    \t\t}\n    \tfor (int i = 0; i < rows; i++)\n    \t\tfor (int j = 0; j < columns; j++) {\n    \t\t\tif (board[i][j] == 'B')\n    \t\t\t\tboard[i][j] = 'O';\n    \t\t\telse if (board[i][j] == 'O')\n    \t\t\t\tboard[i][j] = 'X';\n    \t\t}\n\n    }\n\n\n}\n"
  },
  {
    "path": "src/SwapAdjacentInLRString777.java",
    "content": "/**\n * In a string composed of 'L', 'R', and 'X' characters, like \"RXXLRXRXL\", a\n * move consists of either replacing one occurrence of \"XL\" with \"LX\", or\n * replacing one occurrence of \"RX\" with \"XR\". Given the starting string start\n * and the ending string end, return True if and only if there exists a\n * sequence of moves to transform one string to the other.\n * \n * Example:\n * Input: start = \"RXXLRXRXL\", end = \"XRLXXRRLX\"\n * Output: True\n * \n * Explanation:\n * We can transform start to end following these steps:\n * RXXLRXRXL ->\n * XRXLRXRXL ->\n * XRLXRXRXL ->\n * XRLXXRRXL ->\n * XRLXXRRLX\n * \n * Note:\n * 1 <= len(start) = len(end) <= 10000.\n * Both start and end will only consist of characters in {'L', 'R', 'X'}.\n */\n\n\npublic class SwapAdjacentInLRString777 {\n    public boolean canTransform(String start, String end) {\n        int len = start.length();\n        char[] starts = start.toCharArray();\n        char[] ends = end.toCharArray();\n        int ps = 0;\n        int pe = 0;\n        while (ps < len) {\n            while (ps < len && starts[ps] == 'X') {\n                ps++;\n            }\n            if (ps == len) break;\n\n            while (pe < len && ends[pe] == 'X') {\n                pe++;\n            }\n            if (pe == len) return false;\n\n            if (starts[ps] == 'R') {\n                if (ends[pe] != 'R' || pe < ps) return false;\n            } else { // starts[ps] == 'L'\n                if (ends[pe] != 'L' || pe > ps) return false;\n            }\n            ps++;\n            pe++;\n        }\n\n        while (pe < len) {\n            if (ends[pe++] != 'X') return false;\n        }\n\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/swap-adjacent-in-lr-string/discuss/114737/Simple-Java-Solution\n     */\n    public boolean canTransform2(String start, String end) {\n        int r = 0;\n        int l = 0;\n        for (int i = 0; i < start.length(); i++){\n            if (start.charAt(i) == 'L') l++;\n            if (start.charAt(i) == 'R') r++;\n            if (end.charAt(i) == 'L') l--;\n            if (end.charAt(i) == 'R') r--;\n            if (l > 0 || r < 0 || (r > 0 && l != 0)) {\n                return false;\n            }\n        }\n        return l == 0 && r == 0;\n    }\n\n\n}\n"
  },
  {
    "path": "src/SymmetricTree101.java",
    "content": "/**\n * Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).\n *\n * For example, this binary tree [1,2,2,3,4,4,3] is symmetric:\n *\n *     1\n *    / \\\n *   2   2\n *  / \\ / \\\n * 3  4 4  3\n *\n * But the following [1,2,2,null,3,null,3] is not:\n *     1\n *    / \\\n *   2   2\n *    \\   \\\n *    3    3\n *\n * Note:\n * Bonus points if you could solve it both recursively and iteratively.\n *\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\n\npublic class SymmetricTree101 {\n    public boolean isSymmetric(TreeNode root) {\n        if (root == null || (root.left == null && root.right == null)) return true;\n\n        LinkedList<TreeNode> queue = new LinkedList<>();\n        queue.add(root.left);\n        queue.add(root.right);\n\n        int i = 1;\n        while (!queue.isEmpty()) {\n            Stack<TreeNode> st = new Stack<>();\n            i = queue.size() >> 1;\n\n            int k = 0;\n            while (k<i) {\n                if (queue.isEmpty()) return false;\n                TreeNode node = queue.remove();\n                if (node != null) {\n                    queue.add(node.left);\n                    queue.add(node.right);\n                }\n                st.push(node);\n                k++;\n            }\n\n            k = 0;\n            while (k<i) {\n                if (queue.isEmpty()) return false;\n                TreeNode node = queue.remove();\n                TreeNode pre = st.pop();\n                if (node != null) {\n                    if (pre == null || node.val != pre.val) return false;\n                    queue.add(node.left);\n                    queue.add(node.right);\n                } else if (pre != null) {\n                    return false;\n                }\n                k++;\n            }\n        }\n\n        return true;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/5941/recursive-and-non-recursive-solutions-in-java\n     */\n    public boolean isSymmetric2(TreeNode root) {\n        if (root==null)  return true;\n\n        Stack<TreeNode> stack = new Stack<TreeNode>();\n        TreeNode left, right;\n        if (root.left != null) {\n            if (root.right == null) return false;\n            stack.push(root.left);\n            stack.push(root.right);\n        } else if (root.right != null) {\n            return false;\n        }\n\n        while (!stack.empty()) {\n            if (stack.size()%2 != 0)   return false;\n            right = stack.pop();\n            left = stack.pop();\n            if(right.val != left.val) return false;\n\n            if (left.left != null) {\n                if(right.right == null)   return false;\n                stack.push(left.left);\n                stack.push(right.right);\n            } else if(right.right != null){\n                return false;\n            }\n\n            if (left.right != null) {\n                if(right.left == null)   return false;\n                stack.push(left.right);\n                stack.push(right.left);\n            } else if(right.left != null) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/5941/recursive-and-non-recursive-solutions-in-java\n     */\n    public boolean isSymmetric3(TreeNode root) {\n        return root==null || isSymmetricHelp(root.left, root.right);\n    }\n\n    private boolean isSymmetricHelp(TreeNode left, TreeNode right){\n        if(left==null || right==null)\n            return left==right;\n        if(left.val!=right.val)\n            return false;\n        return isSymmetricHelp(left.left, right.right) && isSymmetricHelp(left.right, right.left);\n    }\n\n}\n"
  },
  {
    "path": "src/TargetSum494.java",
    "content": "/**\n * You are given a list of non-negative integers, a1, a2, ..., an, and a\n * target, S. Now you have 2 symbols + and -. For each integer, you should\n * choose one from + and - as its new symbol.\n * \n * Find out how many ways to assign symbols to make sum of integers equal to\n * target S.\n * \n * Example 1:\n * Input: nums is [1, 1, 1, 1, 1], S is 3. \n * Output: 5\n * \n * Explanation:\n * -1+1+1+1+1 = 3\n * +1-1+1+1+1 = 3\n * +1+1-1+1+1 = 3\n * +1+1+1-1+1 = 3\n * +1+1+1+1-1 = 3\n * \n * There are 5 ways to assign symbols to make the sum of nums be target 3.\n * \n * Note:\n * The length of the given array is positive and will not exceed 20.\n * The sum of elements in the given array will not exceed 1000.\n * Your output answer is guaranteed to be fitted in a 32-bit integer.\n */\n\npublic class TargetSum494 {\n    public int findTargetSumWays(int[] nums, int S) {\n        if (S > 1000 || S < -1000) return 0;\n        int N = nums.length;\n        int[][] dp = new int[N+1][2001];\n\n        dp[0][1000] = 1;\n        for (int i=1; i<=N; i++) {\n            int n = nums[i-1];\n            for (int j=0; j<2001; j++) {\n                dp[i][j] = (j+n < 2001 ? dp[i-1][j+n] : 0) + (j-n >=0 ? dp[i-1][j-n] : 0);\n            }\n        }\n\n        return dp[N][S + 1000];\n    }\n\n    public int findTargetSumWays2(int[] nums, int S) {\n        if (S > 1000 || S < -1000) return 0;\n        int N = nums.length;\n        int[] dp = new int[2001];\n\n        dp[1000] = 1;\n        for (int i=1; i<=N; i++) {\n            int n = nums[i-1];\n            int[] tmp = new int[2001];\n            for (int j=0; j<2001; j++) tmp[j] = dp[j];\n            for (int j=0; j<2001; j++) {\n                dp[j] = (j+n < 2001 ? tmp[j+n] : 0) + (j-n >=0 ? tmp[j-n] : 0);\n            }\n        }\n\n        return dp[S + 1000];\n    }\n\n\n    /**\n     * https://leetcode.com/problems/target-sum/solution/\n     */\n    public int findTargetSumWays3(int[] nums, int S) {\n        int[][] dp = new int[nums.length][2001];\n        dp[0][nums[0] + 1000] = 1;\n        dp[0][-nums[0] + 1000] += 1;\n        for (int i = 1; i < nums.length; i++) {\n            for (int sum = -1000; sum <= 1000; sum++) {\n                if (dp[i - 1][sum + 1000] > 0) {\n                    dp[i][sum + nums[i] + 1000] += dp[i - 1][sum + 1000];\n                    dp[i][sum - nums[i] + 1000] += dp[i - 1][sum + 1000];\n                }\n            }\n        }\n        return S > 1000 ? 0 : dp[nums.length - 1][S + 1000];\n    }\n\n\n    /**\n     * https://leetcode.com/problems/target-sum/solution/\n     */\n    public int findTargetSumWays4(int[] nums, int S) {\n        int[] dp = new int[2001];\n        dp[nums[0] + 1000] = 1;\n        dp[-nums[0] + 1000] += 1;\n        for (int i = 1; i < nums.length; i++) {\n            int[] next = new int[2001];\n            for (int sum = -1000; sum <= 1000; sum++) {\n                if (dp[sum + 1000] > 0) {\n                    next[sum + nums[i] + 1000] += dp[sum + 1000];\n                    next[sum - nums[i] + 1000] += dp[sum + 1000];\n                }\n            }\n            dp = next;\n        }\n        return S > 1000 ? 0 : dp[S + 1000];\n    }\n\n}\n"
  },
  {
    "path": "src/TaskScheduler621.java",
    "content": "/**\n * Given a char array representing tasks CPU need to do. It contains capital\n * letters A to Z where different letters represent different tasks.Tasks could\n * be done without original order. Each task could be done in one interval.\n * For each interval, CPU could finish one task or just be idle.\n *\n * However, there is a non-negative cooling interval n that means between two\n * same tasks, there must be at least n intervals that CPU are doing different\n * tasks or just be idle.\n *\n * You need to return the least number of intervals the CPU will take to finish\n * all the given tasks.\n *\n * Example 1:\n * Input: tasks = [\"A\",\"A\",\"A\",\"B\",\"B\",\"B\"], n = 2\n * Output: 8\n *\n * Explanation: A -> B -> idle -> A -> B -> idle -> A -> B.\n * Note:\n * The number of tasks is in the range [1, 10000].\n * The integer n is in the range [0, 100].\n *\n */\n\n/**\n *  Note that the names of the tasks are irrelevant for obtaining the solution\n *  of the given problem. The time taken for the tasks to be finished is only\n *  dependent on the number of instances of each task and not on the names of\n *  tasks.\n */\n\n\npublic class TaskScheduler621 {\n    /**\n     * https://leetcode.com/problems/task-scheduler/solution/\n     */\n    public int leastInterval(char[] tasks, int n) {\n        int[] map = new int[26];\n        for (char c: tasks)\n            map[c - 'A']++;\n        Arrays.sort(map);\n\n        int maxVal = map[25] - 1;\n        int idles = maxVal * n;\n        for (int i = 24; i >= 0 && map[i] > 0; i--) {\n            idles -= Math.min(map[i], maxVal);\n        }\n        return idles > 0 ? idles + tasks.length : tasks.length;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/92852/concise-java-solution-o-n-time-o-26-space\n     */\n    public int leastInterval2(char[] tasks, int n) {\n        int[] c = new int[26];\n        for(char t : tasks){\n            c[t - 'A']++;\n        }\n        Arrays.sort(c);\n        int i = 25;\n        while(i >= 0 && c[i] == c[25]) i--;\n\n        return Math.max(tasks.length, (c[25] - 1) * (n + 1) + 25 - i);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/task-scheduler/solution/\n     */\n    public int leastInterval3(char[] tasks, int n) {\n        int[] map = new int[26];\n        for (char c: tasks)\n            map[c - 'A']++;\n        Arrays.sort(map);\n        int time = 0;\n        while (map[25] > 0) {\n            int i = 0;\n            while (i <= n) {\n                if (map[25] == 0)\n                    break;\n                if (i < 26 && map[25 - i] > 0)\n                    map[25 - i]--;\n                time++;\n                i++;\n            }\n            Arrays.sort(map);\n        }\n        return time;\n    }\n\n\n    public int leastInterval4(char[] tasks, int n) {\n        int N = tasks.length;\n        int[] count = new int[26];\n        int max = -1;\n        int maxCount = -1;\n        for (char ch: tasks) {\n            count[ch-'A']++;\n            if (count[ch-'A'] == max) {\n                maxCount++;\n            } else if (count[ch-'A'] > max) {\n                max = count[ch-'A'];\n                maxCount = 1;\n            }\n        }\n        return Math.max((n+1) * (max-1) + maxCount, N);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/task-scheduler/discuss/104500/Java-O(n)-time-O(1)-space-1-pass-no-sorting-solution-with-detailed-explanation\n     */\n    public int leastInterval5(char[] tasks, int n) {\n        int[] counter = new int[26];\n        int max = 0;\n        int maxCount = 0;\n        for(char task : tasks) {\n            counter[task - 'A']++;\n            if(max == counter[task - 'A']) {\n                maxCount++;\n            }\n            else if(max < counter[task - 'A']) {\n                max = counter[task - 'A'];\n                maxCount = 1;\n            }\n        }\n        int partCount = max - 1;\n        int partLength = n - (maxCount - 1);\n        int emptySlots = partCount * partLength;\n        int availableTasks = tasks.length - max * maxCount;\n        int idles = Math.max(0, emptySlots - availableTasks);\n        \n        return tasks.length + idles;\n    }\n\n}\n"
  },
  {
    "path": "src/TextJustification68.java",
    "content": "/**\n * Given an array of words and a width maxWidth, format the text such that each\n * line has exactly maxWidth characters and is fully (left and right) justified.\n * \n * You should pack your words in a greedy approach; that is, pack as many words\n * as you can in each line. Pad extra spaces ' ' when necessary so that each\n * line has exactly maxWidth characters.\n * \n * Extra spaces between words should be distributed as evenly as possible. If\n * the number of spaces on a line do not divide evenly between words, the empty\n * slots on the left will be assigned more spaces than the slots on the right.\n * \n * For the last line of text, it should be left justified and no extra space is\n * inserted between words.\n * \n * Note:\n * A word is defined as a character sequence consisting of non-space characters only.\n * Each word's length is guaranteed to be greater than 0 and not exceed maxWidth.\n * The input array words contains at least one word.\n * \n * Example 1:\n * Input:\n * words = [\"This\", \"is\", \"an\", \"example\", \"of\", \"text\", \"justification.\"]\n * maxWidth = 16\n * Output:\n * [\n *    \"This    is    an\",\n *    \"example  of text\",\n *    \"justification.  \"\n * ]\n * \n * Example 2:\n * Input:\n * words = [\"What\",\"must\",\"be\",\"acknowledgment\",\"shall\",\"be\"]\n * maxWidth = 16\n * Output:\n * [\n *   \"What   must   be\",\n *   \"acknowledgment  \",\n *   \"shall be        \"\n * ]\n * Explanation: Note that the last line is \"shall be    \" instead of \"shall     be\",\n * because the last line must be left-justified instead of fully-justified.\n * Note that the second line is also left-justified becase it contains only one word.\n * \n * Example 3:\n * Input:\n * words = [\"Science\",\"is\",\"what\",\"we\",\"understand\",\"well\",\"enough\",\"to\",\n * \"explain\",\"to\",\"a\",\"computer.\",\"Art\",\"is\",\"everything\",\"else\",\"we\",\"do\"]\n * maxWidth = 20\n * Output:\n * [\n *   \"Science  is  what we\",\n *   \"understand      well\",\n *   \"enough to explain to\",\n *   \"a  computer.  Art is\",\n *   \"everything  else  we\",\n *   \"do                  \"\n * ]\n */\n\nimport java.util.*;\n\npublic class TextJustification68 {\n    public List<String> fullJustify(String[] words, int maxWidth) {\n        List<String> res = new ArrayList<>();\n        int i = 0;\n        int N = words.length;\n        while (i < N) {\n            int spaceLeft = maxWidth;\n            int wordsLen = 0;\n            List<String> line = new ArrayList<>();\n            while (i < N) {\n                if (words[i].length() > spaceLeft) break;\n                line.add(words[i]);\n                wordsLen += words[i].length();\n                spaceLeft -= words[i].length() + 1;\n                i++;\n            }\n            StringBuilder sb = new StringBuilder();\n            if (i == N || line.size() == 1) {\n                res.add(leftJustify(line, maxWidth));\n            } else {\n                res.add(middleJustify(line, maxWidth, wordsLen));\n            }\n        }\n        return res;\n    }\n\n    private String leftJustify(List<String> line, int maxWidth) {\n        StringBuilder sb = new StringBuilder();\n        for (String w: line) {\n            sb.append(w);\n            if (sb.length() < maxWidth) sb.append(' ');\n        }\n        while (sb.length() < maxWidth) {\n            sb.append(' ');\n        }\n        return sb.toString();\n    }\n\n    private String middleJustify(List<String> line, int maxWidth, int wordsLen) {\n        StringBuilder sb = new StringBuilder();\n        int n = line.size();\n        int spaces = maxWidth - wordsLen;\n        int interval = spaces / (n-1);\n        int rest = spaces - interval * (n-1);\n        for (int k=0; k<n; k++) {\n            sb.append(line.get(k));\n            int p = interval;\n            while (p > 0 && sb.length() < maxWidth) {\n                sb.append(' ');\n                p--;\n            }\n            if (rest > 0 && sb.length() < maxWidth) {\n                sb.append(' ');\n                rest--;\n            }\n        }\n        return sb.toString();\n    }\n\n}\n"
  },
  {
    "path": "src/TheMaze490.java",
    "content": "/**\n * There is a ball in a maze with empty spaces and walls. The ball can go\n * through empty spaces by rolling up, down, left or right, but it won't stop\n * rolling until hitting a wall. When the ball stops, it could choose the next\n * direction.\n * \n * Given the ball's start position, the destination and the maze, determine\n * whether the ball could stop at the destination.\n * \n * The maze is represented by a binary 2D array. 1 means the wall and 0 means\n * the empty space. You may assume that the borders of the maze are all walls.\n * The start and destination coordinates are represented by row and column\n * indexes.\n * \n * Example 1\n * \n * Input 1: a maze represented by a 2D array\n * \n * 0 0 1 0 0\n * 0 0 0 0 0\n * 0 0 0 1 0\n * 1 1 0 1 1\n * 0 0 0 0 0\n * \n * Input 2: start coordinate (rowStart, colStart) = (0, 4)\n * Input 3: destination coordinate (rowDest, colDest) = (4, 4)\n * \n * Output: true\n * Explanation: One possible way is : left -> down -> left -> down -> right -> down -> right.\n * https://leetcode.com/static/images/problemset/maze_1_example_1.png\n * \n * Example 2\n * \n * Input 1: a maze represented by a 2D array\n * \n * 0 0 1 0 0\n * 0 0 0 0 0\n * 0 0 0 1 0\n * 1 1 0 1 1\n * 0 0 0 0 0\n * \n * Input 2: start coordinate (rowStart, colStart) = (0, 4)\n * Input 3: destination coordinate (rowDest, colDest) = (3, 2)\n * \n * Output: false\n * Explanation: There is no way for the ball to stop at the destination.\n * https://leetcode.com/static/images/problemset/maze_1_example_2.png\n * \n * Note:\n * There is only one ball and one destination in the maze.\n * Both the ball and the destination exist on an empty space, and they will not\n * be at the same position initially.\n * The given maze does not contain border (like the red rectangle in the example\n * pictures), but you could assume the border of the maze are all walls.\n * The maze contains at least 2 empty spaces, and both the width and height of\n * the maze won't exceed 100.\n */\n\npublic class TheMaze490 {\n    private boolean[][] visited;\n      \n    public boolean hasPath(int[][] maze, int[] start, int[] destination) {\n        visited = new boolean[maze.length][maze[0].length];\n        if (hasPath(maze, start, destination, Direction.Left) ||\n            hasPath(maze, start, destination, Direction.Right) ||\n            hasPath(maze, start, destination, Direction.Top) ||\n            hasPath(maze, start, destination, Direction.Down)) return true;\n        \n        return false;\n    }\n    \n    public boolean hasPath(int[][] maze, int[] start, int[] destination, Direction d) {\n        visited[start[0]][start[1]] = true;\n        int[] now = new int[]{start[0], start[1]};\n        Direction origin = d;\n        while (true) {\n            if (d == Direction.Left) {\n                int nextLeft = now[1] - 1;\n                if (nextLeft < 0 || maze[now[0]][nextLeft] == 1) break;\n                now[1] = nextLeft;\n                // System.out.println(tuple(now));\n                origin = Direction.Right;\n            } else if (d == Direction.Right) {\n                int nextRight = now[1] + 1;\n                if (nextRight >= maze[0].length || maze[now[0]][nextRight] == 1) break;\n                now[1] = nextRight;\n                origin = Direction.Left;\n            } else if (d == Direction.Top) {\n                int nextTop = now[0] - 1;\n                if (nextTop < 0 || maze[nextTop][now[1]] == 1) break;\n                now[0] = nextTop;\n                origin = Direction.Down;\n            } else {\n                int nextDown = now[0] + 1;\n                if (nextDown >= maze.length || maze[nextDown][now[1]] == 1) break;\n                now[0] = nextDown;\n                origin = Direction.Top;\n            }\n        }\n        \n        if (now[0] == destination[0] && now[1] == destination[1]) return true;\n        if (visited[now[0]][now[1]]) return false;\n        for (Direction nextDir: Direction.values()) {\n            if (nextDir != origin && hasPath(maze, now, destination, nextDir)) return true;\n        }\n        visited[start[0]][start[1]] = false;\n        \n        return false;\n    }\n    \n    public enum Direction {\n        Left, Right, Top, Down\n    }\n\n\n    public boolean hasPath2(int[][] maze, int[] start, int[] destination) {\n        int M = maze.length;\n        int N = maze[0].length;\n        return roll(maze, start[0], start[1], destination[0], destination[1], M, N, new boolean[M][N]);\n    }\n\n    private boolean roll(int[][] maze, int i, int j, int di, int dj, int M, int N, boolean[][] visited) {\n        // if (i < 0 || j < 0 || i >= M || j >= N) return false;\n        if (visited[i][j]) return false;\n        if (i == di && j == dj) return true;\n        visited[i][j] = true;\n        \n        // top\n        int x = i - 1;\n        int y = j;\n        while (x >= 0 && maze[x][y] == 0) x--;\n        if (roll(maze, x+1, y, di, dj, M, N, visited)) {\n            return true;\n        }\n\n        // bottom\n        x = i + 1;\n        y = j;\n        while (x < M && maze[x][y] == 0) x++;\n        if (roll(maze, x-1, y, di, dj, M, N, visited)) {\n            return true;\n        }\n\n        // left\n        x = i;\n        y = j - 1;\n        while (y >= 0 && maze[x][y] == 0) y--;\n        if (roll(maze, x, y+1, di, dj, M, N, visited)) {\n            return true;\n        }\n\n        // right\n        x = i;\n        y = j + 1;\n        while (y < N && maze[x][y] == 0) y++;\n        if (roll(maze, x, y-1, di, dj, M, N, visited)) {\n            return true;\n        }\n\n        return false;\n    }\n\n\n    public boolean hasPath3(int[][] maze, int[] start, int[] destination) {\n        if (maze == null || maze.length == 0 || maze[0].length == 0 || start == null || destination == null) return false;\n        if (start[0] == destination[0] && start[1] == destination[1]) return true;\n        int M = maze.length;\n        int N = maze[0].length;\n        boolean[][] visited = new boolean[M][N];\n        Queue<int[]> q = new LinkedList<>();\n        q.add(start);\n        visited[start[0]][start[1]] = true;\n        while (!q.isEmpty()) {\n            int[] curr = q.poll();\n            if (curr[0] == destination[0] && curr[1] == destination[1]) return true;\n            addNextSteps(maze, q, visited, curr, M, N);\n        }\n        \n        return false;\n    }\n    \n    private void addNextSteps(int[][] maze, Queue<int[]> q, boolean[][] visited, int[] curr, int M, int N) {\n        int i = curr[0];\n        while (i >= 0 && maze[i][curr[1]] == 0) {\n            i--;\n        }\n        if (!visited[i+1][curr[1]]) {\n            q.add(new int[]{i+1, curr[1]});\n            visited[i+1][curr[1]] = true;\n        }\n        \n        i = curr[0];\n        while (i < M && maze[i][curr[1]] == 0) {\n            i++;\n        }\n        if (!visited[i-1][curr[1]]) {\n            q.add(new int[]{i-1, curr[1]});\n            visited[i-1][curr[1]] = true;\n        }\n        \n        i = curr[1];\n        while (i >= 0 && maze[curr[0]][i] == 0) {\n            i--;\n        }\n        if (!visited[curr[0]][i+1]) {\n            q.add(new int[]{curr[0], i+1});\n            visited[curr[0]][i+1] = true;\n        }\n        \n        \n        i = curr[1];\n        while (i < N && maze[curr[0]][i] == 0) {\n            i++;\n        }\n        if (!visited[curr[0]][i-1]) {\n            q.add(new int[]{curr[0], i-1});\n            visited[curr[0]][i-1] = true;\n        }\n    }\n\n    private int[][] DIRECTIONS = new int[][]{{0,1}, {0,-1}, {1,0}, {-1,0}};\n    public boolean hasPath4(int[][] maze, int[] start, int[] destination) {\n        int M = maze.length;\n        int N = maze[0].length;\n        boolean[][] visited = new boolean[M][N];\n        Queue<int[]> q = new LinkedList<>();\n        q.add(start);\n        visited[start[0]][start[1]] = true;\n        while (!q.isEmpty()) {\n            int[] curr = q.poll();\n            for (int[] dir: DIRECTIONS) {\n                int x = curr[0]+dir[0];\n                int y = curr[1]+dir[1];\n                while (x >= 0 && x < M && y >= 0 && y < N && maze[x][y] == 0) {\n                    x += dir[0];\n                    y += dir[1];\n                }\n                x -= dir[0];\n                y -= dir[1];\n                if (x == destination[0] && y == destination[1]) return true;\n                if (!visited[x][y]) {\n                    q.add(new int[]{x, y});\n                    visited[x][y] = true;\n                }\n            }\n        }\n        return false;\n    }\n\n\n}\n\n\n"
  },
  {
    "path": "src/TheMazeII505.java",
    "content": "/**\n * There is a ball in a maze with empty spaces and walls. The ball can go\n * through empty spaces by rolling up, down, left or right, but it won't stop\n * rolling until hitting a wall. When the ball stops, it could choose the next\n * direction.\n * \n * Given the ball's start position, the destination and the maze, find the\n * shortest distance for the ball to stop at the destination. The distance is\n * defined by the number of empty spaces traveled by the ball from the start\n * position (excluded) to the destination (included). If the ball cannot stop\n * at the destination, return -1.\n * \n * The maze is represented by a binary 2D array. 1 means the wall and 0 means\n * the empty space. You may assume that the borders of the maze are all walls.\n * The start and destination coordinates are represented by row and column\n * indexes.\n * \n * Example 1\n * \n * Input 1: a maze represented by a 2D array\n * \n * 0 0 1 0 0\n * 0 0 0 0 0\n * 0 0 0 1 0\n * 1 1 0 1 1\n * 0 0 0 0 0\n * \n * Input 2: start coordinate (rowStart, colStart) = (0, 4)\n * Input 3: destination coordinate (rowDest, colDest) = (4, 4)\n * \n * Output: 12\n * Explanation: One shortest way is : left -> down -> left -> down -> right -> down -> right.\n *              The total distance is 1 + 1 + 3 + 1 + 2 + 2 + 2 = 12.\n * https://leetcode.com/static/images/problemset/maze_1_example_1.png\n * \n * \n * Example 2\n * \n * Input 1: a maze represented by a 2D array\n * \n * 0 0 1 0 0\n * 0 0 0 0 0\n * 0 0 0 1 0\n * 1 1 0 1 1\n * 0 0 0 0 0\n * \n * Input 2: start coordinate (rowStart, colStart) = (0, 4)\n * Input 3: destination coordinate (rowDest, colDest) = (3, 2)\n * \n * Output: -1\n * Explanation: There is no way for the ball to stop at the destination.\n * https://leetcode.com/static/images/problemset/maze_1_example_2.png\n * \n * Note:\n * There is only one ball and one destination in the maze.\n * Both the ball and the destination exist on an empty space, and they will not\n * be at the same position initially.\n * The given maze does not contain border (like the red rectangle in the\n * example pictures), but you could assume the border of the maze are all walls.\n * The maze contains at least 2 empty spaces, and both the width and height of\n * the maze won't exceed 100.\n */\n\npublic class TheMazeII505 {\n    private int[][] DIRECTIONS = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};\n    public int shortestDistance(int[][] maze, int[] start, int[] destination) {\n        int M = maze.length;\n        int N = maze[0].length;\n        if (isSame(start, destination)) return 0;\n        int[][] visited = new int[M][N];\n        for (int[] row: visited) {\n            Arrays.fill(row, -1);\n        }\n        Queue<Point> q = new LinkedList<>();\n        q.add(new Point(start, 0));\n        visited[start[0]][start[1]] = 0;\n        int min = Integer.MAX_VALUE;\n        while (!q.isEmpty()) {\n            int size = q.size();\n            Point curr = q.poll();\n            if (isSame(curr.pos, destination)) {\n                min = Math.min(min, curr.dist);\n                continue;\n            }\n            for (int[] d: DIRECTIONS) {\n                int x = curr.pos[0] + d[0];\n                int y = curr.pos[1] + d[1];\n                int more = 1;\n                while (x >= 0 && y >= 0 && x < M && y < N && maze[x][y] == 0) {\n                    x += d[0];\n                    y += d[1];\n                    more++;\n                }\n                x -= d[0];\n                y -= d[1];\n                more--;\n                int[] newPos = new int[]{x, y};\n                if (visited[x][y] == -1 || visited[x][y] > curr.dist + more) {\n                    q.add(new Point(newPos, curr.dist + more));\n                    visited[x][y] = curr.dist + more;\n                }\n            }\n        }\n        return min == Integer.MAX_VALUE ? -1 : min;\n    }\n    \n    private boolean isSame(int[] a, int[] b) {\n        return a[0] == b[0] && a[1] == b[1];\n    }\n    \n    class Point {\n        int[] pos;\n        int dist;\n        Point(int[] p, int d) {\n            pos = p;\n            dist = d;\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/the-maze-ii/discuss/98418/Simple-Java-Solution-BFS\n     */\n    public int shortestDistance2(int[][] maze, int[] start, int[] destination) {\n        Queue<int[]> q = new LinkedList<>();\n        int m = maze.length, n = maze[0].length;\n        int[][] dist = new int[m][n];\n        for (int i = 0; i < m; i++) {\n            Arrays.fill(dist[i], Integer.MAX_VALUE);\n        }\n        int[] dx = new int[] {-1, 0, 1, 0};\n        int[] dy = new int[] { 0, 1, 0, -1};\n        q.offer(start);\n        dist[start[0]][start[1]] = 0;\n        while (!q.isEmpty()) {\n            int[] p = q.poll();\n            for (int i = 0; i < 4; i++) {\n                int x = p[0] + dx[i], y = p[1] + dy[i];\n                int cnt = 1;\n                \n                while (x >=0 && x < m && y >= 0 && y < n && maze[x][y] != 1) {\n                    x += dx[i];\n                    y += dy[i];\n                    cnt++;\n                }\n                x -= dx[i];\n                y -= dy[i];\n                cnt--;\n                if (dist[p[0]][p[1]] + cnt < dist[x][y]) {\n                    dist[x][y] = dist[p[0]][p[1]] + cnt;\n                    q.offer(new int[] {x, y});\n                }\n            }\n        }\n        return dist[destination[0]][destination[1]] == Integer.MAX_VALUE ? -1 : dist[destination[0]][destination[1]];\n    }\n\n\n    public int shortestDistance3(int[][] maze, int[] start, int[] destination) {\n        int M = maze.length;\n        int N = maze[0].length;\n        int[][] memo = new int[M][N];\n        for (int[] row: memo) Arrays.fill(row, Integer.MAX_VALUE);\n        memo[start[0]][start[1]] = 0;\n        roll(maze, start[0], start[1], memo, M, N);\n        return memo[destination[0]][destination[1]] == Integer.MAX_VALUE ? -1 : memo[destination[0]][destination[1]];\n    }\n\n    private void roll(int[][] maze, int i, int j, int[][] memo, int M, int N) {\n        // top\n        int t = i - 1;\n        int rt = 1;\n        while (t >= 0 && maze[t][j] == 0) {\n            t--;\n            rt++;\n        }\n        t++;\n        rt--;\n        if (memo[i][j] + rt < memo[t][j]) {\n            memo[t][j] = memo[i][j] + rt;\n            roll(maze, t, j, memo, M, N);\n        }\n\n        // bottom\n        int b = i + 1;\n        int rb = 1;\n        while (b < M && maze[b][j] == 0) {\n            b++;\n            rb++;\n        }\n        b--;\n        rb--;\n        if (memo[i][j] + rb < memo[b][j]) {\n            memo[b][j] = memo[i][j] + rb;\n            roll(maze, b, j, memo, M, N);\n        }\n\n        // left\n        int l = j - 1;\n        int rl = 1;\n        while (l >= 0 && maze[i][l] == 0) {\n            l--;\n            rl++;\n        }\n        l++;\n        rl--;\n        if (memo[i][j] + rl < memo[i][l]) {\n            memo[i][l] = memo[i][j] + rl;\n            roll(maze, i, l, memo, M, N);\n        }\n\n        // right\n        int r = j + 1;\n        int rr = 1;\n        while (r < N && maze[i][r] == 0) {\n            r++;\n            rr++;\n        }\n        r--;\n        rr--;\n        if (memo[i][j] + rr < memo[i][r]) {\n            memo[i][r] = memo[i][j] + rr;\n            roll(maze, i, r, memo, M, N);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/the-maze-ii/solution/\n     */\n    public int shortestDistance4(int[][] maze, int[] start, int[] dest) {\n        int[][] distance = new int[maze.length][maze[0].length];\n        for (int[] row: distance)\n            Arrays.fill(row, Integer.MAX_VALUE);\n        distance[start[0]][start[1]] = 0;\n        dfs(maze, start, distance);\n        return distance[dest[0]][dest[1]] == Integer.MAX_VALUE ? -1 : distance[dest[0]][dest[1]];\n    }\n\n    public void dfs(int[][] maze, int[] start, int[][] distance) {\n        int[][] dirs={{0,1}, {0,-1}, {-1,0}, {1,0}};\n        for (int[] dir: dirs) {\n            int x = start[0] + dir[0];\n            int y = start[1] + dir[1];\n            int count = 0;\n            while (x >= 0 && y >= 0 && x < maze.length && y < maze[0].length && maze[x][y] == 0) {\n                x += dir[0];\n                y += dir[1];\n                count++;\n            }\n            if (distance[start[0]][start[1]] + count < distance[x - dir[0]][y - dir[1]]) {\n                distance[x - dir[0]][y - dir[1]] = distance[start[0]][start[1]] + count;\n                dfs(maze, new int[]{x - dir[0],y - dir[1]}, distance);\n            }\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/the-maze-ii/solution/\n     */\n    public int shortestDistance5(int[][] maze, int[] start, int[] destination) {\n        int M = maze.length;\n        int N = maze[0].length;\n        int[][] distances = new int[M][N];\n        for (int[] row: distances) Arrays.fill(row, Integer.MAX_VALUE);\n        distances[start[0]][start[1]] = 0;\n        boolean[][] visited = new boolean[M][N];\n        roll(maze, distances, visited, M, N);\n        int res = distances[destination[0]][destination[1]];\n        return res == Integer.MAX_VALUE ? -1 : res;\n    }\n\n    private void roll(int[][] maze, int[][] distances, boolean[][] visited, int M, int N) {\n        while (true) {\n            int[] m = minDistance(distances, visited, M, N);\n            if (m == null) return;\n            visited[m[0]][m[1]] = true;\n            for (int[] dir: DIRECTIONS) {\n                int x = m[0] + dir[0];\n                int y = m[1] + dir[1];\n                int dis = 0;\n                while (x >= 0 && y >= 0 && x < M && y < N && maze[x][y] == 0) {\n                    x += dir[0];\n                    y += dir[1];\n                    dis++;\n                }\n                x -= dir[0];\n                y -= dir[1];\n                int d = distances[m[0]][m[1]] + dis;\n                if (d < distances[x][y]) {\n                    distances[x][y] = d;\n                    \n                }\n            }  \n        }\n    }\n\n    private int[] minDistance(int[][] distances, boolean[][] visited, int M, int N) {\n        int[] res = null;\n        int min = Integer.MAX_VALUE;\n        for (int i=0; i<M; i++) {\n            for (int j=0; j<N; j++) {\n                if (!visited[i][j] && distances[i][j] < min) {\n                    res = new int[]{i, j};\n                    min = distances[i][j];\n                }\n            }\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/the-maze-ii/solution/\n     */\n    public int shortestDistance6(int[][] maze, int[] start, int[] destination) {\n        int M = maze.length;\n        int N = maze[0].length;\n        int[][] distances = new int[M][N];\n        for (int[] row: distances) Arrays.fill(row, Integer.MAX_VALUE);\n        distances[start[0]][start[1]] = 0;\n        roll(maze, distances, start, M, N);\n        int res = distances[destination[0]][destination[1]];\n        return res == Integer.MAX_VALUE ? -1 : res;\n    }\n\n    private void roll(int[][] maze, int[][] distances, int[] start, int M, int N) {\n        PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[2] - b[2]);\n        pq.add(new int[]{start[0], start[1], 0});\n        while (!pq.isEmpty()) {\n            int[] md = pq.poll();\n            if (distances[md[0]][md[1]] < md[2]) continue; \n            for (int[] dir: DIRECTIONS) {\n                int x = md[0] + dir[0];\n                int y = md[1] + dir[1];\n                int dis = 0;\n                while (x >= 0 && y >= 0 && x < M && y < N && maze[x][y] == 0) {\n                    x += dir[0];\n                    y += dir[1];\n                    dis++;\n                }\n                x -= dir[0];\n                y -= dir[1];\n                int d = distances[md[0]][md[1]] + dis;\n                if (d < distances[x][y]) {\n                    distances[x][y] = d;\n                    pq.add(new int[]{x, y, d});\n                }\n            }  \n        }\n    }\n\n}\n"
  },
  {
    "path": "src/TheMazeIII499.java",
    "content": "/**\n * There is a ball in a maze with empty spaces and walls. The ball can go\n * through empty spaces by rolling up (u), down (d), left (l) or right (r),\n * but it won't stop rolling until hitting a wall. When the ball stops, it\n * could choose the next direction. There is also a hole in this maze. The\n * ball will drop into the hole if it rolls on to the hole.\n * \n * Given the ball position, the hole position and the maze, find out how the\n * ball could drop into the hole by moving the shortest distance. The distance\n * is defined by the number of empty spaces traveled by the ball from the start\n * position (excluded) to the hole (included). Output the moving directions\n * by using 'u', 'd', 'l' and 'r'. Since there could be several different\n * shortest ways, you should output the lexicographically smallest way. If\n * the ball cannot reach the hole, output \"impossible\".\n * \n * The maze is represented by a binary 2D array. 1 means the wall and 0 means\n * the empty space. You may assume that the borders of the maze are all walls.\n * The ball and the hole coordinates are represented by row and column indexes.\n * \n * Example 1:\n * Input 1: a maze represented by a 2D array\n * 0 0 0 0 0\n * 1 1 0 0 1\n * 0 0 0 0 0\n * 0 1 0 0 1\n * 0 1 0 0 0\n * \n * Input 2: ball coordinate (rowBall, colBall) = (4, 3)\n * Input 3: hole coordinate (rowHole, colHole) = (0, 1)\n * \n * Output: \"lul\"\n * \n * Explanation: There are two shortest ways for the ball to drop into the hole.\n * The first way is left -> up -> left, represented by \"lul\".\n * The second way is up -> left, represented by 'ul'.\n * Both ways have shortest distance 6, but the first way is lexicographically\n * smaller because 'l' < 'u'. So the output is \"lul\".\n * \n * Example 2:\n * Input 1: a maze represented by a 2D array\n * 0 0 0 0 0\n * 1 1 0 0 1\n * 0 0 0 0 0\n * 0 1 0 0 1\n * 0 1 0 0 0\n * \n * Input 2: ball coordinate (rowBall, colBall) = (4, 3)\n * Input 3: hole coordinate (rowHole, colHole) = (3, 0)\n * \n * Output: \"impossible\"\n * \n * Explanation: The ball cannot reach the hole.\n * \n * Note:\n * There is only one ball and one hole in the maze.\n * Both the ball and hole exist on an empty space, and they will not be at the\n * same position initially.\n * The given maze does not contain border (like the red rectangle in the\n * example pictures), but you could assume the border of the maze are all walls.\n * The maze contains at least 2 empty spaces, and the width and the height\n * of the maze won't exceed 30.\n */\n\npublic class TheMazeIII499 {\n    private int[][] DIRECTIONS = new int[][]{{1,0}, {0,-1}, {0,1}, {-1,0}};\n    private char[] LETTERS = new char[]{'d', 'l', 'r', 'u'};\n\n    public String findShortestWay(int[][] maze, int[] ball, int[] hole) {\n        int M = maze.length;\n        int N = maze[0].length;\n        int[][] distance = new int[M][N];\n        for (int[] row: distance) Arrays.fill(row, Integer.MAX_VALUE);\n        distance[ball[0]][ball[1]] = 0;\n        StringBuilder sb = new StringBuilder();\n        String[] res = new String[1];\n        int[] dis = new int[]{Integer.MAX_VALUE};\n        roll(maze, ball[0], ball[1], hole[0], hole[1], distance, sb, M, N, res, dis);\n        return res[0] == null ? \"impossible\" : res[0];\n    }\n\n    private void roll(int[][] maze, int i, int j, int hi, int hj, int[][] distance, StringBuilder sb, int M, int N, String[] res, int[] dis) {\n        int len = sb.length();\n        for (int k=0; k<4; k++) {\n            int[] dir = DIRECTIONS[k];\n            char ch = LETTERS[k];\n            sb.append(ch);\n            int x = i + dir[0];\n            int y = j + dir[1];\n            int count = 0;\n            while (x >= 0 && y >= 0 && x < M && y < N && maze[x][y] == 0) {\n                if (x == hi && y == hj) break;\n                x += dir[0];\n                y += dir[1];\n                count++;\n            }\n            int d = distance[i][j] + count;\n            if (x == hi && y == hj) {\n                if (d < dis[0]) {\n                    dis[0] = d;\n                    res[0] = sb.toString();\n                } else if (d == dis[0]) {\n                    String tmp = sb.toString();\n                    if (res[0] == null || tmp.compareTo(res[0]) < 0) {\n                        res[0] = tmp;\n                    }\n                }\n                sb.setLength(len);\n                continue;\n            }\n            x -= dir[0];\n            y -= dir[1];\n            if (d < distance[x][y]) {\n                distance[x][y] = d;\n                roll(maze, x, y, hi, hj, distance, sb, M, N, res, dis);\n            }\n            sb.setLength(len);\n        }\n    }\n\n\n\n}\n"
  },
  {
    "path": "src/TheSkylineProblem218.java",
    "content": "/**\n * A city's skyline is the outer contour of the silhouette formed by all the\n * buildings in that city when viewed from a distance. Now suppose you are\n * given the locations and height of all the buildings as shown on a cityscape\n * photo (Figure A), write a program to output the skyline formed by these\n * buildings collectively (Figure B).\n * \n * https://leetcode.com/static/images/problemset/skyline2.jpg\n * \n * The geometric information of each building is represented by a triplet of\n * integers [Li, Ri, Hi], where Li and Ri are the x coordinates of the left\n * and right edge of the ith building, respectively, and Hi is its height. It\n * is guaranteed that 0 ≤ Li, Ri ≤ INT_MAX, 0 < Hi ≤ INT_MAX, and Ri - Li > 0.\n * You may assume all buildings are perfect rectangles grounded on an\n * absolutely flat surface at height 0.\n * \n * For instance, the dimensions of all buildings in Figure A are recorded as:\n * [ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ] .\n * \n * The output is a list of \"key points\" (red dots in Figure B) in the format\n * of [ [x1,y1], [x2, y2], [x3, y3], ... ] that uniquely defines a skyline. A\n * key point is the left endpoint of a horizontal line segment. Note that the\n * last key point, where the rightmost building ends, is merely used to mark\n * the termination of the skyline, and always has zero height. Also, the\n * ground in between any two adjacent buildings should be considered part of\n * the skyline contour.\n * \n * For instance, the skyline in Figure B should be represented as:\n * [ [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0] ].\n * \n * Notes:\n * \n * The number of buildings in any input list is guaranteed to be in the range [0, 10000].\n * The input list is already sorted in ascending order by the left x position Li.\n * The output list must be sorted by the x position.\n * There must be no consecutive horizontal lines of equal height in the output\n * skyline. For instance, [...[2 3], [4 5], [7 5], [11 5], [12 7]...] is not\n * acceptable; the three lines of height 5 should be merged into one in the\n * final output as such: [...[2 3], [4 5], [12 7], ...]\n */\n\npublic class TheSkylineProblem218 {\n    private static int L = 0;\n    private static int R = 1;\n    public List<int[]> getSkyline(int[][] buildings) {\n        List<int[]> res = new ArrayList<>();\n        int N = buildings.length;\n        if (N == 0) return res;\n        \n        // xi, hi, L/R\n        int[][] verts = new int[N * 2][3];\n        int t = 0;\n        for (int[] b: buildings) {\n            verts[t++] = new int[]{b[0], b[2], L};\n            verts[t++] = new int[]{b[1], b[2], R};\n        }\n        Comparator<int[]> comp1 = new Comparator<int[]>() {\n            @Override\n            public int compare(int[] v1, int[] v2) {\n                int xd = Integer.compare(v1[0], v2[0]);\n                if (xd != 0) return xd;\n\n                if (v1[2] == L && v2[2] == L) {\n                    return Integer.compare(v2[1], v1[1]);\n                } else if (v1[2] == R && v2[2] == R) {\n                    return Integer.compare(v1[1], v2[1]);\n                } else {\n                    return Integer.compare(v1[2], v2[2]);\n                }\n            }\n        };\n        Arrays.sort(verts, comp1);\n        \n        Comparator<Integer> comp2 = (h1, h2) -> Integer.compare(h2, h1);\n        PriorityQueue<Integer> pq = new PriorityQueue<>(comp2);\n        for (int[] vi: verts) {\n            int xi = vi[0];\n            int hi = vi[1];\n            int Di = vi[2];\n\n            if (Di == L) { // L\n                if (pq.isEmpty() || pq.peek() < hi) {\n                    res.add(new int[]{xi, hi});\n                }\n                pq.add(hi);\n            } else { // R\n                pq.remove(hi);\n                if (pq.isEmpty() || pq.peek() < hi) {\n                    int y = pq.isEmpty() ? 0 : pq.peek();\n                    res.add(new int[]{xi, y});\n                }\n            }\n        }\n\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/the-skyline-problem/discuss/61192/Once-for-all-explanation-with-clean-Java-code(O(n2)time-O(n)-space)\n     */\n    public List<int[]> getSkyline2(int[][] buildings) {\n        List<int[]> result = new ArrayList<>();\n        List<int[]> height = new ArrayList<>();\n        for(int[] b:buildings) {\n            // start point has negative height value\n            height.add(new int[]{b[0], -b[2]});\n            // end point has normal height value\n            height.add(new int[]{b[1], b[2]}); \n        }\n\n        // sort $height, based on the first value, if necessary, use the second to\n        // break ties\n        Collections.sort(height, (a, b) -> {\n                if(a[0] != b[0]) \n                    return a[0] - b[0];\n                return a[1] - b[1];\n        });\n\n        // Use a maxHeap to store possible heights\n        Queue<Integer> pq = new PriorityQueue<>((a, b) -> (b - a));\n\n        // Provide a initial value to make it more consistent\n        pq.offer(0);\n\n        // Before starting, the previous max height is 0;\n        int prev = 0;\n\n        // visit all points in order\n        for(int[] h:height) {\n            if(h[1] < 0) { // a start point, add height\n                pq.offer(-h[1]);\n            } else {  // a end point, remove height\n                pq.remove(h[1]);\n            }\n            int cur = pq.peek(); // current max height;\n      \n            // compare current max height with previous max height, update result and \n            // previous max height if necessary\n            if(prev != cur) {\n                result.add(new int[]{h[0], cur});\n                prev = cur;\n            }\n        }\n        return result;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/the-skyline-problem/discuss/61281/Java-divide-and-conquer-solution-beats-96\n     */\n    public List<int[]> getSkyline3(int[][] buildings) {\n        return merge(buildings, 0, buildings.length-1);\n    }\n\n    private LinkedList<int[]> merge(int[][] buildings, int lo, int hi) {\n        LinkedList<int[]> res = new LinkedList<>();\n        if(lo > hi) {\n            return res;\n        } else if(lo == hi) {\n            res.add(new int[]{buildings[lo][0], buildings[lo][2]});\n            res.add(new int[]{buildings[lo][1], 0});\n            return res;\n        } \n        int mid = lo+(hi-lo)/2;\n        LinkedList<int[]> left = merge(buildings, lo, mid);\n        LinkedList<int[]> right = merge(buildings, mid+1, hi);\n        int leftH = 0, rightH = 0;\n        while(!left.isEmpty() || !right.isEmpty()) {\n            long x1 = left.isEmpty()? Long.MAX_VALUE: left.peekFirst()[0];\n            long x2 = right.isEmpty()? Long.MAX_VALUE: right.peekFirst()[0];\n            int x = 0;\n            if(x1 < x2) {\n                int[] temp = left.pollFirst();\n                x = temp[0];\n                leftH = temp[1];\n            } else if(x1 > x2) {\n                int[] temp = right.pollFirst();\n                x = temp[0];\n                rightH = temp[1];\n            } else {\n                x = left.peekFirst()[0];\n                leftH = left.pollFirst()[1];\n                rightH = right.pollFirst()[1];\n            }\n            int h = Math.max(leftH, rightH);\n            if(res.isEmpty() || h != res.peekLast()[1]) {\n                res.add(new int[]{x, h});\n            }\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/ThirdMaximumNumber414.java",
    "content": "/**\n * Given a non-empty array of integers, return the third maximum number in this\n * array. If it does not exist, return the maximum number.\n * The time complexity must be in O(n).\n * \n * Example 1:\n * Input: [3, 2, 1]\n * Output: 1\n * Explanation: The third maximum is 1.\n * \n * Example 2:\n * Input: [1, 2]\n * Output: 2\n * Explanation: The third maximum does not exist, so the maximum (2) is\n * returned instead.\n * \n * Example 3:\n * Input: [2, 2, 3, 1]\n * Output: 1\n * Explanation: Note that the third maximum here means the third maximum\n * distinct number. Both numbers with value 2 are both considered as\n * second maximum.\n * \n */\n\n\npublic class ThirdMaximumNumber414 {\n\n    public static int thirdMax(int[] arr) {\n        // non-empty array, no need for checking empty\n        Stack<Integer> st = new Stack<>();\n        for (int i: arr) {\n            Stack<Integer> temp = new Stack<>();\n            while (!st.empty() && st.peek() <= i) {\n                temp.push(st.pop());\n            }\n            st.push(i);\n            while (!temp.empty() && st.size() < 3) {\n                int t = temp.pop();\n                if (!st.empty() && st.peek() == t) continue;\n                st.push(t);\n            }\n            while (st.size() > 3) {\n                st.pop();\n            }\n        }\n\n        if (st.size() == 3) return st.peek();\n\n        while (st.size() > 1) {\n            st.pop();\n        }\n        return st.peek();\n    }\n\n    public static int thirdMax2(int[] arr) {\n        PriorityQueue<Integer> q = new PriorityQueue();\n        // non empty array\n        q.add(arr[0]);\n        for (int i=1; i<arr.length; i++) {\n            int num = arr[i];\n            if (q.size() >= 3 && q.peek() >= num) continue;\n            if (q.contains(num)) continue;\n            if (q.size() >= 3) q.poll();\n            q.add(num);\n        }\n        // exits\n        if (q.size() == 3) return q.peek();\n\n        // not exits\n        while (q.size() > 1) q.poll();\n        return q.peek();\n    }\n\n\n    /**\n     * https://leetcode.com/problems/third-maximum-number/discuss/90190/Java-PriorityQueue-O(n)-+-O(1)\n     */\n    public int thirdMax3(int[] nums) {\n        PriorityQueue<Integer> pq = new PriorityQueue<>();\n        Set<Integer> set = new HashSet<>();\n        for (int i : nums) {\n            if (!set.contains(i)) {\n                pq.offer(i);\n                set.add(i);\n                if (pq.size() > 3) {\n                    set.remove(pq.poll());\n                }\n            }\n        }\n        if (pq.size() < 3) {\n            while (pq.size() > 1) {\n                pq.poll();\n            }\n        }\n        return pq.peek();\n    }\n\n\n    /**\n     * https://leetcode.com/problems/third-maximum-number/discuss/90202/Java-neat-and-easy-understand-solution-O(n)-time-O(1)-space\n     */\n    public int thirdMax4(int[] nums) {\n        Integer max1 = null;\n        Integer max2 = null;\n        Integer max3 = null;\n        for (Integer n : nums) {\n            if (n.equals(max1) || n.equals(max2) || n.equals(max3)) continue;\n            if (max1 == null || n > max1) {\n                max3 = max2;\n                max2 = max1;\n                max1 = n;\n            } else if (max2 == null || n > max2) {\n                max3 = max2;\n                max2 = n;\n            } else if (max3 == null || n > max3) {\n                max3 = n;\n            }\n        }\n        return max3 == null ? max1 : max3;\n    }\n\n\n    // public static int thirdMax4(int[] arr) {\n    //     int[] temp = new int[3];\n    //     Arrays.fill(temp, Integer.MIN_VALUE);\n    //     int c = 0;\n    //     for (int i: arr) {\n    //         int minIdx = -1;\n    //         int min = Integer.MAX_VALUE;\n    //         boolean dup = false;\n    //         for (int k=0; k<3; k++) {\n    //             if (temp[k] == i) {\n    //                 dup = true;\n    //                 break;\n    //             }\n    //             if (min > i) {\n    //                 min = i;\n    //                 minIdx = k;\n    //             }\n    //         }\n    //         if (!dup && minIdx != -1) {\n    //             c++;\n    //             temp[minIdx] = i;\n    //         }\n    //     }\n\n    //     if (c >= 3) {\n    //         return Math.min(Math.min(temp[0], temp[1]), temp[2]);\n    //     } else {\n    //         return Math.max(Math.max(temp[0], temp[1]), temp[2]);\n    //     }\n    // }\n\n\n}\n"
  },
  {
    "path": "src/ThreeSum15.java",
    "content": "/**\n * Given an array S of n integers, are there elements a, b, c in S such that\n * a + b + c = 0? Find all unique triplets in the array which gives the sum\n * of zero.\n *\n * Note: The solution set must not contain duplicate triplets.\n *\n * For example, given array S = [-1, 0, 1, 2, -1, -4],\n *\n * A solution set is:\n * [\n *   [-1, 0, 1],\n *   [-1, -1, 2]\n * ]\n */\n\n\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.LinkedList;\n\npublic class ThreeSum15 {\n\n    /**\n     * https://discuss.leetcode.com/topic/8125/concise-o-n-2-java-solution\n     */\n    public List<List<Integer>> threeSum(int[] nums) {\n        List<List<Integer>> res = new ArrayList<>();\n        if (nums == null || nums.length < 3) return res;\n        Arrays.sort(nums);\n        if (nums[0] > 0 || nums[nums.length-1] < 0) return res;\n\n        for (int i=0; i<nums.length-2; i++) {\n            if (i > 0 && nums[i] == nums[i-1]) continue;\n\n            int l = i+1;\n            int r = nums.length-1;\n            int left = 0 - nums[i];\n            while (l < r) {\n                if (nums[l] + nums[r] == left) {\n                    res.add(Arrays.asList(nums[i], nums[l], nums[r]));\n                    while (l < r && nums[l] == nums[l+1]) l++;\n                    while (l < r && nums[r] == nums[r-1]) r--;\n                    l++;\n                    r--;\n                } else if (nums[l] + nums[r] > left) {\n                    r--;\n                } else {\n                    l++;\n                }\n            }\n        }\n\n        return res;\n    }\n\n    public static void main(String[] args) {\n        ThreeSum15 ts = new ThreeSum15();\n\n        System.out.println(ts.threeSum(new int[]{-1, 0, 1, 2, -1, -4}));\n        System.out.println(ts.threeSum(new int[]{0, 0, 0}));\n        System.out.println(ts.threeSum(new int[]{0, 0, 0, 0}));\n        System.out.println(ts.threeSum(new int[]{-4, -2, -2, -2, 0, 1, 2, 2, 2, 3, 3, 4, 4, 6, 6}));\n        System.out.println(ts.threeSum(new int[]{0, 0, 0, 1, 1}));\n        System.out.println(ts.threeSum(new int[]{-1, -1, 0, 0, 0}));\n    }\n\n}\n"
  },
  {
    "path": "src/ThreeSumClosest16.java",
    "content": "/**\n * Given an array S of n integers, find three integers in S such that the sum\n * is closest to a given number, target. Return the sum of the three integers.\n * You may assume that each input would have exactly one solution.\n *\n * For example, given array S = {-1 2 1 -4}, and target = 1.\n *\n * The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).\n */\n\n\nimport java.util.Arrays;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.HashSet;\nimport java.util.Set;\n\n\npublic class ThreeSumClosest16 {\n\n    public int threeSumClosest(int[] nums, int target) {\n        Arrays.sort(nums);\n\n        Integer sumClosest = Integer.MAX_VALUE;\n        Integer diffClosest = Integer.MAX_VALUE;\n\n        for (int i = 0; i < nums.length - 2; i++) {\n            if (i == 0 || (i > 0 && nums[i] != nums[i-1])) {\n                int low = i + 1;\n                int high = nums.length - 1;\n                while (low < high) {\n                    int tempSum  = nums[i] + nums[low] + nums[high];\n                    if (tempSum == target) {\n                        return tempSum;\n                    }\n\n                    boolean update = diffClosest > Math.abs(tempSum - target);\n                    sumClosest = update ? tempSum : sumClosest;\n                    diffClosest = update ? Math.abs(tempSum - target) : diffClosest;\n\n                    if (tempSum < target) {\n                        low++;\n                    } else {\n                        high--;\n                    }\n                }\n            }\n        }\n        return sumClosest;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/5192/java-solution-with-o-n2-for-reference/19\n     */\n    public int threeSumClosest2(int[] num, int target) {\n        int result = num[0] + num[1] + num[num.length - 1];\n        Arrays.sort(num);\n        for (int i = 0; i < num.length - 2; i++) {\n            if (i > 0 && num[i] == num[i-1]) continue;\n            int start = i + 1, end = num.length - 1;\n            while (start < end) {\n                int sum = num[i] + num[start] + num[end];\n                if (sum > target) {\n                    end--;\n                } else {\n                    start++;\n                }\n                if (Math.abs(sum - target) < Math.abs(result - target)) {\n                    result = sum;\n                }\n            }\n        }\n        return result;\n    }\n\n\n    public static void main(String[] args) {\n        ThreeSumClosest16 tsc = new ThreeSumClosest16();\n\n        System.out.println(tsc.threeSumClosest(new int[]{-1, 2, 1, -4}, 1));\n        System.out.println(tsc.threeSumClosest(new int[]{-1, 0, 1, 1, 55}, 3));\n    }\n\n}\n"
  },
  {
    "path": "src/ThreeSumSmaller259.java",
    "content": "/**\n * Given an array of n integers nums and a target, find the number of index\n * triplets i, j, k with 0 <= i < j < k < n that satisfy the condition\n * nums[i] + nums[j] + nums[k] < target.\n *\n * For example, given nums = [-2, 0, 1, 3], and target = 2.\n *\n * Return 2. Because there are two triplets which sums are less than 2:\n *\n * [-2, 0, 1]\n * [-2, 0, 3]\n *\n * Follow up:\n * Could you solve it in O(n2) runtime?\n */\n\npublic class ThreeSumSmaller259 {\n    public int threeSumSmaller(int[] nums, int target) {\n        if (nums == null || nums.length < 3) return 0;\n        int res = 0;\n        Arrays.sort(nums);\n\n        for (int i=0; i<nums.length-2; i++) {\n            for (int l=i+1; l<nums.length-1; l++) {\n                for (int r=l+1; r<nums.length; r++) {\n                    int sum = nums[i] + nums[l] + nums[r];\n                    if (sum >= target) break;\n                    res++;\n                }\n            }\n        }\n        return res;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/3sum-smaller/solution/\n     */\n    public int threeSumSmaller2(int[] nums, int target) {\n        Arrays.sort(nums);\n        int sum = 0;\n        for (int i = 0; i < nums.length - 2; i++) {\n            sum += twoSumSmaller(nums, i + 1, target - nums[i]);\n        }\n        return sum;\n    }\n\n    private int twoSumSmaller(int[] nums, int startIndex, int target) {\n        int sum = 0;\n        int left = startIndex;\n        int right = nums.length - 1;\n        while (left < right) {\n            if (nums[left] + nums[right] < target) {\n                sum += right - left;\n                left++;\n            } else {\n                right--;\n            }\n        }\n        return sum;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/3sum-smaller/solution/\n     */\n    public int threeSumSmaller3(int[] nums, int target) {\n        Arrays.sort(nums);\n        int sum = 0;\n        for (int i = 0; i < nums.length - 2; i++) {\n            sum += twoSumSmaller(nums, i + 1, target - nums[i]);\n        }\n        return sum;\n    }\n\n    private int twoSumSmaller(int[] nums, int startIndex, int target) {\n        int sum = 0;\n        for (int i = startIndex; i < nums.length - 1; i++) {\n            int j = binarySearch(nums, i, target - nums[i]);\n            sum += j - i;\n        }\n        return sum;\n    }\n\n    private int binarySearch(int[] nums, int startIndex, int target) {\n        int left = startIndex;\n        int right = nums.length - 1;\n        while (left < right) {\n            int mid = (left + right + 1) / 2;\n            if (nums[mid] < target) {\n                left = mid;\n            } else {\n                right = mid - 1;\n            }\n        }\n        return left;\n    }\n\n}\n"
  },
  {
    "path": "src/ToLowerCase709.java",
    "content": "/**\n * mplement function ToLowerCase() that has a string parameter str, and returns\n * the same string in lowercase.\n * \n * Example 1:\n * Input: \"Hello\"\n * Output: \"hello\"\n * \n * Example 2:\n * Input: \"here\"\n * Output: \"here\"\n * \n * Example 3:\n * Input: \"LOVELY\"\n * Output: \"lovely\"\n */\n\npublic class ToLowerCase709 {\n    public String toLowerCase(String str) {\n        return str.toLowerCase();\n    }\n\n    /**\n     * https://leetcode.com/problems/to-lower-case/discuss/148993/Java-no-library-methods\n     */\n    public String toLowerCase2(String str) {\n        char[] a = str.toCharArray();\n        for (int i = 0; i < a.length; i++)\n            if ('A' <= a[i] && a[i] <= 'Z')\n                a[i] = (char) (a[i] - 'A' + 'a');\n        return new String(a);\n    }\n\n}\n"
  },
  {
    "path": "src/TopKFrequentElements347.java",
    "content": "/**\n * Given a non-empty array of integers, return the k most frequent elements.\n *  *\n * For example,\n * Given [1,1,1,2,2,3] and k = 2, return [1,2].\n *\n * Note:\n *      You may assume k is always valid, 1 ? k ? number of unique elements.\n *      Your algorithm's time complexity must be better than O(n log n), where\n *          n is the array's size.\n */\n\n\n\npublic class TopKFrequentElements347 {\n    public List<Integer> topKFrequent(int[] nums, int k) {\n        Map<Integer, Integer> map = new HashMap<>();\n        for (int n : nums) {\n            map.put(n, (map.getOrDefault(n, 0)) + 1);\n        }\n\n        Iterator<Map.Entry<Integer, Integer>> ite = sortByValue(map).entrySet().iterator();\n        List<Integer> results = new ArrayList<>();\n\n        int i = 0;\n        while(i<k) {\n            Map.Entry<Integer, Integer> me = (Map.Entry)ite.next();\n            results.add(me.getKey());\n            i++;\n        }\n\n        return results;\n    }\n\n    private Map<Integer, Integer> sortByValue(Map<Integer, Integer> unsortMap) {\n        List<Map.Entry<Integer, Integer>> list =\n                new LinkedList<Map.Entry<Integer, Integer>>(unsortMap.entrySet());\n\n        Collections.sort(list, new Comparator<Map.Entry<Integer, Integer>>() {\n            public int compare(Map.Entry<Integer, Integer> o1,\n                               Map.Entry<Integer, Integer> o2) {\n                return (o2.getValue()).compareTo(o1.getValue());\n            }\n        });\n\n        Map<Integer, Integer> sortedMap = new LinkedHashMap<Integer, Integer>();\n        for (Map.Entry<Integer, Integer> entry : list) {\n            sortedMap.put(entry.getKey(), entry.getValue());\n        }\n\n        return sortedMap;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/48158/3-java-solution-using-array-maxheap-treemap\n     */\n    public List<Integer> topKFrequent2(int[] nums, int k) {\n        Map<Integer, Integer> map = new HashMap<>();\n        for(int n: nums){\n            map.put(n, map.getOrDefault(n,0)+1);\n        }\n\n        // corner case: if there is only one number in nums, we need the bucket has index 1.\n        List<Integer>[] bucket = new List[nums.length+1];\n        for(int n:map.keySet()){\n            int freq = map.get(n);\n            if(bucket[freq]==null)\n                bucket[freq] = new LinkedList<>();\n            bucket[freq].add(n);\n        }\n\n        List<Integer> res = new LinkedList<>();\n        for(int i=bucket.length-1; i>0 && k>0; --i){\n            if(bucket[i]!=null){\n                List<Integer> list = bucket[i];\n                res.addAll(list);\n                k-= list.size();\n            }\n        }\n\n        return res;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/48158/3-java-solution-using-array-maxheap-treemap\n     */\n    public List<Integer> topKFrequent3(int[] nums, int k) {\n        Map<Integer, Integer> map = new HashMap<>();\n        for(int n: nums){\n            map.put(n, map.getOrDefault(n,0)+1);\n        }\n\n        PriorityQueue<Map.Entry<Integer, Integer>> maxHeap =\n                         new PriorityQueue<>((a,b)->(b.getValue()-a.getValue()));\n        for(Map.Entry<Integer,Integer> entry: map.entrySet()){\n            maxHeap.add(entry);\n        }\n\n        List<Integer> res = new ArrayList<>();\n        while(res.size()<k){\n            Map.Entry<Integer, Integer> entry = maxHeap.poll();\n            res.add(entry.getKey());\n        }\n        return res;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/48158/3-java-solution-using-array-maxheap-treemap\n     */\n    public List<Integer> topKFrequent4(int[] nums, int k) {\n        Map<Integer, Integer> map = new HashMap<>();\n        for(int n: nums){\n            map.put(n, map.getOrDefault(n,0)+1);\n        }\n\n        TreeMap<Integer, List<Integer>> freqMap = new TreeMap<>();\n        for(int num : map.keySet()){\n           int freq = map.get(num);\n           if(!freqMap.containsKey(freq)){\n               freqMap.put(freq, new LinkedList<>());\n           }\n           freqMap.get(freq).add(num);\n        }\n\n        List<Integer> res = new ArrayList<>();\n        while(res.size()<k){\n            Map.Entry<Integer, List<Integer>> entry = freqMap.pollLastEntry();\n            res.addAll(entry.getValue());\n        }\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/TopKFrequentWords692.java",
    "content": "/**\n * Given a non-empty list of words, return the k most frequent elements.\n *\n * Your answer should be sorted by frequency from highest to lowest. If two\n * words have the same frequency, then the word with the lower alphabetical\n * order comes first.\n *\n * Example 1:\n * Input: [\"i\", \"love\", \"leetcode\", \"i\", \"love\", \"coding\"], k = 2\n * Output: [\"i\", \"love\"]\n * Explanation: \"i\" and \"love\" are the two most frequent words.\n *     Note that \"i\" comes before \"love\" due to a lower alphabetical order.\n *\n * Example 2:\n * Input: [\"the\", \"day\", \"is\", \"sunny\", \"the\", \"the\", \"the\", \"sunny\", \"is\", \"is\"], k = 4\n * Output: [\"the\", \"is\", \"sunny\", \"day\"]\n * Explanation: \"the\", \"is\", \"sunny\" and \"day\" are the four most frequent words,\n *     with the number of occurrence being 4, 3, 2 and 1 respectively.\n *\n * Note:\n * You may assume k is always valid, 1 ≤ k ≤ number of unique elements.\n * Input words contain only lowercase letters.\n *\n * Follow up:\n * Try to solve it in O(n log k) time and O(n) extra space.\n *\n */\n\n\npublic class TopKFrequentWords692 {\n    public List<String> topKFrequent(String[] words, int k) {\n        Map<String, Integer> counts = new HashMap<>();\n        for (String w: words) {\n            counts.put(w, counts.getOrDefault(w, 0) + 1);\n        }\n\n        return sortByValue(counts, k);\n    }\n\n    private List<String> sortByValue(Map<String, Integer> unsortMap, int k) {\n        List<Map.Entry<String, Integer>> list =\n                new LinkedList<Map.Entry<String, Integer>>(unsortMap.entrySet());\n\n        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {\n            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {\n                if (o1.getValue().equals(o2.getValue())) {\n                    return o1.getKey().compareTo(o2.getKey());\n                } else {\n                    return o2.getValue().compareTo(o1.getValue());\n                }\n            }\n        });\n\n        List<String> topK = new ArrayList<>();\n        int i = 0;\n        while (i < k) {\n            topK.add(list.get(i).getKey());\n            i++;\n        }\n\n        return topK;\n    }\n\n\n\n    public List<String> topKFrequent2(String[] words, int k) {\n        Map<String, Integer> counts = new HashMap<>();\n        for (String w: words) {\n            counts.put(w, counts.getOrDefault(w, 0) + 1);\n        }\n\n        Map<Integer, List<String>> freqs = new HashMap<>();\n        for (Map.Entry<String, Integer> c: counts.entrySet()) {\n            List<String> l = freqs.getOrDefault(c.getValue(), new ArrayList<>());\n            l.add(c.getKey());\n            freqs.put(c.getValue(), l);\n        }\n        List<Map.Entry<Integer, List<String>>> buckets = sortByKey(freqs);\n\n        List<String> topK = new ArrayList<>();\n        int i = 0;\n        int j = 0;\n        while (j < buckets.size() && i < k) {\n            List<String> curr = buckets.get(j).getValue();\n            Collections.sort(curr);\n            int p = 0;\n            while (p < curr.size() && i < k) {\n                topK.add(curr.get(p));\n                p++;\n                i++;\n            }\n            j++;\n        }\n\n        return topK;\n    }\n\n    private List<Map.Entry<Integer, List<String>>> sortByKey(Map<Integer, List<String>> unsortMap) {\n        List<Map.Entry<Integer, List<String>>> list =\n                new LinkedList<Map.Entry<Integer, List<String>>>(unsortMap.entrySet());\n\n        Collections.sort(list, new Comparator<Map.Entry<Integer, List<String>>>() {\n            public int compare(Map.Entry<Integer, List<String>> o1, Map.Entry<Integer, List<String>> o2) {\n                return o2.getKey().compareTo(o1.getKey());\n            }\n        });\n\n        return list;\n    }\n\n\n\n    /**\n     * https://discuss.leetcode.com/topic/107751/my-simple-java-solution-using-hashmap-priorityqueue-o-nlogk-time-o-n-space\n     */\n    public List<String> topKFrequent3(String[] words, int k) {\n\n        List<String> result = new LinkedList<>();\n        Map<String, Integer> map = new HashMap<>();\n        for(int i=0; i<words.length; i++)\n        {\n            if(map.containsKey(words[i]))\n                map.put(words[i], map.get(words[i])+1);\n            else\n                map.put(words[i], 1);\n        }\n\n        PriorityQueue<Map.Entry<String, Integer>> pq = new PriorityQueue<>(\n                 (a,b) -> a.getValue()==b.getValue() ? b.getKey().compareTo(a.getKey()) : a.getValue()-b.getValue()\n        );\n\n        for(Map.Entry<String, Integer> entry: map.entrySet())\n        {\n            pq.offer(entry);\n            if(pq.size()>k)\n                pq.poll();\n        }\n\n        while(!pq.isEmpty())\n            result.add(0, pq.poll().getKey());\n\n        return result;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/108675/java-hashmap-maxheap-o-nlogn\n     */\n    public List<String> topKFrequent4(String[] words, int k) {\n        HashMap<String, Integer > map = new HashMap<>();\n        for (String s : words)  map.put(s, map.getOrDefault(s,0) + 1);  // Frequent hashmap\n\n        PriorityQueue<Map.Entry<String,Integer>> maxHeap = new PriorityQueue<>(k, (a,b) ->\n            a.getValue()==b.getValue() ? a.getKey().compareTo(b.getKey()) : b.getValue()-a.getValue());\n        // if same frequency, then sort alphabetical .\n\n        for (Map.Entry<String,Integer> entry : map.entrySet() ) maxHeap.add(entry);\n\n        List<String> res = new ArrayList<>();\n        while (res.size() < k) res.add(maxHeap.poll().getKey());  //add top k\n        return res;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/107069/java-o-n-solution-using-hashmap-bucketsort-and-trie-22ms-beat-81\n     */\n    public List<String> topKFrequent5(String[] words, int k) {\n        // calculate frequency of each word\n        Map<String, Integer> freqMap = new HashMap<>();\n        for(String word : words) {\n            freqMap.put(word, freqMap.getOrDefault(word, 0) + 1);\n        }\n        // build the buckets\n        TrieNode[] count = new TrieNode[words.length + 1];\n        for(String word : freqMap.keySet()) {\n            int freq = freqMap.get(word);\n            if(count[freq] == null) {\n                count[freq] = new TrieNode();\n            }\n            addWord(count[freq], word);\n        }\n        // get k frequent words\n        List<String> list = new LinkedList<>();\n        for(int f = count.length - 1; f >= 1 && list.size() < k; f--) {\n            if(count[f] == null) continue;\n            getWords(count[f], list, k);\n        }\n        return list;\n    }\n\n    private void getWords(TrieNode node, List<String> list, int k) {\n        if(node == null) return;\n        if(node.word != null) {\n            list.add(node.word);\n        }\n        if(list.size() == k) return;\n        for(int i = 0; i < 26; i++) {\n            if(node.next[i] != null) {\n                getWords(node.next[i], list, k);\n            }\n        }\n    }\n\n    private boolean addWord(TrieNode root, String word) {\n        TrieNode curr = root;\n        for(char c : word.toCharArray()) {\n            if(curr.next[c - 'a'] == null) {\n                curr.next[c - 'a'] = new TrieNode();\n            }\n            curr = curr.next[c - 'a'];\n        }\n        curr.word = word;\n        return true;\n    }\n\n    class TrieNode {\n        TrieNode[] next;\n        String word;\n        TrieNode() {\n            this.next = new TrieNode[26];\n            this.word = null;\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "src/TotalHammingDistance477.java",
    "content": "/**\n * The Hamming distance (https://en.wikipedia.org/wiki/Hamming_distance) between\n * two integers is the number of positions at which the corresponding bits are different.\n *\n * Now your job is to find the total Hamming distance between all pairs of the given numbers.\n *\n * Example:\n * Input: 4, 14, 2\n *\n * Output: 6\n *\n * Explanation: In binary representation, the 4 is 0100, 14 is 1110, and 2 is\n * 0010 (just showing the four bits relevant in this case). So the answer will\n * be: HammingDistance(4, 14) + HammingDistance(4, 2) + HammingDistance(14, 2)\n * = 2 + 2 + 2 = 6.\n *\n * Note:\n *      Elements of the given array are in the range of 0 to 10^9\n *      Length of the array will not exceed 10^4.\n */\n\n\npublic class TotalHammingDistance477 {\n    /**\n     * https://discuss.leetcode.com/topic/72092/java-o-n-time-o-1-space\n     */\n    public int totalHammingDistance2(int[] nums) {\n        int total = 0, n = nums.length;\n        for (int j=0;j<32;j++) {\n            int bitCount = 0;\n            for (int i=0;i<n;i++)\n                bitCount += (nums[i] >> j) & 1;\n            total += bitCount*(n - bitCount);\n        }\n        return total;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/72104/java-solution-with-explanation\n     */\n    public int totalHammingDistance2(int[] nums) {\n        int n = 31;\n        int len = nums.length;\n        int[] countOfOnes = new int[n];\n        for (int i = 0; i < len; i++) {\n            for (int j = 0; j < n; j++) {\n                countOfOnes[j] += (nums[i] >> j) & 1;\n            }\n        }\n        int sum = 0;\n        for (int count: countOfOnes) {\n            sum += count * (len - count);\n        }\n        return sum;\n    }\n\n}\n"
  },
  {
    "path": "src/TrappingRainWater42.java",
    "content": "/**\n * Given n non-negative integers representing an elevation map where the width\n * of each bar is 1, compute how much water it is able to trap after raining.\n *\n * For example,\n * Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.\n *\n * http://www.leetcode.com/static/images/problemset/rainwatertrap.png\n *\n * The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1].\n * In this case, 6 units of rain water (blue section) are being trapped.\n */\n\npublic class TrappingRainWater42 {\n\n    /**\n     * https://leetcode.com/problems/trapping-rain-water/solution/\n     */\n    // brute force\n    public int trap(int[] height) {\n        int res = 0;\n        for (int i=1; i<height.length-1; i++) {\n            int l = 0;\n            int r = 0;\n            for (int j = i; j >= 0; j--) l = Math.max(l, height[j]);\n            for (int j = i; j < height.length; j++) r = Math.max(r, height[j]);\n            res += Math.min(l, r) - height[i];\n        }\n        return res;\n    }\n\n    public int trap2(int[] height) {\n        if (height.length <= 2) {\n            return 0;\n        }\n\n        Stack<Integer> st = new Stack<>();\n        st.push(0);\n        int p = 1;\n\n        int sum = 0;\n        while(p < height.length) {\n            while(!st.empty() && height[p] > height[st.peek()]) {\n                Integer now = st.pop();\n                if (st.empty()) {\n                    break;\n                }\n                sum += (Math.min(height[p], height[st.peek()]) - height[now]) * (p-st.peek()-1);\n            }\n            st.push(p++);\n        }\n\n        return sum;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/3016/share-my-short-solution\n     */\n    public int trap3(int[] A){\n        int a=0;\n        int b=A.length-1;\n        int max=0;\n        int leftmax=0;\n        int rightmax=0;\n        while(a<=b){\n            leftmax=Math.max(leftmax,A[a]);\n            rightmax=Math.max(rightmax,A[b]);\n            if(leftmax<rightmax){\n                max+=(leftmax-A[a]);       // leftmax is smaller than rightmax, so the (leftmax-A[a]) water can be stored\n                a++;\n            }\n            else{\n                max+=(rightmax-A[b]);\n                b--;\n            }\n        }\n        return max;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/trapping-rain-water/solution/\n     */\n    // DP\n    public int trap4(int[] height) {\n        if (height == null || height.length <= 2) return 0;\n\n        int res = 0;\n        int[] l = new int[height.length];\n        l[0] = height[0];\n        for (int i=1; i<height.length; i++) l[i] = Math.max(l[i-1], height[i]);\n\n        int[] r = new int[height.length];\n        r[height.length-1] = height[height.length-1];\n        for (int i=height.length-2; i>=0; i--) r[i] = Math.max(r[i+1], height[i]);\n\n        for (int i=1; i<height.length-1; i++) res += Math.min(l[i], r[i]) - height[i];\n\n        return res;\n    }\n\n\n    public int trap5(int[] height) {\n        if (height == null || height.length <= 2) return 0;\n\n        int res = 0;\n        int l = 1;\n        int r = 0;\n        Stack<Integer> st = new Stack<>();\n        while (l < height.length) {\n            if (height[l] > height[l-1] && !st.isEmpty()) {\n                int top = st.pop();\n                res += (l-top-1) * (Math.min(height[l], height[top]) - height[l-1]);\n\n            }\n\n            if (l <= height.length-3 && height[l] > height[l+1]) {\n                st.add(l);\n            }\n            l++;\n        }\n\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/TrappingRainWaterII407.java",
    "content": "/**\n * Given an m x n matrix of positive integers representing the height of each\n * unit cell in a 2D elevation map, compute the volume of water it is able to\n * trap after raining.\n * \n * Note:\n * Both m and n are less than 110. The height of each unit cell is greater than\n * 0 and is less than 20,000.\n * \n * Example:\n * \n * Given the following 3x6 height map:\n * [\n *   [1,4,3,1,3,2],\n *   [3,2,1,3,2,4],\n *   [2,3,3,2,3,1]\n * ]\n * \n * Return 4.\n * \n * https://leetcode.com/static/images/problemset/rainwater_empty.png\n * \n * The above image represents the elevation map\n * [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]] before the rain.\n * \n * https://leetcode.com/static/images/problemset/rainwater_fill.png\n * \n * After the rain, water is trapped between the blocks. The total volume of\n * water trapped is 4.\n */\n\npublic class TrappingRainWaterII407 {\n    public int trapRainWater(int[][] heightMap) {\n        if (heightMap == null || heightMap.length < 3 || heightMap[0].length < 3) return 0;\n        int M = heightMap.length;\n        int N = heightMap[0].length;\n        boolean[][] visited = new boolean[M][N];\n        // lambda function is much slower than anonymous Comparator class,\n        // due to first-time initialization overhead of lambda expressions\n        PriorityQueue<Pair> pq = new PriorityQueue<>(1, new Comparator<Pair>(){\n            public int compare(Pair a, Pair b) {\n                return a.value - b.value;\n            }\n        });\n        for (int j=0; j<N; j++) {\n            pq.add(new Pair(0, j, heightMap[0][j]));\n            visited[0][j] = true;\n            pq.offer(new Pair(M-1, j, heightMap[M-1][j]));\n            visited[M-1][j] = true;\n        }\n        for (int i=1; i<M-1; i++) {\n            pq.add(new Pair(i, 0, heightMap[i][0]));\n            visited[i][0] = true;\n            pq.offer(new Pair(i, N-1, heightMap[i][N-1]));\n            visited[i][N-1] = true;\n        }\n\n        int[][] directions = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};\n        int res = 0;\n        int max = Integer.MIN_VALUE;\n        while (!pq.isEmpty()) {\n            Pair top = pq.poll();\n            max = Math.max(max, top.value);\n            for (int[] d: directions) {\n                int x = top.x + d[0];\n                int y = top.y + d[1];\n                if (x < 0 || y < 0 || x >= M || y >= N || visited[x][y]) continue;\n                if (max > heightMap[x][y]) res += max - heightMap[x][y];\n                pq.offer(new Pair(x, y, heightMap[x][y]));\n                visited[x][y] = true;\n            }\n\n        }\n\n        return res;\n    }\n\n    class Pair {\n        int x;\n        int y;\n        int value;\n        Pair(int i, int j, int v) {\n            x = i;\n            y = j;\n            value = v;\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/trapping-rain-water-ii/discuss/89477/Java-solution-beating-100\n     */\n    private static class Cell implements Comparable<Cell> {\n        private int row;\n        private int col;\n        private int value;\n        public Cell(int r, int c, int v) {\n            this.row = r;\n            this.col = c;\n            this.value = v;\n        }\n        @Override\n        public int compareTo(Cell other) {\n            return value - other.value;\n        }\n    }\n    private int water;\n    private boolean[][] visited1;\n    public int trapRainWater2(int[][] heightMap) {\n        if (heightMap.length == 0) return 0;\n        PriorityQueue<Cell> walls = new PriorityQueue<Cell>();\n        water = 0;\n        visited1 = new boolean[heightMap.length][heightMap[0].length];\n        int rows = heightMap.length, cols = heightMap[0].length;\n        //build wall;\n        for (int c = 0; c < cols; c++) {\n          walls.add(new Cell(0, c, heightMap[0][c]));\n          walls.add(new Cell(rows - 1, c, heightMap[rows - 1][c]));\n          visited1[0][c] = true;\n          visited1[rows - 1][c] = true;\n        }\n        for (int r = 1; r < rows - 1; r++) {\n          walls.add(new Cell(r, 0, heightMap[r][0]));\n          walls.add(new Cell(r, cols - 1, heightMap[r][cols - 1]));\n          visited1[r][0] = true;\n          visited1[r][cols - 1] = true;\n        }\n        //end build wall;\n        while(walls.size() > 0) {\n            Cell min = walls.poll();\n            visit(heightMap, min, walls);\n        }\n        return water;\n    }\n    private void visit(int[][] height, Cell start, PriorityQueue<Cell> walls) {\n        fill(height, start.row + 1, start.col, walls, start.value);\n        fill(height, start.row - 1, start.col, walls, start.value);\n        fill(height, start.row, start.col + 1, walls, start.value);\n        fill(height, start.row, start.col - 1, walls, start.value);\n    }\n    private void fill(int[][] height, int row, int col, PriorityQueue<Cell> walls, int min) {\n        if (row < 0 || col < 0) return;\n        else if (row >= height.length || col >= height[0].length) return;\n        else if (visited1[row][col]) return;\n        else if (height[row][col] >= min) {\n            walls.add(new Cell(row, col, height[row][col]));\n            visited1[row][col] = true;\n            return;\n        } else {\n            water += min - height[row][col];\n            visited1[row][col] = true;\n            fill(height, row + 1, col, walls, min);\n            fill(height, row - 1, col, walls, min);\n            fill(height, row, col + 1, walls, min);\n            fill(height, row, col - 1, walls, min);\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "src/TreeLinkNode.java",
    "content": "/**\n * Definition for binary tree with next pointer.\n */\n\npublic class TreeLinkNode {\n    int val;\n    TreeLinkNode left, right, next;\n    TreeLinkNode(int x) { val = x; }\n}\n"
  },
  {
    "path": "src/TreeNode.java",
    "content": "/**\n * Definition for a binary tree node.\n */\n\npublic class TreeNode {\n    int val;\n    TreeNode left;\n    TreeNode right;\n    TreeNode(int x) { val = x; }\n}\n"
  },
  {
    "path": "src/TreeToForestByErasingNodes.java",
    "content": "/**\n * \n */\n\npublic class TreeToForestByErasingNodes {\n\n    // shouldBeErased is predefined\n\n    public List<Node> treeToForest(Node root) {\n        List<Node> res = new ArrayList<>();\n        dfs(root, true, res);\n        return res;\n    }\n\n    private Node dfs(Node curr, boolean parentIsErasable, List<Node> res) {\n        if (curr == null) return null;\n        boolean currIsErasable = shouldBeErased(curr);\n        if (parentIsErasable && !currIsErasable) res.add(curr);\n        curr.left = dfs(curr.left, currIsErasable, res);\n        curr.right = dfs(curr.right, currIsErasable, res);\n        return currIsErasable ? null : curr;\n    }\n\n    class Node {\n        Node left;\n        Node right;\n    }\n\n}\n"
  },
  {
    "path": "src/Triangle120.java",
    "content": "/**\n * Given a triangle, find the minimum path sum from top to bottom. Each step\n * you may move to adjacent numbers on the row below.\n * \n * For example, given the following triangle\n * \n * [\n *      [2],\n *     [3,4],\n *    [6,5,7],\n *   [4,1,8,3]\n * ]\n * The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).\n * \n * Note:\n * Bonus point if you are able to do this using only O(n) extra space, where\n * n is the total number of rows in the triangle.\n */\n\npublic class Triangle120 {\n    public int minimumTotal(List<List<Integer>> triangle) {\n        if (triangle == null || triangle.size() == 0) return 0;\n        int size = triangle.size();\n        List<Integer> sums = triangle.get(size - 1);\n        int i = size - 2;\n        while (i >= 0) {\n            List<Integer> curr = triangle.get(i);\n            int level = curr.size();\n            for (int j=0; j<level; j++) {\n                curr.set(j, curr.get(j) + Math.min(sums.get(j), sums.get(j+1)));\n            }\n            sums = curr;\n            i--;\n        }\n        return sums.get(0);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/triangle/discuss/38724/7-lines-neat-Java-Solution\n     */\n    public int minimumTotal2(List<List<Integer>> triangle) {\n        int[] A = new int[triangle.size()+1];\n        for(int i=triangle.size()-1;i>=0;i--){\n            for(int j=0;j<triangle.get(i).size();j++){\n                A[j] = Math.min(A[j],A[j+1])+triangle.get(i).get(j);\n            }\n        }\n        return A[0];\n    }\n\n}\n"
  },
  {
    "path": "src/TrimABinarySearchTree669.java",
    "content": "/**\n * Given a binary search tree and the lowest and highest boundaries as L and R,\n * trim the tree so that all its elements lies in [L, R] (R >= L). You might\n * need to change the root of the tree, so the result should return the new\n * root of the trimmed binary search tree.\n * \n * Example 1:\n * Input: \n *     1\n *    / \\\n *   0   2\n * \n *   L = 1\n *   R = 2\n * \n * Output: \n *     1\n *       \\\n *        2\n * \n * Example 2:\n * Input: \n *     3\n *    / \\\n *   0   4\n *    \\\n *     2\n *    /\n *   1\n * \n *   L = 1\n *   R = 3\n * \n * Output: \n *       3\n *      / \n *    2   \n *   /\n *  1\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class TrimABinarySearchTree669 {\n    public TreeNode trimBST(TreeNode root, int L, int R) {\n        if (root == null) return null;\n        if (root.val < L) return trimBST(root.right, L, R);\n        if (root.val > R) return trimBST(root.left, L, R);\n        root.left = trimBST(root.left, L, R);\n        root.right = trimBST(root.right, L, R);\n        return root;\n    }\n\n}\n"
  },
  {
    "path": "src/TwoSum1.java",
    "content": "/**\n * Given an array of integers, return indices of the two numbers such that\n * they add up to a specific target.\n *\n * You may assume that each input would have exactly one solution, and\n * you may not use the same element twice.\n *\n * Example:\n * Given nums = [2, 7, 11, 15], target = 9,\n *\n * Because nums[0] + nums[1] = 2 + 7 = 9,\n * return [0, 1].\n */\n\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n\npublic class TwoSum1 {\n\n    public int[] twoSum(int[] nums, int target) {\n        Map<Integer, Integer> foundSet = new HashMap<>();\n\n        int[] returns = new int[2];\n        for (int i = 0; i < nums.length; i++) {\n            Integer now = nums[i];\n            Integer lookingfor = target - now;\n            if (foundSet.containsKey(lookingfor)) {\n                returns[0] = foundSet.get(lookingfor);\n                returns[1] = i;\n                return returns;\n            } else {\n                foundSet.put(now, i);\n            }\n        }\n        return returns;\n    }\n\n    public static void main(String[] args) {\n        TwoSum1 ts = new TwoSum1();\n\n        System.out.println(ts.twoSum(new int[]{2, 7, 11, 15}, 9));\n        System.out.println(ts.twoSum(new int[]{1, 2, 3}, 5));\n    }\n\n}\n"
  },
  {
    "path": "src/TwoSumIIInputArrayIsSorted167.java",
    "content": "/**\n * Given an array of integers that is already sorted in ascending order, find\n * two numbers such that they add up to a specific target number.\n * \n * The function twoSum should return indices of the two numbers such that they\n * add up to the target, where index1 must be less than index2.\n * \n * Note:\n * Your returned answers (both index1 and index2) are not zero-based.\n * You may assume that each input would have exactly one solution and you may\n * not use the same element twice.\n * \n * Example:\n * Input: numbers = [2,7,11,15], target = 9\n * Output: [1,2]\n * Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.\n */\n\npublic class TwoSumIIInputArrayIsSorted167 {\n    public int[] twoSum(int[] numbers, int target) {\n        if (numbers == null || numbers.length < 2) return new int[2];\n        \n        int len = numbers.length;\n        for (int i=0; i<=len-2; i++) {\n            int idx = binarySearch(numbers, target-numbers[i], i+1, len-1);\n            if (idx != -1) {\n                return new int[]{i+1, idx+1};\n            }\n        }\n        \n        return new int[2];\n    }\n\n    private int binarySearch(int[] numbers, int target, int l, int r) {\n        if (l > r) return -1;\n        if (l == r) return numbers[l] == target ? l : -1;\n        \n        int mid = (l + r) / 2;\n        if (numbers[mid] == target) return mid;\n        if (numbers[mid] > target) {\n            return binarySearch(numbers, target, l, mid-1);\n        } else {\n            return binarySearch(numbers, target, mid+1, r);\n        }\n    }\n\n\n    // using Arrays.binarySearch\n    public int[] twoSum2(int[] numbers, int target) {\n        if (numbers == null || numbers.length < 2) return new int[2];\n        \n        int len = numbers.length;\n        for (int i=0; i<=len-2; i++) {\n            int idx = Arrays.binarySearch(numbers, i+1, len, target - numbers[i]);\n            if (idx >= 0) {\n                return new int[]{i+1, idx+1};\n            }\n        }\n        \n        return new int[2];\n    }\n\n}\n"
  },
  {
    "path": "src/TwoSumIVInputIsABST653.java",
    "content": "/**\n * Given a Binary Search Tree and a target number, return true if there exist\n * two elements in the BST such that their sum is equal to the given target.\n * \n * Example 1:\n * Input: \n *     5\n *    / \\\n *   3   6\n *  / \\   \\\n * 2   4   7\n * \n * Target = 9\n * Output: True\n * \n * Example 2:\n * Input: \n *     5\n *    / \\\n *   3   6\n *  / \\   \\\n * 2   4   7\n * \n * Target = 28\n * Output: False\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class TwoSumIVInputIsABST653 {\n    public boolean findTarget(TreeNode root, int k) {\n        List<Integer> list = treeToList(root);\n        \n        for (int i=0; i<list.size(); i++) {\n            int remain = k - list.get(i);\n            for (int j=i+1; j<list.size(); j++) {\n                if (list.get(j) == remain) return true;\n                else if (list.get(j) > remain) break;\n            }\n        }\n        return false;\n    }\n\n    public boolean findTarget2(TreeNode root, int k) {\n        List<Integer> list = treeToList(root);\n        if (list.size() <= 1) return false;\n        int l = 0;\n        int r = list.size() - 1;\n        while (l < r) {\n            int sum = list.get(l) + list.get(r);\n            if (sum == k) return true;\n            if (sum < k) {\n                l++;\n            } else {\n                r--;\n            }\n        }\n        return false;\n    }\n\n    private List<Integer> treeToList(TreeNode root) {\n        List<Integer> res = new ArrayList<>();\n        dfs(root, res);\n        return res;\n    }\n    \n    private void dfs(TreeNode root, List<Integer> res) {\n        if (root == null) return;\n        dfs(root.left, res);\n        res.add(root.val);\n        dfs(root.right, res);\n    }\n\n\n    public boolean findTarget3(TreeNode root, int k) {\n        return dfs(root, new HashSet<Integer>(), k);\n    }\n    \n    private boolean dfs(TreeNode root, Set<Integer> set, int k) {\n        if (root == null) return false;\n        if (set.contains(k - root.val)) return true;\n        set.add(root.val);\n        return dfs(root.left, set, k) || dfs(root.right, set, k);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/two-sum-iv-input-is-a-bst/solution/\n     */\n    public boolean findTarget4(TreeNode root, int k) {\n        Set < Integer > set = new HashSet();\n        Queue < TreeNode > queue = new LinkedList();\n        queue.add(root);\n        while (!queue.isEmpty()) {\n            if (queue.peek() != null) {\n                TreeNode node = queue.remove();\n                if (set.contains(k - node.val))\n                    return true;\n                set.add(node.val);\n                queue.add(node.right);\n                queue.add(node.left);\n            } else\n                queue.remove();\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "src/UTF8Validation393.java",
    "content": "/**\n * A character in UTF8 can be from 1 to 4 bytes long, subjected to the following rules:\n *\n * For 1-byte character, the first bit is a 0, followed by its unicode code.\n * For n-bytes character, the first n-bits are all one's, the n+1 bit is 0,\n * followed by n-1 bytes with most significant 2 bits being 10.\n * This is how the UTF-8 encoding would work:\n *\n *    Char. number range  |        UTF-8 octet sequence\n *       (hexadecimal)    |              (binary)\n *    --------------------+---------------------------------------------\n *    0000 0000-0000 007F | 0xxxxxxx\n *    0000 0080-0000 07FF | 110xxxxx 10xxxxxx\n *    0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx\n *    0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n * Given an array of integers representing the data, return whether it is a valid utf-8 encoding.\n *\n * Note:\n * The input is an array of integers. Only the least significant 8 bits of each\n * integer is used to store the data. This means each integer represents only 1 byte of data.\n *\n * Example 1:\n * data = [197, 130, 1], which represents the octet sequence: 11000101 10000010 00000001.\n *\n * Return true.\n * It is a valid utf-8 encoding for a 2-bytes character followed by a 1-byte character.\n *\n * Example 2:\n * data = [235, 140, 4], which represented the octet sequence: 11101011 10001100 00000100.\n *\n * Return false.\n *\n * The first 3 bits are all one's and the 4th bit is 0 means it is a 3-bytes character.\n * The next byte is a continuation byte which starts with 10 and that's correct.\n * But the second continuation byte does not start with 10, so it is invalid.\n */\n\n\npublic class UTF8Validation393 {\n    public boolean validUtf8(int[] data) {\n        int L = data.length;\n        if (L == 0) return false;\n\n        for (int k = 0; k<L; ) {\n            int num = data[k];\n            if (getBit(num, 7) == 0) {\n                k++;\n            } else {\n                int n = 1;\n                while (getBit(num, (7-n)) == 1) n++;\n                if (n == 1 || n > 4 || k+n > L) return false;\n\n                for (int i = 1; i<n; i++) {\n                    int t = data[k+i];\n                    if (getBit(t, 7) != 1 || getBit(t, 6) != 0) return false;\n                }\n\n                k += n;\n            }\n        }\n\n        return true;\n    }\n\n\n    private int getBit(int num, int pos) {\n        return (num >> pos) & 1;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/58338/bit-manipulation-java-6ms\n     */\n    public boolean validUtf82(int[] data) {\n        if(data==null || data.length==0) return false;\n        boolean isValid = true;\n        for(int i=0;i<data.length;i++) {\n            if(data[i]>255) return false; // 1 after 8th digit, 100000000\n            int numberOfBytes = 0;\n            if((data[i] & 128) == 0) { // 0xxxxxxx, 1 byte, 128(10000000)\n                numberOfBytes = 1;\n            } else if((data[i] & 224) == 192) { // 110xxxxx, 2 bytes, 224(11100000), 192(11000000)\n                numberOfBytes = 2;\n            } else if((data[i] & 240) == 224) { // 1110xxxx, 3 bytes, 240(11110000), 224(11100000)\n                numberOfBytes = 3;\n            } else if((data[i] & 248) == 240) { // 11110xxx, 4 bytes, 248(11111000), 240(11110000)\n                numberOfBytes = 4;\n            } else {\n                return false;\n            }\n            for(int j=1;j<numberOfBytes;j++) { // check that the next n bytes start with 10xxxxxx\n                if(i+j>=data.length) return false;\n                if((data[i+j] & 192) != 128) return false; // 192(11000000), 128(10000000)\n            }\n            i=i+numberOfBytes-1;\n        }\n        return isValid;\n    }\n\n}\n"
  },
  {
    "path": "src/UglyNumber263.java",
    "content": "/**\n * Write a program to check whether a given number is an ugly number.\n * \n * Ugly numbers are positive numbers whose prime factors only include 2, 3, 5.\n * \n * Example 1:\n * Input: 6\n * Output: true\n * Explanation: 6 = 2 × 3\n * \n * Example 2:\n * Input: 8\n * Output: true\n * Explanation: 8 = 2 × 2 × 2\n * \n * Example 3:\n * Input: 14\n * Output: false \n * Explanation: 14 is not ugly since it includes another prime factor 7.\n * \n * Note:\n * 1 is typically treated as an ugly number.\n * Input is within the 32-bit signed integer range: [−231,  231 − 1].\n */\n\npublic class UglyNumber263 {\n    public boolean isUgly(int num) {\n        if (num == 1) return true;\n        if (num <= 0) return false;\n        int n = num;\n        if (num % 2 == 0) num /= 2;\n        if (num % 3 == 0) num /= 3;\n        if (num % 5 == 0) num /= 5;\n        if (num == n) return false;\n        return isUgly(num);\n    }\n\n\n    public boolean isUgly2(int num) {\n        if (num <= 0) return false;\n        while (num % 2 == 0) num /= 2;\n        while (num % 3 == 0) num /= 3;\n        while (num % 5 == 0) num /= 5;\n        return num == 1;\n    }\n\n}\n"
  },
  {
    "path": "src/UglyNumberII264.java",
    "content": "/**\n * Write a program to find the n-th ugly number.\n * \n * Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. \n * \n * Example:\n * Input: n = 10\n * Output: 12\n * Explanation: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.\n * \n * Note:\n * 1 is typically treated as an ugly number.\n * n does not exceed 1690.\n */\n\n/**\n * https://www.geeksforgeeks.org/ugly-numbers/\n */\npublic class UglyNumberII264 {\n    public int nthUglyNumber(int n) {\n        if (n < 1) return 0;\n        if (n == 1) return 1;\n        Set<Long> set = new HashSet<>();\n        Comparator<long[]> comp = (a1, a2) -> Long.compare(a1[0] * a1[1], a2[0] * a2[1]);\n        PriorityQueue<long[]> pq = new PriorityQueue<>(1, comp);\n        set.add(1L);\n        pq.add(new long[]{(long)1, (long)2});\n\n        while (true) {\n            long[] curr = pq.poll();\n            long newAdd = curr[0] * curr[1];\n            if (move(curr)) {\n                pq.add(curr);\n            }\n            if (!set.contains(newAdd)) {\n                pq.add(new long[]{newAdd, 2L});\n                set.add(newAdd);\n            }\n            if (set.size() == n) {\n                return (int) newAdd;\n            }\n        }\n    }\n\n    private boolean move(long[] p) {\n        if (p[1] == 5) return false;\n        if (p[1] == 2) {\n            p[1] = 3L;\n        } else {\n            p[1] = 5L;\n        }\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/ugly-number-ii/discuss/69362/O(n)-Java-solution\n     */\n    public int nthUglyNumber2(int n) {\n        int[] ugly = new int[n];\n        ugly[0] = 1;\n        int index2 = 0, index3 = 0, index5 = 0;\n        int factor2 = 2, factor3 = 3, factor5 = 5;\n        for(int i=1;i<n;i++){\n            int min = Math.min(Math.min(factor2,factor3),factor5);\n            ugly[i] = min;\n            if(factor2 == min)\n                factor2 = 2*ugly[++index2];\n            if(factor3 == min)\n                factor3 = 3*ugly[++index3];\n            if(factor5 == min)\n                factor5 = 5*ugly[++index5];\n        }\n        return ugly[n-1];\n    }\n\n\n    /**\n     * https://leetcode.com/problems/ugly-number-ii/discuss/69372/Java-solution-using-PriorityQueue\n     */\n    public int nthUglyNumber3(int n) {\n        if(n==1) return 1;\n        PriorityQueue<Long> q = new PriorityQueue();\n        q.add(1l);\n        \n        for(long i=1; i<n; i++) {\n            long tmp = q.poll();\n            while(!q.isEmpty() && q.peek()==tmp) tmp = q.poll();\n            \n            q.add(tmp*2);\n            q.add(tmp*3);\n            q.add(tmp*5);\n        }\n        return q.poll().intValue();\n    }\n\n}\n\n"
  },
  {
    "path": "src/UncommonWordsFromTwoSentences884.java",
    "content": "/**\n * We are given two sentences A and B.  (A sentence is a string of space separated\n * words.  Each word consists only of lowercase letters.)\n * \n * A word is uncommon if it appears exactly once in one of the sentences, and\n * does not appear in the other sentence.\n * \n * Return a list of all uncommon words.\n * \n * You may return the list in any order.\n * \n * Example 1:\n * Input: A = \"this apple is sweet\", B = \"this apple is sour\"\n * Output: [\"sweet\",\"sour\"]\n * \n * Example 2:\n * Input: A = \"apple apple\", B = \"banana\"\n * Output: [\"banana\"]\n * \n * Note:\n * 0 <= A.length <= 200\n * 0 <= B.length <= 200\n * A and B both contain only spaces and lowercase letters.\n */\n\npublic class UncommonWordsFromTwoSentences884 {\n    public String[] uncommonFromSentences(String A, String B) {\n        Set<String> once = new HashSet<>();\n        Set<String> mult = new HashSet<>();\n        String[] as = A.split(\" \");\n        for (String s: as) {\n            if (once.contains(s)) {\n                once.remove(s);\n                mult.add(s);\n            } else if (!mult.contains(s)) {\n                once.add(s);\n            }\n        }\n        \n        String[] bs = B.split(\" \");\n        Set<String> resCand = new HashSet<>();\n        Set<String> resMult = new HashSet<>();\n        for (String s: bs) {\n            if (!once.contains(s) && !mult.contains(s)) {\n                if (resCand.contains(s)) {\n                    resCand.remove(s);\n                    resMult.add(s);\n                } else if (!resMult.contains(s)) {\n                    resCand.add(s);\n                }\n            } else if (once.contains(s)) {\n                once.remove(s);\n                mult.add(s);\n            }\n        }\n        \n        String[] res = new String[resCand.size() + once.size()];\n        int i = 0;\n        for (String c: resCand) {\n            res[i++] = c;\n        }\n        for (String c: once) {\n            res[i++] = c;\n        }\n        return res;\n    }\n\n    /**\n     * https://leetcode.com/problems/uncommon-words-from-two-sentences/solution/\n     */\n    public String[] uncommonFromSentences2(String A, String B) {\n        Map<String, Integer> count = new HashMap();\n        for (String word: A.split(\" \"))\n            count.put(word, count.getOrDefault(word, 0) + 1);\n        for (String word: B.split(\" \"))\n            count.put(word, count.getOrDefault(word, 0) + 1);\n\n        List<String> ans = new LinkedList();\n        for (String word: count.keySet())\n            if (count.get(word) == 1)\n                ans.add(word);\n\n        return ans.toArray(new String[ans.size()]);\n    }\n}\n"
  },
  {
    "path": "src/UndirectedGraphNode.java",
    "content": "/**\n * Definition for undirected graph.\n */\n\npublic class UndirectedGraphNode {\n    int label;\n    List<UndirectedGraphNode> neighbors;\n    UndirectedGraphNode(int x) {\n        label = x;\n        neighbors = new ArrayList<UndirectedGraphNode>();\n    }\n};\n"
  },
  {
    "path": "src/UniqueBinarySearchTrees96.java",
    "content": "/**\n * Given n, how many structurally unique BST's (binary search trees) that store values 1...n?\n *\n * For example,\n * Given n = 3, there are a total of 5 unique BST's.\n *\n *    1         3     3      2      1\n *     \\       /     /      / \\      \\\n *      3     2     1      1   3      2\n *     /     /       \\                 \\\n *    2     1         2                 3\n *\n */\n\n\npublic class UniqueBinarySearchTrees96 {\n    public int numTrees(int n) {\n        int[][] dp = new int[n][n];\n        for (int s=0; s<n; s++) dp[s][s] = 1;\n\n        for (int i=0; i<n; i++) {\n            for (int j=i+1; j<n; j++) {\n                helper(i, j, dp);\n            }\n        }\n\n        return dp[0][n-1];\n    }\n\n    private int helper(int i, int j, int[][] dp) {\n        if (i > j) return 1;\n        if (dp[i][j] != 0) return dp[i][j];\n\n        int u = 0;\n        for (int r=i; r<=j; r++) {\n            int left = helper(i, r-1, dp);\n            int right = helper(r+1, j, dp);\n            u += left * right;\n        }\n        dp[i][j] = u;\n\n        return u;\n    }\n\n\n    public int numTrees2(int n) {\n        int[] dp = new int[n];\n        return helper2(n-1, dp);\n    }\n\n    private int helper2(int i, int[] dp) {\n        if (i <= 0) return 1;\n        if (dp[i] != 0) return dp[i];\n\n        int u = 0;\n        for (int j=0; j<=i; j++) {\n            int left = helper2(j-1, dp);\n            int right = helper2(i-j-1, dp);\n            u += left * right;\n        }\n        dp[i] = u;\n\n        return u;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/37310/fantastic-clean-java-dp-solution-with-detail-explaination\n     */\n    public int numTrees3(int n) {\n       int [] dp = new int[n+1];\n       dp[0]= 1;\n       dp[1] = 1;\n       for(int level = 2; level <=n; level++)\n           for(int root = 1; root<=level; root++)\n               dp[level] += dp[level-root]*dp[root-1];\n       return dp[n];\n   }\n\n}\n"
  },
  {
    "path": "src/UniqueBinarySearchTreesII95.java",
    "content": "/**\n * Given an integer n, generate all structurally unique BST's (binary search\n * trees) that store values 1...n.\n *\n * For example,\n * Given n = 3, your program should return all 5 unique BST's shown below.\n *\n *    1         3     3      2      1\n *     \\       /     /      / \\      \\\n *      3     2     1      1   3      2\n *     /     /       \\                 \\\n *    2     1         2                 3\n *\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class UniqueBinarySearchTreesII95 {\n    public List<TreeNode> generateTrees(int n) {\n        return generateTrees(n, 1, n);\n    }\n\n    public List<TreeNode> generateTrees(int n, int l, int r) {\n        List<TreeNode> res = new ArrayList<>();\n        if (l > r) return res;\n        for (int i=l; i<=r; i++) {\n            List<TreeNode> lefts = generateTrees(n, l, i-1);\n            if (lefts.isEmpty()) lefts.add(null);\n            List<TreeNode> rights = generateTrees(n, i+1, r);\n            if (rights.isEmpty()) rights.add(null);\n            for (TreeNode ll: lefts) {\n                for (TreeNode rr: rights) {\n                    TreeNode t = new TreeNode(i);\n                    t.left = ll;\n                    t.right = rr;\n                    res.add(t);\n                }\n            }\n        }\n\n        return res;\n    }\n\n\n    // DP\n    public List<TreeNode> generateTrees2(int n) {\n        return generateTrees(n, 1, n, new List[n][n]);\n    }\n\n    public List<TreeNode> generateTrees(int n, int l, int r, List[][] dp) {\n        List<TreeNode> res = new ArrayList<>();\n        if (l > r) return res;\n        if (dp[l-1][r-1] != null) return dp[l-1][r-1];\n        for (int i=l; i<=r; i++) {\n            List<TreeNode> lefts = generateTrees(n, l, i-1, dp);\n            if (lefts.isEmpty()) lefts.add(null);\n            List<TreeNode> rights = generateTrees(n, i+1, r, dp);\n            if (rights.isEmpty()) rights.add(null);\n            for (TreeNode ll: lefts) {\n                for (TreeNode rr: rights) {\n                    TreeNode t = new TreeNode(i);\n                    t.left = ll;\n                    t.right = rr;\n                    res.add(t);\n                }\n            }\n        }\n\n        dp[l-1][r-1] = res;\n        return res;\n    }\n\n\n    public List<TreeNode> generateTrees3(int n) {\n        if (n == 0) return new ArrayList<TreeNode>();\n        List<TreeNode>[][] dp = new List[n][n];\n        \n        List<TreeNode> lefts;\n        List<TreeNode> rights;\n        for (int len=1; len<=n; len++) {\n            for (int start=1; start<=n+1-len; start++) {\n                int end = start + len - 1;\n                List<TreeNode> list = new ArrayList<>();\n                for (int k=start; k<=end; k++) {\n                    \n                    if (start > k-1) {\n                        lefts = new ArrayList<TreeNode>();\n                        lefts.add(null);\n                    } else {\n                        lefts = dp[start-1][k-2];\n                    }\n                    \n                    if (k+1 > end) {\n                        rights = new ArrayList<TreeNode>();\n                        rights.add(null);\n                    } else {\n                        rights = dp[k][end-1];\n                    }\n                    for (TreeNode left: lefts) {\n                        for (TreeNode right: rights) {\n                            TreeNode curr = new TreeNode(k);\n                            curr.left = left;\n                            curr.right = right;\n                            list.add(curr);\n                        }\n                    }\n                }\n                dp[start-1][end-1] = list;\n            }\n        }\n        \n        return dp[0][n-1];\n    }\n\n\n    public List<TreeNode> generateTrees4(int n) {\n        if (n == 0) return new ArrayList<TreeNode>();\n        List<TreeNode>[][] dp = new List[n][n];\n        for (int i=0; i<n; i++) {\n            List<TreeNode> l = new ArrayList<>();\n            l.add(new TreeNode(i+1));\n            dp[i][i] = l;\n        }\n        for (int len=1; len<n; len++) {\n            for (int i=0; i<n-len; i++) {\n                List<TreeNode> l = new ArrayList<>();\n                for (int j=i; j<=i+len; j++) {\n                    add(dp, i, j, i+len, l);\n                }\n                dp[i][i+len] = l;\n            }\n        }\n        \n        return dp[0][n-1];\n    }\n\n    private void add(List<TreeNode>[][] dp, int i, int j, int k, List<TreeNode> l) {\n        List<TreeNode> lefts = get(dp, i, j-1);\n        List<TreeNode> rights = get(dp, j+1, k);\n        \n        for (TreeNode lf: lefts) {\n            for (TreeNode rt: rights) {\n                TreeNode n = new TreeNode(j+1);\n                n.left = lf;\n                n.right = rt;\n                l.add(n);\n            }\n        }\n    }\n    \n    private List<TreeNode> get(List<TreeNode>[][] dp, int i, int j) {\n        if (i > j) {\n            List<TreeNode> l = new ArrayList<>();\n            l.add(null);\n            return l;\n        }\n        return dp[i][j];\n    }\n\n}\n"
  },
  {
    "path": "src/UniqueMorseCodeWords804.java",
    "content": "/**\n * International Morse Code defines a standard encoding where each letter is\n * mapped to a series of dots and dashes, as follows: \"a\" maps to \".-\", \"b\"\n * maps to \"-...\", \"c\" maps to \"-.-.\", and so on.\n * \n * For convenience, the full table for the 26 letters of the English alphabet\n * is given below:\n * [\".-\",\"-...\",\"-.-.\",\"-..\",\".\",\"..-.\",\"--.\",\"....\",\"..\",\".---\",\"-.-\",\".-..\",\n * \"--\",\"-.\",\"---\",\".--.\",\"--.-\",\".-.\",\"...\",\"-\",\"..-\",\"...-\",\".--\",\"-..-\",\n * \"-.--\",\"--..\"]\n * \n * Now, given a list of words, each word can be written as a concatenation of\n * the Morse code of each letter. For example, \"cab\" can be written as\n * \"-.-.-....-\", (which is the concatenation \"-.-.\" + \"-...\" + \".-\"). We'll\n * call such a concatenation, the transformation of a word.\n * \n * Return the number of different transformations among all words we have.\n * \n * Example:\n * Input: words = [\"gin\", \"zen\", \"gig\", \"msg\"]\n * Output: 2\n * Explanation: \n * The transformation of each word is:\n * \"gin\" -> \"--...-.\"\n * \"zen\" -> \"--...-.\"\n * \"gig\" -> \"--...--.\"\n * \"msg\" -> \"--...--.\"\n * \n * There are 2 different transformations, \"--...-.\" and \"--...--.\".\n * \n * Note:\n * The length of words will be at most 100.\n * Each words[i] will have length in range [1, 12].\n * words[i] will only consist of lowercase letters.\n */\n\npublic class UniqueMorseCodeWords804 {\n    private String[] MOSRE_TABLE = new String[]{\".-\",\"-...\",\"-.-.\",\"-..\",\".\",\"..-.\",\"--.\",\"....\",\"..\",\".---\",\"-.-\",\".-..\",\"--\",\"-.\",\"---\",\".--.\",\"--.-\",\".-.\",\"...\",\"-\",\"..-\",\"...-\",\".--\",\"-..-\",\"-.--\",\"--..\"};\n    public int uniqueMorseRepresentations(String[] words) {\n        Set<String> set = new HashSet<>();\n        for (String word: words) {\n            set.add(getMorseCode(word));\n        }\n        return set.size();\n    }\n\n    private String getMorseCode(String word) {\n        StringBuilder sb = new StringBuilder();\n        for (char ch: word.toCharArray()) {\n            sb.append(MOSRE_TABLE[ch-'a']);\n        }\n        return sb.toString();\n    }\n\n}\n"
  },
  {
    "path": "src/UniquePaths62.java",
    "content": "/**\n * A robot is located at the top-left corner of a m x n grid (marked 'Start'\n * in the diagram below).\n *\n * The robot can only move either down or right at any point in time. The robot\n * is trying to reach the bottom-right corner of the grid (marked 'Finish' in\n * the diagram below).\n *\n * How many possible unique paths are there?\n *\n * https://leetcode.com/static/images/problemset/robot_maze.png\n *\n * Above is a 3 x 7 grid. How many possible unique paths are there?\n *\n * Note: m and n will be at most 100.\n *\n */\n\n\npublic class UniquePaths62 {\n    public int uniquePaths(int m, int n) {\n        if (m == 1 || n == 1) return 1;\n        int s = Math.min(m, n);\n        int l = Math.max(m, n);\n        int[][] dp = new int[s][l];\n        return uniquePaths(m, n, dp);\n    }\n\n    private int uniquePaths(int m, int n, int[][] dp) {\n        if (m == 1 || n == 1) return 1;\n        int s = Math.min(m, n);\n        int l = Math.max(m, n);\n        if (dp[s-1][l-1] != 0) return dp[s-1][l-1];\n\n        int a = uniquePaths(s-1, l, dp);\n        int b = uniquePaths(s, l-1, dp);\n        dp[s-1][l-1] = a + b;\n        return a + b;\n    }\n\n    public int uniquePaths2(int m, int n) {\n        int[] row = new int[n];\n        Arrays.fill(row,1);\n        for ( int i = 1; i < m; i++){\n            for ( int j = 1; j < n; j++){\n                row[j]+=row[j-1];\n            }\n        }\n        return row[n-1];\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/31724/java-solution-0ms-4lines\n     */\n    public int uniquePaths3(int m, int n) {\n        long result = 1;\n        for(int i=0;i<Math.min(m-1,n-1);i++)\n            result = result*(m+n-2-i)/(i+1);\n        return (int)result;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/23866/clean-and-simple-dp-java\n     */\n    public int uniquePaths4(int m, int n) {\n        int[][] grid = new int[m][n];\n        for(int i = 0; i<m; i++){\n            for(int j = 0; j<n; j++){\n                if(i==0||j==0)\n                    grid[i][j] = 1;\n                else\n                    grid[i][j] = grid[i][j-1] + grid[i-1][j];\n            }\n        }\n        return grid[m-1][n-1];\n    }\n}\n"
  },
  {
    "path": "src/UniquePathsII63.java",
    "content": "/**\n * Follow up for \"Unique Paths\":\n *\n * Now consider if some obstacles are added to the grids. How many unique paths\n * would there be?\n *\n * An obstacle and empty space is marked as 1 and 0 respectively in the grid.\n *\n * For example,\n * There is one obstacle in the middle of a 3x3 grid as illustrated below.\n *\n * [\n *   [0,0,0],\n *   [0,1,0],\n *   [0,0,0]\n * ]\n * The total number of unique paths is 2.\n *\n * Note: m and n will be at most 100.\n */\n\n\npublic class UniquePathsII63 {\n    public int uniquePathsWithObstacles(int[][] obstacleGrid) {\n        int m = obstacleGrid.length;\n        int n = obstacleGrid[0].length;\n        if (m == 0) return 0;\n        int[][] dp = new int[m][n];\n\n        dp[0][0] = (obstacleGrid[0][0] == 1) ? 0 : 1;\n        for (int i=1; i<m; i++) dp[i][0] = (obstacleGrid[i][0] == 1) ? 0 : dp[i-1][0];\n        for (int j=1; j<n; j++) dp[0][j] = (obstacleGrid[0][j] == 1) ? 0 : dp[0][j-1];\n\n        for (int i=1; i<m; i++) {\n            for (int j=1; j<n; j++) {\n                dp[i][j] = (obstacleGrid[i][j] == 1) ? 0 : dp[i][j-1] + dp[i-1][j];\n            }\n        }\n\n        return dp[m-1][n-1];\n    }\n\n\n    public int uniquePathsWithObstacles2(int[][] obstacleGrid) {\n        int m = obstacleGrid.length;\n        int n = obstacleGrid[0].length;\n        if (m == 0) return 0;\n        int[] dp = new int[n];\n\n        dp[0] = (obstacleGrid[0][0] == 1) ? 0 : 1;\n        for (int j=1; j<n; j++) dp[j] = (obstacleGrid[0][j] == 1) ? 0 : dp[j-1];\n\n        for (int i=1; i<m; i++) {\n            dp[0] = (obstacleGrid[i][0] == 1) ? 0 : dp[0];\n            for (int j=1; j<n; j++) {\n                dp[j] = (obstacleGrid[i][j] == 1) ? 0 : (dp[j-1] + dp[j]);\n            }\n        }\n\n        return dp[n-1];\n    }\n\n}\n"
  },
  {
    "path": "src/UniqueWordAbbreviation288.java",
    "content": "/**\n * An abbreviation of a word follows the form\n * <first letter><number><last letter>. Below are some examples of word\n * abbreviations:\n * \n * a) it                      --> it    (no abbreviation)\n * \n *      1\n *      ↓\n * b) d|o|g                   --> d1g\n * \n *               1    1  1\n *      1---5----0----5--8\n *      ↓   ↓    ↓    ↓  ↓    \n * c) i|nternationalizatio|n  --> i18n\n * \n *               1\n *      1---5----0\n *      ↓   ↓    ↓\n * d) l|ocalizatio|n          --> l10n\n * Assume you have a dictionary and given a word, find whether its abbreviation\n * is unique in the dictionary. A word's abbreviation is unique if no other\n * word from the dictionary has the same abbreviation.\n * \n * Example:\n * Given dictionary = [ \"deer\", \"door\", \"cake\", \"card\" ]\n * isUnique(\"dear\") -> false\n * isUnique(\"cart\") -> true\n * isUnique(\"cane\") -> false\n * isUnique(\"make\") -> true\n */\n\npublic class UniqueWordAbbreviation288 {\n    class ValidWordAbbr {\n        Map<String, Set<String>> map = new HashMap<>();\n\n        public ValidWordAbbr(String[] dictionary) {\n            for (String word: dictionary) {\n                String encoded = encode(word);\n                if (!map.containsKey(encoded)) {\n                    map.put(encoded, new HashSet<>());\n                }\n                map.get(encoded).add(word);\n            }\n        }\n\n        public boolean isUnique(String word) {\n            String encoded = encode(word);\n            return !map.containsKey(encoded) || (map.get(encoded).size() == 1 && map.get(encoded).contains(word));\n        }\n        \n        private String encode(String word) {\n            if (word.length() <= 2) return word;\n            return word.charAt(0) + Integer.toString(word.length()-2) + word.charAt(word.length()-1);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/unique-word-abbreviation/solution/\n     */\n    public class ValidWordAbbr2 {\n        private final Map<String, Boolean> abbrDict = new HashMap<>();\n        private final Set<String> dict;\n\n        public ValidWordAbbr2(String[] dictionary) {\n            dict = new HashSet<>(Arrays.asList(dictionary));\n            for (String s : dict) {\n                String abbr = toAbbr(s);\n                abbrDict.put(abbr, !abbrDict.containsKey(abbr));\n            }\n        }\n\n        public boolean isUnique(String word) {\n            String abbr = toAbbr(word);\n            Boolean hasAbbr = abbrDict.get(abbr);\n            return hasAbbr == null || (hasAbbr && dict.contains(word));\n        }\n\n        private String toAbbr(String s) {\n            int n = s.length();\n            if (n <= 2) {\n                return s;\n            }\n            return s.charAt(0) + Integer.toString(n - 2) + s.charAt(n - 1);\n        }\n    }\n\n\n/**\n * Your ValidWordAbbr object will be instantiated and called as such:\n * ValidWordAbbr obj = new ValidWordAbbr(dictionary);\n * boolean param_1 = obj.isUnique(word);\n */\n\n}\n\n"
  },
  {
    "path": "src/ValidAnagram242.java",
    "content": "/**\n * Given two strings s and t, write a function to determine if t is an\n * anagram of s.\n *\n * For example,\n * s = \"anagram\", t = \"nagaram\", return true.\n * s = \"rat\", t = \"car\", return false.\n *\n * Note:\n * You may assume the string contains only lowercase alphabets.\n *\n * Follow up:\n * What if the inputs contain unicode characters? How would you adapt your\n * solution to such case?\n */\n\npublic class ValidAnagram242 {\n    public boolean isAnagram(String s, String t) {\n        int[] cs = new int[26];\n        for (int i=0; i<s.length(); i++) cs[s.charAt(i)-'a']++;\n        int[] ct = new int[26];\n        for (int i=0; i<t.length(); i++) ct[t.charAt(i)-'a']++;\n        for (int i=0; i<26; i++) {\n            if (cs[i] != ct[i]) return false;\n        }\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/valid-anagram/solution/\n     */\n    public boolean isAnagram2(String s, String t) {\n        if (s.length() != t.length()) {\n            return false;\n        }\n        char[] str1 = s.toCharArray();\n        char[] str2 = t.toCharArray();\n        Arrays.sort(str1);\n        Arrays.sort(str2);\n        return Arrays.equals(str1, str2);\n    }\n\n    /**\n     * https://leetcode.com/problems/valid-anagram/solution/\n     */\n    public boolean isAnagram3(String s, String t) {\n        if (s.length() != t.length()) {\n            return false;\n        }\n        int[] counter = new int[26];\n        for (int i = 0; i < s.length(); i++) {\n            counter[s.charAt(i) - 'a']++;\n            counter[t.charAt(i) - 'a']--;\n        }\n        for (int count : counter) {\n            if (count != 0) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "src/ValidNumber65.java",
    "content": "/**\n * Validate if a given string is numeric.\n * \n * Some examples:\n * \"0\" => true\n * \" 0.1 \" => true\n * \"abc\" => false\n * \"1 a\" => false\n * \"2e10\" => true\n * \n * Note: It is intended for the problem statement to be ambiguous. You should\n * gather all requirements up front before implementing one.\n */\n\npublic class ValidNumber65 {\n    public boolean isNumber(String s) {\n        try {\n            Double.valueOf(s);\n        } catch (Exception e1) {\n            return false;\n        }\n        char last = s.charAt(s.length()-1);\n        if(last == 'D' || last == 'd' || last == 'f' || last == 'F') return false;\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/ValidPalindrome125.java",
    "content": "/**\n * Given a string, determine if it is a palindrome, considering only alphanumeric\n * characters and ignoring cases.\n *\n * For example,\n * \"A man, a plan, a canal: Panama\" is a palindrome.\n * \"race a car\" is not a palindrome.\n *\n * Note:\n * Have you consider that the string might be empty? This is a good question to\n * ask during an interview.\n *\n * For the purpose of this problem, we define empty string as valid palindrome.\n *\n */\n\n\npublic class ValidPalindrome125 {\n    public boolean isPalindrome(String s) {\n        int l = 0;\n        int r = s.length()-1;\n        s = s.toLowerCase();\n        while (l < r) {\n            while (!isLowerAlphanumeric(s.charAt(l)) && l < r) {\n                l++;\n            }\n            while (!isLowerAlphanumeric(s.charAt(r)) && l < r) {\n                r--;\n            }\n            if (s.charAt(l) != s.charAt(r)) return false;\n            l++;\n            r--;\n        }\n\n        return true;\n    }\n\n    private boolean isLowerAlphanumeric(char c) {\n        return (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9');\n    }\n\n\n    public boolean isPalindrome2(String s) {\n        int l = 0;\n        int r = s.length()-1;\n        // s = s.toLowerCase();\n        while (l < r) {\n            while (!isAlphanumeric(s.charAt(l)) && l < r) {\n                l++;\n            }\n            while (!isAlphanumeric(s.charAt(r)) && l < r) {\n                r--;\n            }\n            if (Character.toLowerCase(s.charAt(l)) != Character.toLowerCase(s.charAt(r))) return false;\n            l++;\n            r--;\n        }\n\n        return true;\n    }\n\n    private boolean isAlphanumeric(char c) {\n        return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9');\n    }\n\n}\n"
  },
  {
    "path": "src/ValidPalindromeII680.java",
    "content": "/**\n * Given a non-empty string s, you may delete at most one character.\n * Judge whether you can make it a palindrome.\n *\n * Example 1:\n * Input: \"aba\"\n * Output: True\n *\n * Example 2:\n * Input: \"abca\"\n * Output: True\n *\n * Explanation: You could delete the character 'c'.\n * Note:\n * The string will only contain lowercase characters a-z.\n * The maximum length of the string is 50000.\n *\n */\n\n\npublic class ValidPalindromeII680 {\n    public boolean validPalindrome(String s) {\n        return validPalindrome(s, 0, s.length()-1, false);\n    }\n\n    private boolean validPalindrome(String s, int l, int r, boolean flag) {\n        while (l < r) {\n            if (s.charAt(l) == s.charAt(r)) {\n                l++;\n                r--;\n                continue;\n            }\n\n            if (flag) return false;\n            if (l == r) return true;\n            return validPalindrome(s, l+1, r, true) || validPalindrome(s, l, r-1, true);\n        }\n\n        return true;\n    }\n\n    // // stackoverflow\n    // private boolean validPalindrome(String s, int l, int r, boolean flag) {\n    //     if (l >= r) return true;\n    //     if (s.charAt(l) == s.charAt(r)) {\n    //         return validPalindrome(s, l+1, r-1, flag);\n    //     } else if (!flag) {\n    //         return validPalindrome(s, l+1, r, true) || validPalindrome(s, l, r-1, true);\n    //     } else {\n    //         return false;\n    //     }\n    // }\n\n}\n"
  },
  {
    "path": "src/ValidParentheses20.java",
    "content": "/**\n * Given a string containing just the characters '(', ')', '{', '}', '[' and ']',\n * determine if the input string is valid.\n *\n * The brackets must close in the correct order, \"()\" and \"()[]{}\" are all\n * valid but \"(]\" and \"([)]\" are not.\n */\n\n\nimport java.util.Map;\nimport java.util.HashMap;\nimport java.util.Stack;\n\n\npublic class ValidParentheses20 {\n    public boolean isValid(String s) {\n        char[] chars = s.toCharArray();\n\n        Stack st = new Stack();\n\n        for (char c: chars) {\n\n            if (isBackP(c)) {\n                if (st.empty()) {\n                    return false;\n                } else {\n                    char top = (char) st.pop();\n                    if (c != top) {\n                        return false;\n                    }\n                }\n            } else {\n                st.push(pair(c));\n            }\n        }\n\n        return st.empty();\n    }\n\n    private boolean isBackP(char c) {\n        return c == '}' || c == ']' || c == ')';\n    }\n\n    private char pair(char c) {\n        if (c == '{') {\n            return '}';\n        } else if (c == '[') {\n            return ']';\n        } else {\n            return ')';\n        }\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/27572/short-java-solution\n     */\n    public boolean isValid2(String s) {\n      \tStack<Character> stack = new Stack<Character>();\n      \tfor (char c : s.toCharArray()) {\n        \t\tif (c == '(')\n        \t\t\t  stack.push(')');\n        \t\telse if (c == '{')\n        \t\t\t  stack.push('}');\n        \t\telse if (c == '[')\n        \t\t\t  stack.push(']');\n        \t\telse if (stack.isEmpty() || stack.pop() != c)\n        \t\t\t  return false;\n      \t}\n      \treturn stack.isEmpty();\n    }\n\n\n\n    public boolean isValid3(String s) {\n        if (s == null || s.length()%2 == 1) return false;\n        if (s.length() == 0) return true;\n\n        Stack<Character> st = new Stack<>();\n        for (char c : s.toCharArray()) {\n            if (c == '(' || c == '[' || c == '{') {\n                st.push(c);\n                continue;\n            }\n\n            if (st.isEmpty()) return false;\n\n            switch (c) {\n                case ')':\n                    if (st.peek() == '(') {\n                        st.pop();\n                        break;\n                    } else {\n                        return false;\n                    }\n                case ']':\n                    if (st.peek() == '[') {\n                        st.pop();\n                        break;\n                    } else {\n                        return false;\n                    }\n                case '}':\n                    if (st.peek() == '{') {\n                        st.pop();\n                        break;\n                    } else {\n                        return false;\n                    }\n                default: return false;\n            }\n\n        }\n\n        return st.isEmpty();\n    }\n\n\n    public static void main(String[] args) {\n        ValidParentheses20 vp = new ValidParentheses20();\n\n        System.out.println(vp.isValid(\"[\"));\n        System.out.println(vp.isValid(\"]\"));\n        System.out.println(vp.isValid(\"[]\"));\n    }\n\n}\n"
  },
  {
    "path": "src/ValidParenthesisString678.java",
    "content": "/**\n * Given a string containing only three types of characters: '(', ')' and '*',\n * write a function to check whether this string is valid. We define the\n * validity of a string by these rules:\n * \n * Any left parenthesis '(' must have a corresponding right parenthesis ')'.\n * Any right parenthesis ')' must have a corresponding left parenthesis '('.\n * Left parenthesis '(' must go before the corresponding right parenthesis ')'.\n * '*' could be treated as a single right parenthesis ')' or a single left parenthesis '(' or an empty string.\n * An empty string is also valid.\n * \n * Example 1:\n * Input: \"()\"\n * Output: True\n * \n * Example 2:\n * Input: \"(*)\"\n * Output: True\n * \n * Example 3:\n * Input: \"(*))\"\n * Output: True\n * \n * Note:\n * The string size will be in the range [1, 100].\n */\n\npublic class ValidParenthesisString678 {\n    public boolean checkValidString(String s) {\n        return checkValidString(s.toCharArray(), 0, new int[]{0});\n    }\n\n    public boolean checkValidString(char[] chars, int i, int[] count) {\n        if (i == chars.length) return count[0] == 0;\n        char c = chars[i];\n        if (c == '(') {\n            count[0]++;\n            return checkValidString(chars, i + 1, count);\n        } else if (c == ')') {\n            if (count[0] == 0) return false;\n            count[0]--;\n            return checkValidString(chars, i + 1, count); \n        } else {\n            int pre = count[0];\n            if (checkValidString(chars, i + 1, count)) return true;\n            count[0] = pre + 1;\n            if (checkValidString(chars, i + 1, count)) return true;\n            count[0] = pre;\n            if (count[0] == 0) return false;\n            count[0]--;\n            return checkValidString(chars, i + 1, count);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/valid-parenthesis-string/solution/\n     */\n    public boolean checkValidString2(String s) {\n        int n = s.length();\n        if (n == 0) return true;\n        boolean[][] dp = new boolean[n][n];\n\n        for (int i = 0; i < n; i++) {\n            if (s.charAt(i) == '*') dp[i][i] = true;\n            if (i < n-1 &&\n                    (s.charAt(i) == '(' || s.charAt(i) == '*') &&\n                    (s.charAt(i+1) == ')' || s.charAt(i+1) == '*')) {\n                dp[i][i+1] = true;\n            }\n        }\n\n        for (int size = 2; size < n; size++) {\n            for (int i = 0; i + size < n; i++) {\n                if (s.charAt(i) == '*' && dp[i+1][i+size] == true) {\n                    dp[i][i+size] = true;\n                } else if (s.charAt(i) == '(' || s.charAt(i) == '*') {\n                    for (int k = i+1; k <= i+size; k++) {\n                        if ((s.charAt(k) == ')' || s.charAt(k) == '*') &&\n                                (k == i+1 || dp[i+1][k-1]) &&\n                                (k == i+size || dp[k+1][i+size])) {\n                            dp[i][i+size] = true;\n                        }\n                    }\n                }\n            }\n        }\n        return dp[0][n-1];\n    }\n\n\n    /**\n     * https://leetcode.com/problems/valid-parenthesis-string/solution/\n     */\n    public boolean checkValidString3(String s) {\n      int lo = 0, hi = 0;\n      for (char c: s.toCharArray()) {\n          lo += c == '(' ? 1 : -1;\n          hi += c != ')' ? 1 : -1;\n          if (hi < 0) break;\n          lo = Math.max(lo, 0);\n      }\n      return lo == 0;\n   }\n\n}\n"
  },
  {
    "path": "src/ValidSudoku36.java",
    "content": "/**\n * Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.\n * http://sudoku.com.au/TheRules.aspx\n *\n * The Sudoku board could be partially filled, where empty cells are filled\n * with the character '.'.\n *\n * http://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Sudoku-by-L2G-20050714.svg/250px-Sudoku-by-L2G-20050714.svg.png\n *\n * A partially filled sudoku which is valid.\n *\n * Note:\n * A valid Sudoku board (partially filled) is not necessarily solvable. Only\n * the filled cells need to be validated.\n *\n */\n\npublic class ValidSudoku36 {\n    public boolean isValidSudoku(char[][] board) {\n        boolean[][] rows = new boolean[9][9];\n        boolean[][] cols = new boolean[9][9];\n        boolean[][] cubs = new boolean[9][9];\n\n        for (int i=0; i<9; i++) {\n            for (int j=0; j<9; j++) {\n                if (board[i][j] == '.') continue;\n                int n = board[i][j] - '1';\n                if (rows[i][n] || cols[j][n] || cubs[cubeId(i,j)][n]) return false;\n                rows[i][n] = true;\n                cols[j][n] = true;\n                cubs[cubeId(i,j)][n] = true;\n            }\n        }\n\n        return true;\n    }\n\n    private int cubeId(int i, int j) {\n        return (i/3)*3 + (j/3);\n    }\n\n    /**\n     * https://leetcode.com/problems/valid-sudoku/discuss/15472/Short+Simple-Java-using-Strings\n     */\n    public boolean isValidSudoku2(char[][] board) {\n        Set seen = new HashSet();\n        for (int i=0; i<9; ++i) {\n            for (int j=0; j<9; ++j) {\n                if (board[i][j] != '.') {\n                    String b = \"(\" + board[i][j] + \")\";\n                    if (!seen.add(b + i) || !seen.add(j + b) || !seen.add(i/3 + b + j/3))\n                        return false;\n                }\n            }\n        }\n        return true;\n    }\n\n    /**\n     * https://leetcode.com/problems/valid-sudoku/discuss/15560/Yet-another-java-2ms-solution\n     */\n    public boolean isValidSudoku3s(char[][] board) {\n        int [] vset = new int [9];\n        int [] hset = new int [9];\n        int [] bckt = new int [9];\n        int idx = 0;\n        for (int i = 0; i < 9; i++) {\n            for (int j = 0; j < 9; j++) {\n                if (board[i][j] != '.') {\n                    idx = 1 << (board[i][j] - '0') ;\n                    if ((hset[i] & idx) > 0 ||\n                        (vset[j] & idx) > 0 ||\n                        (bckt[(i / 3) * 3 + j / 3] & idx) > 0) return false;\n                    hset[i] |= idx;\n                    vset[j] |= idx;\n                    bckt[(i / 3) * 3 + j / 3] |= idx;\n                }\n            }\n        }\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "src/ValidTriangleNumber611.java",
    "content": "/**\n * Given an array consists of non-negative integers, your task is to count the\n * number of triplets chosen from the array that can make triangles if we take\n * them as side lengths of a triangle.\n * \n * Example 1:\n * Input: [2,2,3,4]\n * Output: 3\n * Explanation:\n * Valid combinations are: \n * 2,3,4 (using the first 2)\n * 2,3,4 (using the second 2)\n * 2,2,3\n * \n * Note:\n * The length of the given array won't exceed 1000.\n * The integers in the given array are in the range of [0, 1000].\n */\n\n\npublic class ValidTriangleNumber611 {\n    public int triangleNumber(int[] nums) {\n        if (nums == null || nums.length < 3) return 0;\n        Arrays.sort(nums);\n        int res = 0;\n        for (int i=0; i<nums.length-2; i++) {\n            for (int j=i+1; j<nums.length-1; j++) {\n                for (int k=j+1; k<nums.length; k++) {\n                    if (isValidTriangle(nums[i], nums[j], nums[k])) res++;\n                    else break;\n                }\n            }\n        }\n        \n        return res;\n    }\n\n    public boolean isValidTriangle(int a, int b, int c) {\n        if (a == 0 || b == 0 || c == 0) return false;\n        int longestSide = a;\n        if (b > longestSide) longestSide = b;\n        if (c > longestSide) longestSide = c;\n        return longestSide < (a + b + c - longestSide);\n    }\n  \n  \n    public int triangleNumber2(int[] nums) {\n        if (nums == null || nums.length < 3) return 0;\n        \n        Arrays.sort(nums);\n        int[] sum = new int[1001];\n        for(int n: nums) sum[n]++;\n        for(int i=1; i<1001; i++) sum[i] += sum[i-1];\n\n        int res = 0;\n        for (int i=0; i<nums.length-2; i++) {\n            if (nums[i] == 0) continue;\n            for (int j=i+1; j<nums.length-1; j++) {\n                if (nums[j] == 0) continue;\n                int upper = nums[i] + nums[j];\n                int lower = Math.abs(nums[i] - nums[j]);\n                int c = sum[upper-1] - Math.max(sum[lower], j+1);\n                res += c;\n            }\n        }\n        return res;\n    }\n\n    /**\n     * https://leetcode.com/problems/valid-triangle-number/solution/\n     */\n    public int triangleNumber3(int[] nums) {\n        int count = 0;\n        Arrays.sort(nums);\n        for (int i = 0; i < nums.length - 2; i++) {\n            int k = i + 2;\n            for (int j = i + 1; j < nums.length - 1 && nums[i] != 0; j++) {\n                while (k < nums.length && nums[i] + nums[j] > nums[k])\n                    k++;\n                count += k - j - 1;\n            }\n        }\n        return count;\n    }\n\n    /**\n     * https://leetcode.com/problems/valid-triangle-number/discuss/104174/Java-O(n2)-Time-O(1)-Space\n     */\n    public static int triangleNumber4(int[] A) {\n        Arrays.sort(A);\n        int count = 0, n = A.length;\n        for (int i=n-1;i>=2;i--) {\n            int l = 0, r = i-1;\n            while (l < r) {\n                if (A[l] + A[r] > A[i]) {\n                    count += r-l;\n                    r--;\n                }\n                else l++;\n            }\n        }\n        return count;\n    }\n  \n}\n\n\n\n"
  },
  {
    "path": "src/ValidWordAbbreviation408.java",
    "content": "/**\n * Given a non-empty string s and an abbreviation abbr, return whether the\n * string matches with the given abbreviation.\n * \n * A string such as \"word\" contains only the following valid abbreviations:\n * \n * [\"word\", \"1ord\", \"w1rd\", \"wo1d\", \"wor1\", \"2rd\", \"w2d\", \"wo2\", \"1o1d\",\n * \"1or1\", \"w1r1\", \"1o2\", \"2r1\", \"3d\", \"w3\", \"4\"]\n * \n * Notice that only the above abbreviations are valid abbreviations of the\n * string \"word\". Any other string is not a valid abbreviation of \"word\".\n * \n * Note:\n * Assume s contains only lowercase letters and abbr contains only lowercase\n * letters and digits.\n * \n * Example 1:\n * Given s = \"internationalization\", abbr = \"i12iz4n\":\n * Return true.\n * \n * Example 2:\n * Given s = \"apple\", abbr = \"a2e\":\n * Return false.\n */\n\npublic class ValidWordAbbreviation408 {\n    public boolean validWordAbbreviation(String word, String abbr) {\n        if (abbr.length() == 0) return word.length() == 0;\n        char[] wordChars = word.toCharArray();\n        char[] abbrChars = abbr.toCharArray();\n        int wLen = word.length();\n        int aLen = abbr.length();\n        int i = 0;\n        int j = 0;\n        while (i < wLen && j < aLen) {\n            if (isDigit(abbrChars[j])) {\n                if (abbrChars[j] == '0') return false;\n                int preJ = j;\n                while (j < aLen && isDigit(abbrChars[j])) {\n                    j++;\n                }\n                int num = Integer.valueOf(abbr.substring(preJ, j));\n                i += num;\n                if (i > wLen) return false;\n            } else {\n                if (wordChars[i] != abbrChars[j]) return false;\n                i++;\n                j++;\n            }\n        }\n        return i == wLen && j == aLen;\n    }\n\n    private boolean isDigit(char ch) {\n        return ch >= '0' && ch <= '9';\n    }\n}\n"
  },
  {
    "path": "src/ValidateBinarySearchTree98.java",
    "content": "/**\n * Given a binary tree, determine if it is a valid binary search tree (BST).\n *\n * Assume a BST is defined as follows:\n *\n * The left subtree of a node contains only nodes with keys less than the node's key.\n * The right subtree of a node contains only nodes with keys greater than the node's key.\n * Both the left and right subtrees must also be binary search trees.\n *\n * Example 1:\n *     2\n *    / \\\n *   1   3\n * Binary tree [2,1,3], return true.\n *\n * Example 2:\n *     1\n *    / \\\n *   2   3\n * Binary tree [1,2,3], return false.\n */\n\n/**\n * Definition for a binary tree node.\n * public class TreeNode {\n *     int val;\n *     TreeNode left;\n *     TreeNode right;\n *     TreeNode(int x) { val = x; }\n * }\n */\n\npublic class ValidateBinarySearchTree98 {\n    public boolean isValidBST(TreeNode root) {\n        return helper(root, Long.MIN_VALUE, Long.MAX_VALUE);\n    }\n\n    private boolean helper(TreeNode root, long min, long max) {\n        if (root == null) return true;\n        if (root.val <= min || root.val >= max) return false;\n        return helper(root.left, min, root.val) && helper(root.right, root.val, max);\n    }\n\n\n    public boolean isValidBST2(TreeNode root) {\n        if (root == null) return true;\n        return isValidBST(root, new int[]{0, 0});\n    }\n\n    private boolean isValidBST(TreeNode root, int[] bounds) {\n        bounds[0] = root.val;\n        bounds[1] = root.val;\n        if (root.left == null && root.right == null) {\n            return true;\n        }\n\n        if (root.left != null) {\n            int[] leftBounds = new int[]{0, 0};\n            boolean left = isValidBST(root.left, leftBounds);\n            if (!left || leftBounds[1] >= root.val) return false;\n            bounds[0] = leftBounds[0];\n        }\n\n        if (root.right != null) {\n            int[] rightBounds = new int[]{0, 0};\n            boolean right = isValidBST(root.right, rightBounds);\n            if (!right || rightBounds[0] <= root.val) return false;\n            bounds[1] = rightBounds[1];\n        }\n\n        return true;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/46016/learn-one-iterative-inorder-traversal-apply-it-to-multiple-tree-questions-java-solution\n     */\n    public boolean isValidBST3(TreeNode root) {\n        if (root == null) return true;\n        Stack<TreeNode> stack = new Stack<>();\n        TreeNode pre = null;\n        while (root != null || !stack.isEmpty()) {\n            while (root != null) {\n                stack.push(root);\n                root = root.left;\n            }\n            root = stack.pop();\n            if(pre != null && root.val <= pre.val) return false;\n            pre = root;\n            root = root.right;\n        }\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "src/ValidateStackSequences946.java",
    "content": "/**\n * Given two sequences pushed and popped with distinct values, return true if and\n * only if this could have been the result of a sequence of push and pop operations on an initially empty stack.\n * \n * Example 1:\n * Input: pushed = [1,2,3,4,5], popped = [4,5,3,2,1]\n * Output: true\n * Explanation: We might do the following sequence:\n * push(1), push(2), push(3), push(4), pop() -> 4,\n * push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1\n * \n * Example 2:\n * Input: pushed = [1,2,3,4,5], popped = [4,3,5,1,2]\n * Output: false\n * Explanation: 1 cannot be popped before 2.\n * \n * Note:\n * 0 <= pushed.length == popped.length <= 1000\n * 0 <= pushed[i], popped[i] < 1000\n * pushed is a permutation of popped.\n * pushed and popped have distinct values.\n */\npublic class ValidateStackSequences946 {\n    public boolean validateStackSequences(int[] pushed, int[] popped) {\n        int i = 0;\n        int j = 0;\n        int len = pushed.length;\n        Stack<Integer> st = new Stack<>();\n        while (i < len && j < len) {\n            while (!st.isEmpty() && j < len &&  popped[j] == st.peek()) {\n                j++;\n                st.pop();\n            }\n            if (j >= len) break;\n            while (i < len && pushed[i] != popped[j]) {\n                st.push(pushed[i]);\n                i++;\n            }\n            if (i < len && pushed[i] == popped[j]) {\n                st.push(pushed[i]);\n                i++;\n            }\n        }\n        while (!st.isEmpty() && j < len && popped[j] == st.peek()) {\n            j++;\n            st.pop();\n        }\n        return i == len && j == len && st.isEmpty();\n    }\n}\n"
  },
  {
    "path": "src/VerifyPreorderSequenceInBinarySearchTree255.java",
    "content": "/**\n * Given an array of numbers, verify whether it is the correct preorder\n * traversal sequence of a binary search tree.\n * \n * You may assume each number in the sequence is unique.\n * \n * Consider the following binary search tree: \n * \n *      5\n *     / \\\n *    2   6\n *   / \\\n *  1   3\n * \n * Example 1:\n * Input: [5,2,6,1,3]\n * Output: false\n * \n * Example 2:\n * Input: [5,2,1,3,6]\n * Output: true\n * \n * Follow up:\n * Could you do it using only constant space complexity?\n */\n\npublic class VerifyPreorderSequenceInBinarySearchTree255 {\n    public boolean verifyPreorder(int[] preorder) {\n        if (preorder == null || preorder.length <= 1) return true;\n        Stack<Integer> stack = new Stack<>();\n        int lower = Integer.MIN_VALUE;\n        for (int n: preorder) {\n            if (n < lower) return false;\n            while (!stack.isEmpty() && stack.peek() < n) {\n                int top = stack.pop();\n                if (top > lower) lower = top;\n            }\n            stack.push(n);\n        }\n        return true;\n    }\n\n\n    public boolean verifyPreorder2(int[] preorder) {\n        if (preorder == null || preorder.length <= 1) return true;\n        return helper(preorder, 0, preorder.length-1, Integer.MIN_VALUE);\n    }\n\n    private boolean helper(int[] preorder, int i, int j, int lower) {\n        if (i > j) return true;\n        if (i == j) return preorder[i] > lower;\n        \n        int root = preorder[i];\n        if (root < lower) return false;\n        int mid = i + 1;\n        while (mid <= j && preorder[mid] < root) {\n            mid++;\n        }\n        return helper(preorder, i+1, mid-1, lower) && helper(preorder, mid, j, root);\n    }\n\n\n\n    public boolean verifyPreorder3(int[] preorder) {\n        if (preorder == null || preorder.length <= 1) return true;\n        int i = -1;\n        int lower = Integer.MIN_VALUE;\n        for (int n: preorder) {\n            if (n < lower) return false;\n            while (i != -1 && preorder[i] < n) {\n                int top = preorder[i--];\n                if (top > lower) lower = top;\n            }\n            preorder[++i] = n;\n        }\n        return true;\n    }\n\n\n\n\n\n\n\n\n}\n"
  },
  {
    "path": "src/WallsAndGates286.java",
    "content": "/**\n * You are given a m x n 2D grid initialized with these three possible values.\n * \n * -1 - A wall or an obstacle.\n * 0 - A gate.\n * INF - Infinity means an empty room. We use the value 231 - 1 = 2147483647 to\n * represent INF as you may assume that the distance to a gate is less\n * than 2147483647.\n * \n * Fill each empty room with the distance to its nearest gate. If it is\n * impossible to reach a gate, it should be filled with INF.\n * \n * Example: \n * \n * Given the 2D grid:\n * \n * INF  -1  0  INF\n * INF INF INF  -1\n * INF  -1 INF  -1\n *   0  -1 INF INF\n * \n * After running your function, the 2D grid should be:\n * \n *   3  -1   0   1\n *   2   2   1  -1\n *   1  -1   2  -1\n *   0  -1   3   4\n *\n */\n\n\npublic class WallsAndGates286 {\n\n    private int[][] directions = new int[][]{{-1, 0}, {0, 1}, {1, 0}, {0, -1}};\n\n    public void wallsAndGates(int[][] rooms) {\n        if (rooms == null || rooms.length == 0 || rooms[0].length == 0) return;\n\n        int n = rooms.length;\n        int m = rooms[0].length;\n        for (int i=0; i<n; i++) {\n            for (int j=0; j<m; j++) {\n                if (rooms[i][j] == 0) {\n                    for (int[] dir: directions) {\n                        dfs(rooms, 1, i + dir[0], j + dir[1]);\n                    }\n                }\n            }\n        }\n    }\n\n    private void dfs(int[][] rooms, int distance, int i, int j) {\n        if (i < 0 || i >= rooms.length || j < 0 || j >= rooms[0].length) return;\n        if (rooms[i][j] == -1 || rooms[i][j] == 0) return;\n\n        // can be optimized: early stop\n        // rooms[i][j] = Math.min(rooms[i][j], distance);\n        if (rooms[i][j] > distance) {\n            rooms[i][j] = distance;\n        } else if (rooms[i][j] <= distance) {\n            return;\n        }\n\n        for (int[] dir: directions) {\n            dfs(rooms, distance + 1, i + dir[0], j + dir[1]);\n        }\n    }\n\n    /**\n     * leetcode solution\n     */\n    public void wallsAndGates2(int[][] rooms) {\n        if(rooms.length == 0 || rooms[0].length == 0) return;\n        for(int i = 0; i < rooms.length; i++) {\n            for(int j = 0; j < rooms[0].length; j++) {\n                if(rooms[i][j] == 0) {\n                    dfs2(rooms, i, j, 0);\n                }\n            }\n        }\n    }\n    \n    private void dfs2(int[][] rooms, int i, int j, int dis) {\n        if(i < 0 || i >= rooms.length || j < 0 || j >= rooms[0].length || dis > rooms[i][j] || rooms[i][j] == -1) return;\n        rooms[i][j] = dis;\n        \n        dfs2(rooms, i + 1, j, dis+1);\n        dfs2(rooms, i - 1, j, dis+1);\n        dfs2(rooms, i, j - 1, dis+1);\n        dfs2(rooms, i, j + 1, dis+1);\n    }\n\n    /**\n     * https://leetcode.com/problems/walls-and-gates/solution/\n     */\n    private static final int EMPTY = Integer.MAX_VALUE;\n    private static final int GATE = 0;\n    private static final List<int[]> DIRECTIONS = Arrays.asList(\n            new int[] { 1,  0},\n            new int[] {-1,  0},\n            new int[] { 0,  1},\n            new int[] { 0, -1}\n    );\n    \n    public void wallsAndGates4(int[][] rooms) {\n        int m = rooms.length;\n        if (m == 0) return;\n        int n = rooms[0].length;\n        Queue<int[]> q = new LinkedList<>();\n        for (int row = 0; row < m; row++) {\n            for (int col = 0; col < n; col++) {\n                if (rooms[row][col] == GATE) {\n                    q.add(new int[] { row, col });\n                }\n            }\n        }\n        while (!q.isEmpty()) {\n            int[] point = q.poll();\n            int row = point[0];\n            int col = point[1];\n            for (int[] direction : DIRECTIONS) {\n                int r = row + direction[0];\n                int c = col + direction[1];\n                if (r < 0 || c < 0 || r >= m || c >= n || rooms[r][c] != EMPTY) {\n                    continue;\n                }\n                rooms[r][c] = rooms[row][col] + 1;\n                q.add(new int[] { r, c });\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/WaterAndJugProblem365.java",
    "content": "/**\n * You are given two jugs with capacities x and y litres. There is an infinite amount of water supply available.\n * You need to determine whether it is possible to measure exactly z litres using these two jugs.\n *\n * If z liters of water is measurable, you must have z liters of water contained within one or both buckets by the end.\n *\n * Operations allowed:\n *\n * Fill any of the jugs completely with water.\n * Empty any of the jugs.\n * Pour water from one jug into another till the other jug is completely full or the first jug itself is empty.\n *\n * Example 1: (From the famous \"Die Hard\" example)\n * Input: x = 3, y = 5, z = 4\n * Output: True\n *\n * Example 2:\n * Input: x = 2, y = 6, z = 5\n * Output: False\n */\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n\npublic class WaterAndJugProblem365 {\n\n    public boolean canMeasureWater(int x, int y, int z) {\n        if (x < 0 || y < 0 || z < 0) {\n            return false;\n        }\n\n        if (x == z || y == z || z == 0 || ((x + y) == z)) {\n            return true;\n        }\n\n        if (x == y) {\n            return false;\n        }\n\n        return canGetZ(Math.min(x, y), Math.max(x, y), z);\n\n    }\n\n    private boolean canGetZ(int x, int y, int z) {\n        Integer a = x;\n        Integer b = 0;\n        do {\n            Integer tempB = a + b;\n            if (tempB == z) {\n                return true;\n            }\n\n            if (b == y) {\n                b = 0;\n                continue;\n            }\n\n            if (a == 0) {\n                a = x;\n                continue;\n            }\n\n            if (tempB > y) {\n                a = tempB - y;\n                b = y;\n            } else {\n                a = 0;\n                b = tempB;\n            }\n        } while (!(a == x && b == 0));\n        return false;\n    }\n\n\n    /** -------------------------------------------------------------------\n     * Top Solution:\n     * https://discuss.leetcode.com/topic/49238/math-solution-java-solution\n     * https://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity\n     * --------------------------------------------------------------------\n     */\n\n\n    public boolean canMeasureWaterMath(int x, int y, int z) {\n        //limit brought by the statement that water is finallly in one or both buckets\n        if(x + y < z) return false;\n        //case x or y is zero\n        if( x == z || y == z || x + y == z ) return true;\n\n        //get GCD, then we can use the property of Bézout's identity\n        return z%GCD(x, y) == 0;\n    }\n\n    public int GCD(int a, int b){\n        while(b != 0 ){\n            int temp = b;\n            b = a%b;\n            a = temp;\n        }\n        return a;\n    }\n\n\n\n\n    public static void main(String[] args) {\n        WaterAndJugProblem365 wjp = new WaterAndJugProblem365();\n        System.out.println(wjp.canMeasureWaterMath(3, 5, 4));\n        System.out.println(wjp.canMeasureWaterMath(4, 6, 8));\n        System.out.println(wjp.canMeasureWaterMath(1, 2, 3));\n        System.out.println(wjp.canMeasureWaterMath(2, 6, 5));\n    }\n\n}\n"
  },
  {
    "path": "src/WiggleSort280.java",
    "content": "/**\n * Given an unsorted array nums, reorder it in-place such that\n * nums[0] <= nums[1] >= nums[2] <= nums[3]....\n * \n * Example:\n * \n * Input: nums = [3,5,2,1,6,4]\n * Output: One possible answer is [3,5,1,6,2,4]\n */\n\npublic class WiggleSort280 {\n    public void wiggleSort(int[] nums) {\n        if (nums == null || nums.length <= 1) return;\n        int len = nums.length;\n        int i = 0;\n        while (i < len - 1) {\n            if ((i % 2 == 0 && nums[i] > nums[i+1]) || (i % 2 == 1 && nums[i] < nums[i+1])) swap(nums, i, i+1);\n            i++;\n        }\n    }\n    \n\n    public void wiggleSort2(int[] nums) {\n        if (nums == null || nums.length <= 1) return;\n        Arrays.sort(nums);\n        int len = nums.length;\n        int mid = len / 2;\n        if (mid % 2 == 1) mid++;\n        int left = 1;\n        int right = mid;\n        while (right < len) {\n            swap(nums, left, right);\n            left += 2;\n            right += 2;\n        }\n    }\n\n    private void swap(int[] nums, int i, int j) {\n        int temp = nums[i];\n        nums[i] = nums[j];\n        nums[j] = temp;\n    }\n\n}\n"
  },
  {
    "path": "src/WiggleSortII324.java",
    "content": "/**\n * Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]....\n *\n * Example:\n * (1) Given nums = [1, 5, 1, 1, 6, 4], one possible answer is [1, 4, 1, 5, 1, 6].\n * (2) Given nums = [1, 3, 2, 2, 3, 1], one possible answer is [2, 3, 1, 3, 1, 2].\n *\n * Note:\n * You may assume all input has valid answer.\n *\n * Follow Up:\n * Can you do it in O(n) time and/or in-place with O(1) extra space?\n */\n\n\npublic class WiggleSortII324 {\n    /**\n     * https://www.hrwhisper.me/leetcode-wiggle-sort-ii/\n     */\n    public void wiggleSort(int[] nums) {\n        Arrays.sort(nums);\n        int[] temp = new int[nums.length];\n        int s = (nums.length + 1) >> 1, t = nums.length;\n        for (int i = 0; i < nums.length; i++) {\n            temp[i] = (i & 1) == 0 ?  nums[--s] : nums[--t] ;\n        }\n\n        for (int i = 0; i < nums.length; i++)\n            nums[i] = temp[i];\n    }\n\n\n    /**\n     * https://www.hrwhisper.me/leetcode-wiggle-sort-ii/\n     */\n    public void wiggleSort2(int[] nums) {\n        int medium = findMedium(nums, 0, nums.length - 1, (nums.length + 1) >> 1);\n        int s = 0, t = nums.length - 1 , mid_index = (nums.length + 1) >> 1;\n        int[] temp = new int[nums.length];\n        for (int i = 0; i < nums.length; i++) {\n            if (nums[i] < medium)\n                temp[s++] = nums[i];\n            else if (nums[i] > medium)\n                temp[t--] = nums[i];\n        }\n\n        while (s < mid_index) temp[s++] = medium;\n        while (t >= mid_index) temp[t--] = medium;\n\n        t = nums.length;\n        for (int i = 0; i < nums.length; i++)\n            nums[i] = (i & 1) == 0 ? temp[--s] : temp[--t];\n    }\n\n    private int findMedium(int[] nums, int L, int R, int k) {\n        if (L >= R) return nums[R];\n        int i = partition(nums, L, R);\n        int cnt = i - L + 1;\n        if (cnt == k) return nums[i];\n        return cnt > k ? findMedium(nums, L, i - 1, k) : findMedium(nums, i + 1, R, k - cnt);\n    }\n\n    private int partition(int[] nums, int L, int R) {\n        int val = nums[L];\n        int i = L, j = R + 1;\n        while (true) {\n            while (++i < R && nums[i] < val) ;\n            while (--j > L && nums[j] > val) ;\n            if (i >= j) break;\n            swap(nums, i, j);\n        }\n        swap(nums, L, j);\n        return j;\n    }\n\n    private void swap(int[] nums, int i, int j) {\n        int temp = nums[i];\n        nums[i] = nums[j];\n        nums[j] = temp;\n    }\n\n\n\n\n\n\n}\n"
  },
  {
    "path": "src/WiggleSubsequence376.java",
    "content": "/**\n * A sequence of numbers is called a wiggle sequence if the differences between\n * successive numbers strictly alternate between positive and negative. The\n * first difference (if one exists) may be either positive or negative. A\n * sequence with fewer than two elements is trivially a wiggle sequence.\n * \n * For example, [1,7,4,9,2,5] is a wiggle sequence because the differences\n * (6,-3,5,-7,3) are alternately positive and negative. In contrast,\n * [1,4,7,2,5] and [1,7,4,5,5] are not wiggle sequences, the first because its\n * first two differences are positive and the second because its last\n * difference is zero.\n * \n * Given a sequence of integers, return the length of the longest subsequence\n * that is a wiggle sequence. A subsequence is obtained by deleting some number\n * of elements (eventually, also zero) from the original sequence, leaving the\n * remaining elements in their original order.\n * \n * Examples:\n * Input: [1,7,4,9,2,5]\n * Output: 6\n * The entire sequence is a wiggle sequence.\n * \n * Input: [1,17,5,10,13,15,10,5,16,8]\n * Output: 7\n * There are several subsequences that achieve this length.\n * One is [1,17,10,13,10,16,8].\n * \n * Input: [1,2,3,4,5,6,7,8,9]\n * Output: 2\n * \n * Follow up:\n * Can you do it in O(n) time?\n */\n\npublic class WiggleSubsequence376 {\n    public int wiggleMaxLength(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        int N = nums.length;\n        int[] up = new int[N];\n        int[] down = new int[N];\n        up[0] = 1;\n        down[0] = 1;\n        for (int i=1; i<N; i++) {\n            up[i] = 1;\n            down[i] = 1;\n            for (int j=0; j<i; j++) {\n                if (nums[i] > nums[j]) {\n                    up[i] = Math.max(up[i], down[j] + 1);\n                } else if (nums[i] < nums[j]) {\n                    down[i] = Math.max(down[i], up[j] + 1);\n                }\n            }\n        }\n        return Math.max(up[N-1], down[N-1]);\n    }\n\n\n    public int wiggleMaxLength2(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        int N = nums.length;\n        int[] up = new int[N];\n        int[] down = new int[N];\n        for (int i=1; i<N; i++) {\n            for (int j=0; j<i; j++) {\n                if (nums[i] > nums[j]) {\n                    up[i] = Math.max(up[i], down[j] + 1);\n                } else if (nums[i] < nums[j]) {\n                    down[i] = Math.max(down[i], up[j] + 1);\n                }\n            }\n        }\n        return Math.max(up[N-1], down[N-1]) + 1;\n    }\n\n\n    public int wiggleMaxLength3(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        int N = nums.length;\n        int[] up = new int[N];\n        int[] down = new int[N];\n        up[0] = 1;\n        down[0] = 1;\n        for (int i=1; i<N; i++) {\n            if (nums[i] == nums[i-1]) {\n                up[i] = up[i-1];\n                down[i] = down[i-1];\n            } else if (nums[i] > nums[i-1]) {\n                up[i] = down[i-1] + 1;\n                down[i] = down[i-1];\n            } else {\n                up[i] = up[i-1];\n                down[i] = up[i-1] + 1;\n            }\n        }\n        return Math.max(up[N-1], down[N-1]);\n    }\n\n\n    public int wiggleMaxLength4(int[] nums) {\n        if (nums == null || nums.length == 0) return 0;\n        int N = nums.length;\n        int up = 1;\n        int down = 1;\n        for (int i=1; i<N; i++) {\n            if (nums[i] > nums[i-1]) {\n                up = down + 1;\n            } else if (nums[i] < nums[i-1]){\n                down = up + 1;\n            }\n        }\n        return Math.max(up, down);\n    }\n\n\n    /**\n     * https://leetcode.com/problems/wiggle-subsequence/solution/\n     */\n    public int wiggleMaxLength5(int[] nums) {\n        if (nums.length < 2)\n            return nums.length;\n        int prevdiff = nums[1] - nums[0];\n        int count = prevdiff != 0 ? 2 : 1;\n        for (int i = 2; i < nums.length; i++) {\n            int diff = nums[i] - nums[i - 1];\n            if ((diff > 0 && prevdiff <= 0) || (diff < 0 && prevdiff >= 0)) {\n                count++;\n                prevdiff = diff;\n            }\n        }\n        return count;\n    }\n\n}\n"
  },
  {
    "path": "src/WildcardMatching44.java",
    "content": "/**\n * Implement wildcard pattern matching with support for '?' and '*'.\n *\n * '?' Matches any single character.\n * '*' Matches any sequence of characters (including the empty sequence).\n *\n * The matching should cover the entire input string (not partial).\n *\n * The function prototype should be:\n * bool isMatch(const char *s, const char *p)\n *\n * Some examples:\n * isMatch(\"aa\",\"a\") → false\n * isMatch(\"aa\",\"aa\") → true\n * isMatch(\"aaa\",\"aa\") → false\n * isMatch(\"aa\", \"*\") → true\n * isMatch(\"aa\", \"a*\") → true\n * isMatch(\"ab\", \"?*\") → true\n * isMatch(\"aab\", \"c*a*b\") → false\n *\n */\n\npublic class WildcardMatching44 {\n    // time limit exceeded\n    public boolean isMatch(String s, String p) {\n        if (s == null || p == null) return false;\n        return isMatch(s, 0, p, 0);\n    }\n\n    private boolean isMatch(String s, int i, String p, int j) {\n        if (i >= s.length()) return restAreStars(p, j);\n        if (j >= p.length()) return false;\n\n        switch (p.charAt(j)) {\n            case '?':\n                return isMatch(s, i+1, p, j+1);\n            case '*':\n                while (j+1 < p.length() && p.charAt(j+1) == '*') j++;\n                return isMatch(s, i, p, j+1) || isMatch(s, i+1, p, j+1) || isMatch(s, i+1, p, j);\n            default:\n                return s.charAt(i) == p.charAt(j) && isMatch(s, i+1, p, j+1);\n        }\n    }\n\n    private boolean restAreStars(String p, int j) {\n        while (j < p.length()) {\n            if (p.charAt(j) != '*') return false;\n            j++;\n        }\n        return true;\n    }\n\n\n    // DP, 2D space\n    public boolean isMatch2(String s, String p) {\n        if (s == null || p == null) return false;\n\n        boolean[][] dp = new boolean[p.length()+1][s.length()+1];\n        dp[0][0] = true;\n        for (int j=1; j<=s.length(); j++) dp[0][j] = false;\n        for (int i=1; i<=p.length(); i++) dp[i][0] = p.charAt(i-1) == '*' ? dp[i-1][0] : false;\n\n        for (int i=1; i<=p.length(); i++) {\n            char c = p.charAt(i-1);\n            for (int j=1; j<=s.length(); j++) {\n                switch (c) {\n                    case '?':\n                        dp[i][j] = dp[i-1][j-1];\n                        break;\n                    case '*':\n                        dp[i][j] = dp[i-1][j] || dp[i-1][j-1] || dp[i][j-1];\n                        break;\n                    default:\n                        dp[i][j] = c == s.charAt(j-1) && dp[i-1][j-1];\n                }\n            }\n        }\n\n        return dp[p.length()][s.length()];\n    }\n\n\n    // DP, 1D space\n    public boolean isMatch3(String s, String p) {\n        if (s == null || p == null) return false;\n\n        boolean[] dp = new boolean[s.length()+1];\n        dp[0] = true;\n        for (int j=1; j<=s.length(); j++) dp[j] = false;\n\n        for (int i=1; i<=p.length(); i++) {\n            boolean old = dp[0];\n            boolean pre = dp[0];\n            dp[0] = p.charAt(i-1) == '*' ? dp[0] : false;\n            char c = p.charAt(i-1);\n            for (int j=1; j<=s.length(); j++) {\n                old = dp[j];\n                switch (c) {\n                    case '?':\n                        dp[j] = pre;\n                        break;\n                    case '*':\n                        dp[j] = old || pre || dp[j-1];\n                        break;\n                    default:\n                        dp[j] = c == s.charAt(j-1) && pre;\n                }\n                pre = old;\n            }\n        }\n\n        return dp[s.length()];\n    }\n\n\n    /**\n     * https://leetcode.com/problems/wildcard-matching/discuss/17810/Linear-runtime-and-constant-space-solution\n     */\n    boolean isMatch4(String str, String pattern) {\n        int s = 0, p = 0, match = 0, starIdx = -1;\n        while (s < str.length()){\n            // advancing both pointers\n            if (p < pattern.length()  && (pattern.charAt(p) == '?' || str.charAt(s) == pattern.charAt(p))){\n                s++;\n                p++;\n            }\n            // * found, only advancing pattern pointer\n            else if (p < pattern.length() && pattern.charAt(p) == '*'){\n                starIdx = p;\n                match = s;\n                p++;\n            }\n            // last pattern pointer was *, advancing string pointer\n            else if (starIdx != -1){\n                p = starIdx + 1;\n                match++;\n                s = match;\n            }\n            //current pattern pointer is not star, last patter pointer was not *\n            //characters do not match\n            else return false;\n        }\n\n        //check for remaining characters in pattern\n        while (p < pattern.length() && pattern.charAt(p) == '*') p++;\n\n        return p == pattern.length();\n    }\n\n\n    public boolean isMatch5(String s, String p) {\n        if (p.length() == 0) return s.length() == 0;\n        Map<Integer, Boolean> memo = new HashMap<>();\n        return isMatch(s.toCharArray(), 0, p.toCharArray(), 0, memo);\n    }\n\n    public boolean isMatch(char[] s, int i, char[] p, int j, Map<Integer, Boolean> memo) {\n        int idx = i * p.length + j;\n        if (memo.containsKey(idx)) return memo.get(idx);\n        if (j == p.length) return i == s.length;\n\n        boolean res = false;\n        char pChar = p[j];\n        if (i == s.length) {\n            res = pChar == '*' && isMatch(s, i, p, j+1, memo);\n        } else {\n            char sChar = s[i];\n            if (pChar == '?') {\n                res = isMatch(s, i+1, p, j+1, memo);\n            } else if (pChar == '*') {\n                res = isMatch(s, i+1, p, j+1, memo) ||\n                        isMatch(s, i, p, j+1, memo) ||\n                        isMatch(s, i+1, p, j, memo);\n            } else {\n                res = pChar == sChar && isMatch(s, i+1, p, j+1, memo);\n            }\n        }\n        memo.put(idx, res);\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/WordAbbreviation527.java",
    "content": "/**\n * Given an array of n distinct non-empty strings, you need to generate minimal\n * possible abbreviations for every word following rules below.\n * \n * Begin with the first character and then the number of characters abbreviated,\n * which followed by the last character.\n * \n * If there are any conflict, that is more than one words share the same\n * abbreviation, a longer prefix is used instead of only the first character\n * until making the map from word to abbreviation become unique. In other\n * words, a final abbreviation cannot map to more than one original words.\n * If the abbreviation doesn't make the word shorter, then keep it as original.\n * \n * Example:\n * Input: [\"like\", \"god\", \"internal\", \"me\", \"internet\", \"interval\", \"intension\", \"face\", \"intrusion\"]\n * Output: [\"l2e\",\"god\",\"internal\",\"me\",\"i6t\",\"interval\",\"inte4n\",\"f2e\",\"intr4n\"]\n * \n * Note:\n * Both n and the length of each word will not exceed 400.\n * The length of each word is greater than 1.\n * The words consist of lowercase English letters only.\n * The return answers should be in the same order as the original array.\n */\n\npublic class WordAbbreviation527 {\n    public List<String> wordsAbbreviation(List<String> dict) {\n        int N = dict.size();\n        Abbr[] abbrs = new Abbr[N];\n\n        for (int i=0; i<N; i++) {\n            String word = dict.get(i);\n            abbrs[i] = new Abbr(word, encode(word, 0), 0);\n        }\n\n        for (int i=0; i<N; i++) {\n            while (true) {\n                Set<Abbr> duplicates = new HashSet<>();\n                for (int j=i+1; j<N; j++) {\n                    if (abbrs[j].abbr.equals(abbrs[i].abbr)) {\n                        duplicates.add(abbrs[j]);\n                    }\n                }\n                if (duplicates.isEmpty()) break;\n                duplicates.add(abbrs[i]);\n                for (Abbr abbr: duplicates) {\n                    abbr.offset++;\n                    abbr.abbr = encode(abbr.word, abbr.offset);\n                }\n            }\n        }\n\n        List<String> res = new ArrayList<>();\n        for (Abbr abbr: abbrs) {\n            res.add(abbr.abbr);\n        }\n        return res;\n    }\n\n    private String encode(String word, int offset) {\n        if (offset + 2 >= word.length()) return word;\n        String encoded = word.substring(0, offset+1) + Integer.toString(word.length()-offset-2) + word.charAt(word.length()-1);\n        return encoded.length() >= word.length() ? word : encoded;\n    }\n\n    class Abbr {\n        String word;\n        String abbr;\n        int offset;\n        Abbr(String word, String abbr, int offset) {\n            this.word = word;\n            this.abbr = abbr;\n            this.offset = offset;\n        } \n    }\n\n\n    /**\n     * https://leetcode.com/problems/word-abbreviation/solution/s\n     */\n    public List<String> wordsAbbreviation2(List<String> words) {\n        Map<String, List<IndexedWord>> groups = new HashMap();\n        String[] ans = new String[words.size()];\n\n        int index = 0;\n        for (String word: words) {\n            String ab = abbrev(word, 0);\n            if (!groups.containsKey(ab))\n                groups.put(ab, new ArrayList());\n            groups.get(ab).add(new IndexedWord(word, index));\n            index++;\n        }\n\n        for (List<IndexedWord> group: groups.values()) {\n            Collections.sort(group, (a, b) -> a.word.compareTo(b.word));\n\n            int[] lcp = new int[group.size()];\n            for (int i = 1; i < group.size(); ++i) {\n                int p = longestCommonPrefix(group.get(i-1).word, group.get(i).word);\n                lcp[i] = p;\n                lcp[i-1] = Math.max(lcp[i-1], p);\n            }\n\n            for (int i = 0; i < group.size(); ++i)\n                ans[group.get(i).index] = abbrev(group.get(i).word, lcp[i]);\n        }\n\n        return Arrays.asList(ans);\n    }\n\n    public String abbrev(String word, int i) {\n        int N = word.length();\n        if (N - i <= 3) return word;\n        return word.substring(0, i+1) + (N - i - 2) + word.charAt(N-1);\n    }\n\n    public int longestCommonPrefix(String word1, String word2) {\n        int i = 0;\n        while (i < word1.length() && i < word2.length()\n                && word1.charAt(i) == word2.charAt(i))\n            i++;\n        return i;\n    }\n\n    class IndexedWord {\n        String word;\n        int index;\n        IndexedWord(String w, int i) {\n            word = w;\n            index = i;\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/word-abbreviation/solution/s\n     */\n    public List<String> wordsAbbreviation3(List<String> words) {\n        Map<String, List<IndexedWord>> groups = new HashMap();\n        String[] ans = new String[words.size()];\n\n        int index = 0;\n        for (String word: words) {\n            String ab = abbrev(word, 0);\n            if (!groups.containsKey(ab))\n                groups.put(ab, new ArrayList());\n            groups.get(ab).add(new IndexedWord(word, index));\n            index++;\n        }\n\n        for (List<IndexedWord> group: groups.values()) {\n            TrieNode trie = new TrieNode();\n            for (IndexedWord iw: group) {\n                TrieNode cur = trie;\n                for (char letter: iw.word.substring(1).toCharArray()) {\n                    if (cur.children[letter - 'a'] == null)\n                        cur.children[letter - 'a'] = new TrieNode();\n                    cur.count++;\n                    cur = cur.children[letter - 'a'];\n                }\n            }\n\n            for (IndexedWord iw: group) {\n                TrieNode cur = trie;\n                int i = 1;\n                for (char letter: iw.word.substring(1).toCharArray()) {\n                    if (cur.count == 1) break;\n                    cur = cur.children[letter - 'a'];\n                    i++;\n                }\n                ans[iw.index] = abbrev(iw.word, i-1);\n            }\n        }\n\n        return Arrays.asList(ans);\n    }\n\n    class TrieNode {\n        TrieNode[] children;\n        int count;\n        TrieNode() {\n            children = new TrieNode[26];\n            count = 0;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/WordBreak139.java",
    "content": "/**\n * Given a non-empty string s and a dictionary wordDict containing a list of\n * non-empty words, determine if s can be segmented into a space-separated\n * sequence of one or more dictionary words. You may assume the dictionary\n * does not contain duplicate words.\n *\n * For example, given\n * s = \"leetcode\",\n * dict = [\"leet\", \"code\"].\n *\n * Return true because \"leetcode\" can be segmented as \"leet code\".\n *\n * UPDATE (2017/1/4):\n * The wordDict parameter had been changed to a list of strings (instead of a\n * set of strings). Please reload the code definition to get the latest changes.\n */\n\n\npublic class WordBreak139 {\n    public boolean wordBreak(String s, List<String> wordDict) {\n        int L = s.length();\n        if (L == 0) return true;\n        boolean[] dp = new boolean[L+1];\n        dp[0] = true;\n        int k = 0;\n        for (int i=0; i<=L; i++) {\n            for (int j=0; j<=i; j++) {\n                if (dp[j] && wordDict.contains(s.substring(j, i))) {\n                    dp[i] = true;\n                }\n            }\n        }\n        return dp[L];\n    }\n\n\n    public boolean wordBreak2(String s, List<String> wordDict) {\n        boolean[] dp = new boolean[s.length()+1];\n        dp[0] = true;\n        for (int j=1; j<=s.length(); j++) {\n            for (String word: wordDict) {\n                if (j >= word.length() && s.startsWith(word, j - word.length()) && dp[j - word.length()]) dp[j] = true;\n            }\n        }\n        return dp[s.length()];\n    }\n\n}\n"
  },
  {
    "path": "src/WordBreakII140.java",
    "content": "/**\n * Given a non-empty string s and a dictionary wordDict containing a list of\n * non-empty words, add spaces in s to construct a sentence where each word is\n * a valid dictionary word. Return all such possible sentences.\n * \n * Note:\n * The same word in the dictionary may be reused multiple times in the segmentation.\n * You may assume the dictionary does not contain duplicate words.\n * \n * Example 1:\n * Input:\n * s = \"catsanddog\"\n * wordDict = [\"cat\", \"cats\", \"and\", \"sand\", \"dog\"]\n * Output:\n * [\n *   \"cats and dog\",\n *   \"cat sand dog\"\n * ]\n * \n * Example 2:\n * Input:\n * s = \"pineapplepenapple\"\n * wordDict = [\"apple\", \"pen\", \"applepen\", \"pine\", \"pineapple\"]\n * Output:\n * [\n *   \"pine apple pen apple\",\n *   \"pineapple pen apple\",\n *   \"pine applepen apple\"\n * ]\n * Explanation: Note that you are allowed to reuse a dictionary word.\n * \n * Example 3:\n * Input:\n * s = \"catsandog\"\n * wordDict = [\"cats\", \"dog\", \"sand\", \"and\", \"cat\"]\n * Output:\n * []\n */\n\npublic class WordBreakII140 {\n    // Memory Limit Exceeded\n    // public List<String> wordBreak(String s, List<String> wordDict) {\n    //     int N = s.length();\n    //     LinkedList<String>[] dp = new LinkedList[N+1];\n    //     for (int i=0; i<=N; i++) dp[i] = new LinkedList<>();\n    //     Set<String> wordSet = new HashSet<>(wordDict);\n\n    //     dp[0].add(\"\");\n    //     for (int i=1; i<=N; i++) {\n    //         for (int j=0; j<i; j++) {\n    //             String w = s.substring(j, i);\n    //             if (dp[j].size() > 0 && wordSet.contains(w)) {\n    //                 for (String p: dp[j]) {\n    //                     dp[i].add(p.length() == 0 ? w : (p + \" \" + w));\n    //                 }\n    //             }\n    //         }\n    //     }\n\n    //     return dp[N];\n    // }\n\n\n    // DP\n    public List<String> wordBreak(String s, List<String> wordDict) {\n        Set<String> wordSet = new HashSet<>(wordDict);\n        if (!wordIsBreakable(s, wordSet)) return new ArrayList<>();\n        return wordBreak(s, wordSet);\n    }\n\n    public List<String> wordBreak(String s, Set<String> wordDict) {\n        LinkedList<String>[] dp = new LinkedList[s.length() + 1];\n        LinkedList<String> initial = new LinkedList<>();\n        initial.add(\"\");\n        dp[0] = initial;\n        for (int i = 1; i <= s.length(); i++) {\n            LinkedList<String> list = new LinkedList<>();\n            for (int j = 0; j < i; j++) {\n                if (dp[j].size() > 0 && wordDict.contains(s.substring(j, i))) {\n                    for (String l : dp[j]) {\n                        list.add(l + (l.equals(\"\") ? \"\" : \" \") + s.substring(j, i));\n                    }\n                }\n            }\n            dp[i] = list;\n        }\n        return dp[s.length()];\n    }\n\n    public boolean wordIsBreakable(String s, Set<String> wordDictSet) {\n        boolean[] dp = new boolean[s.length() + 1];\n        dp[0] = true;\n        for (int i = 1; i <= s.length(); i++) {\n            for (int j = 0; j < i; j++) {\n                if (dp[j] && wordDictSet.contains(s.substring(j, i))) {\n                    dp[i] = true;\n                    break;\n                }\n            }\n        }\n        return dp[s.length()];\n    }\n\n\n    // Backtracing\n    public List<String> wordBreak2(String s, List<String> wordDict) {\n        if (!wordIsBreakable(s, new HashSet<>(wordDict))) return new ArrayList<>();\n        int N = s.length();\n        Set<String>[] dp = new Set[N];\n        for (int i=0; i<N; i++) dp[i] = new HashSet<String>();\n\n        for (int i=0; i<N; i++) {\n            for (String word: wordDict) {\n                if (s.startsWith(word, i)) {\n                    dp[i].add(word);\n                }\n            }\n        }\n\n        List<String> res = new ArrayList<>();\n        helper(N, dp, res, new StringBuilder(), 0);\n        return res;\n    }\n\n    private void helper(int N, Set<String>[] dp, List<String> res, StringBuilder sb, int i) {\n        if (i == N) {\n            res.add(sb.substring(0, sb.length()-1).toString());\n            return;\n        }\n        for (String w: dp[i]) {\n            sb.append(w).append(\" \");\n            helper(N, dp, res, sb, i+w.length());\n            sb.delete(sb.length()-w.length()-1, sb.length());\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/word-break-ii/discuss/44167/My-concise-JAVA-solution-based-on-memorized-DFS\n     */\n    public List<String> wordBreak3(String s, Set<String> wordDict) {\n        return DFS(s, wordDict, new HashMap<String, LinkedList<String>>());\n    }\n\n    // DFS function returns an array including all substrings derived from s.\n    List<String> DFS(String s, Set<String> wordDict, HashMap<String, LinkedList<String>>map) {\n        if (map.containsKey(s)) \n            return map.get(s);\n\n        LinkedList<String>res = new LinkedList<String>();     \n        if (s.length() == 0) {\n            res.add(\"\");\n            return res;\n        }\n        for (String word : wordDict) {\n            if (s.startsWith(word)) {\n                List<String>sublist = DFS(s.substring(word.length()), wordDict, map);\n                for (String sub : sublist) \n                    res.add(word + (sub.isEmpty() ? \"\" : \" \") + sub);               \n            }\n        }\n        map.put(s, res);\n        return res;\n    }\n\n}\n"
  },
  {
    "path": "src/WordDictionary.java",
    "content": "/**\n * Design a data structure that supports the following two operations:\n *\n * void addWord(word)\n * bool search(word)\n * search(word) can search a literal word or a regular expression string\n * containing only letters a-z or .. A . means it can represent any one letter.\n *\n * For example:\n *\n * addWord(\"bad\")\n * addWord(\"dad\")\n * addWord(\"mad\")\n * search(\"pad\") -> false\n * search(\"bad\") -> true\n * search(\".ad\") -> true\n * search(\"b..\") -> true\n * Note:\n * You may assume that all words are consist of lowercase letters a-z.\n *\n */\n\n\npublic class WordDictionary {\n\n    Trie t = new Trie();\n\n    /** Initialize your data structure here. */\n    public WordDictionary() {\n    }\n\n    /** Adds a word into the data structure. */\n    public void addWord(String word) {\n        add(t, word.toCharArray(), 0);\n    }\n\n    private static void add(Trie tr, char[] chars, int i) {\n        while (i < chars.length) tr = tr.add(chars[i++]);\n        tr.isWord = true;\n    }\n\n    // private static void add(Trie tr, char[] chars, int i) {\n    //     if (i >= chars.length) {\n    //         tr.isWord = true;\n    //         return;\n    //     }\n    //     add(tr.add(chars[i]), chars, i+1);\n    // }\n\n    /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */\n    public boolean search(String word) {\n        return search(t, word.toCharArray(), 0);\n    }\n\n    private static boolean search(Trie tr, char[] chars, int i) {\n        while (i < chars.length) {\n            char c = chars[i];\n            if (c == '.') {\n                for (char nc: tr.map.keySet()) {\n                    if (tr.has(nc) && search(tr.get(nc), chars, i+1)) {\n                        return true;\n                    }\n                }\n                return false;\n            } else {\n                if (!tr.has(c)) return false;\n                tr = tr.get(c);\n                i++;\n            }\n        }\n        return tr.isWord;\n    }\n\n    // private static boolean search(Trie tr, char[] chars, int i) {\n    //     if (i >= chars.length) return tr.isWord;\n    //     char c = chars[i];\n    //     if (c == '.') {\n    //         for (char nc: tr.map.keySet()) {\n    //             if (tr.has(nc) && search(tr.get(nc), chars, i+1)) {\n    //                 return true;\n    //             }\n    //         }\n    //         return false;\n    //     } else {\n    //         return tr.has(c) && search(tr.get(c), chars, i+1);\n    //     }\n    // }\n\n}\n\n\nclass Trie {\n    // also Trie[] map = new Trie[26];\n    Map<Character, Trie> map = new HashMap<>();\n    boolean isWord = false;\n\n    public Trie() {\n    }\n\n    public Trie get(char c) {\n        return this.map.get(c);\n    }\n\n    public Trie add(char c) {\n        return this.map.computeIfAbsent(c, cc -> new Trie());\n    }\n\n    public boolean has(char c) {\n        return c == '.' || this.map.containsKey(c);\n    }\n}\n\n\n/**\n * Your WordDictionary object will be instantiated and called as such:\n * WordDictionary obj = new WordDictionary();\n * obj.addWord(word);\n * boolean param_2 = obj.search(word);\n */\n"
  },
  {
    "path": "src/WordLadder127.java",
    "content": "/**\n * Given two words (beginWord and endWord), and a dictionary's word list, find\n * the length of shortest transformation sequence from beginWord to endWord,\n * such that:\n *\n * Only one letter can be changed at a time.\n * Each transformed word must exist in the word list. Note that beginWord is not a transformed word.\n * For example,\n *\n * Given:\n *    beginWord = \"hit\"\n *    endWord = \"cog\"\n *    wordList = [\"hot\",\"dot\",\"dog\",\"lot\",\"log\",\"cog\"]\n *\n * As one shortest transformation is \"hit\" -> \"hot\" -> \"dot\" -> \"dog\" -> \"cog\",\n * return its length 5.\n * Note:\n *    Return 0 if there is no such transformation sequence.\n *    All words have the same length.\n *    All words contain only lowercase alphabetic characters.\n *    You may assume no duplicates in the word list.\n *    You may assume beginWord and endWord are non-empty and are not the same.\n *\n */\n\n\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.LinkedList;\nimport java.util.Queue;\nimport java.util.Set;\nimport java.util.HashSet;\n\n\npublic class WordLadder127 {\n    // DFS too slow\n\n    // BFS\n    public int ladderLength(String start, String end, List<String> dictL) {\n        Set<String> dict = new HashSet<>(dictL);\n        if (!dict.contains(end)) {\n            return 0;\n        }\n        Queue<String> queue = new LinkedList<String>();\n        queue.add(start);\n\n        // Mark visited word\n        Set<String> visited = new HashSet<String>();\n        visited.add(start);\n\n        int level = 1;\n        while (!queue.isEmpty()) {\n            int size = queue.size();\n            for (int q=0; q<size; q++) {\n                String str = queue.poll(); \n                // Modify str's each character (so word distance is 1)\n                for (int i = 0; i < str.length(); i++) {\n                    char[] chars = str.toCharArray();\n                    for (char c = 'a'; c <= 'z'; c++) {\n                        chars[i] = c;\n                        String word = new String(chars);\n                        // Found the end word\n                        if (word.equals(end)) return level + 1;\n                        // Put it to the queue\n                        if (dict.contains(word) && !visited.contains(word)) {\n                            queue.add(word);\n                            visited.add(word);\n                        }\n                    }\n                }\n            }\n            level++;\n        }\n        return 0;\n    }\n\n    /**\n     * https://discuss.leetcode.com/topic/17890/another-accepted-java-solution-bfs\n     */\n    public int ladderLength2(String start, String end, List<String> dictL) {\n        Set<String> dict = new HashSet<>(dictL);\n        if (!dict.contains(end)) {\n            return 0;\n        }\n        Queue<String> queue = new LinkedList<String>();\n        queue.add(start);\n        queue.add(null);\n\n        // Mark visited word\n        Set<String> visited = new HashSet<String>();\n        visited.add(start);\n\n        int level = 1;\n\n        while (!queue.isEmpty()) {\n            String str = queue.poll();\n\n            if (str != null) {\n                // Modify str's each character (so word distance is 1)\n                for (int i = 0; i < str.length(); i++) {\n                    char[] chars = str.toCharArray();\n\n                    for (char c = 'a'; c <= 'z'; c++) {\n                        chars[i] = c;\n\n                        String word = new String(chars);\n\n                        // Found the end word\n                        if (word.equals(end)) return level + 1;\n\n                        // Put it to the queue\n                        if (dict.contains(word) && !visited.contains(word)) {\n                            queue.add(word);\n                            visited.add(word);\n                        }\n                    }\n                }\n            } else {\n                level++;\n\n                if (!queue.isEmpty()) {\n                    queue.add(null);\n                }\n            }\n        }\n\n        return 0;\n    }\n\n    /**\n     * Two-end BFS in Java 31ms.\n     * https://discuss.leetcode.com/topic/29303/two-end-bfs-in-java-31ms\n     */\n    public int ladderLength3(String beginWord, String endWord, List<String> wordL) {\n        Set<String> wordList = new HashSet<>(wordL);\n        if (!wordList.contains(endWord)) {\n            return 0;\n        }\n        Set<String> beginSet = new HashSet<String>(), endSet = new HashSet<String>();\n\n        int len = 1;\n        int strLen = beginWord.length();\n        HashSet<String> visited = new HashSet<String>();\n\n        beginSet.add(beginWord);\n        endSet.add(endWord);\n        while (!beginSet.isEmpty() && !endSet.isEmpty()) {\n            if (beginSet.size() > endSet.size()) {\n                Set<String> set = beginSet;\n                beginSet = endSet;\n                endSet = set;\n            }\n\n            Set<String> temp = new HashSet<String>();\n            for (String word : beginSet) {\n                char[] chs = word.toCharArray();\n\n                for (int i = 0; i < chs.length; i++) {\n                    for (char c = 'a'; c <= 'z'; c++) {\n                        char old = chs[i];\n                        chs[i] = c;\n                        String target = String.valueOf(chs);\n\n                        if (endSet.contains(target)) {\n                            return len + 1;\n                        }\n\n                        if (!visited.contains(target) && wordList.contains(target)) {\n                            temp.add(target);\n                            visited.add(target);\n                        }\n                        chs[i] = old;\n                    }\n                }\n            }\n\n            beginSet = temp;\n            len++;\n        }\n\n        return 0;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/20965/java-solution-using-dijkstra-s-algorithm-with-explanation\n     */\n    public int ladderLength4(String beginWord, String endWord, List<String> dictL) {\n        Set<String> wordDict = new HashSet<>(dictL);\n        if (!wordDict.contains(endWord)) {\n            return 0;\n        }\n        Set<String> reached = new HashSet<String>();\n        reached.add(beginWord);\n\n        int distance = 1;\n        while (!reached.contains(endWord)) {\n            Set<String> toAdd = new HashSet<String>();\n            for (String each : reached) {\n                for (int i = 0; i < each.length(); i++) {\n                    char[] chars = each.toCharArray();\n                    for (char ch = 'a'; ch <= 'z'; ch++) {\n                        chars[i] = ch;\n                        String word = new String(chars);\n                        if (wordDict.contains(word)) {\n                            toAdd.add(word);\n                            wordDict.remove(word);\n                        }\n                    }\n                }\n            }\n            distance++;\n            if (toAdd.size() == 0) return 0;\n            reached = toAdd;\n        }\n        return distance;\n    }\n\n    public static void main(String[] args) {\n        WordLadder127 wl = new WordLadder127();\n\n        System.out.println(\"--------\");\n        System.out.println(wl.ladderLength2(\"hit\", \"cog\", Arrays.asList(new String[]{\"hot\", \"dot\", \"dog\",\"lot\",\"log\",\"cog\"})));\n        System.out.println(\"--------\");\n        System.out.println(wl.ladderLength2(\"hot\", \"dog\", Arrays.asList(new String[]{\"hot\",\"cog\",\"dog\",\"tot\",\"hog\",\"hop\",\"pot\",\"dot\"})));\n        System.out.println(\"--------\");\n        System.out.println(wl.ladderLength2(\"hit\", \"cog\", Arrays.asList(new String[]{\"hot\",\"dot\",\"dog\",\"lot\",\"log\"})));\n    }\n\n\n}\n"
  },
  {
    "path": "src/WordLadderII126.java",
    "content": "/**\n * Given two words (beginWord and endWord), and a dictionary's word list, find\n * all shortest transformation sequence(s) from beginWord to endWord, such that:\n * \n * Only one letter can be changed at a time\n * Each transformed word must exist in the word list. Note that beginWord is\n * not a transformed word.\n * \n * Note:\n * Return an empty list if there is no such transformation sequence.\n * All words have the same length.\n * All words contain only lowercase alphabetic characters.\n * You may assume no duplicates in the word list.\n * You may assume beginWord and endWord are non-empty and are not the same.\n * \n * Example 1:\n * Input:\n * beginWord = \"hit\",\n * endWord = \"cog\",\n * wordList = [\"hot\",\"dot\",\"dog\",\"lot\",\"log\",\"cog\"]\n * Output:\n * [\n *   [\"hit\",\"hot\",\"dot\",\"dog\",\"cog\"],\n *   [\"hit\",\"hot\",\"lot\",\"log\",\"cog\"]\n * ]\n * \n * Example 2:\n * Input:\n * beginWord = \"hit\"\n * endWord = \"cog\"\n * wordList = [\"hot\",\"dot\",\"dog\",\"lot\",\"log\"]\n * Output: []\n * \n * Explanation: The endWord \"cog\" is not in wordList, therefore no possible\n * transformation.\n */\n\n\npublic class WordLadderII126 {\n    public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {\n        Set<String> wordDict = new HashSet<>(wordList);\n        if (!wordDict.contains(endWord)) return new ArrayList<>();\n        wordDict.remove(beginWord);\n        Set<String> visited = new HashSet<>();\n        \n        List<String> first = new ArrayList<>();\n        first.add(beginWord);\n        List<List<String>> res = new ArrayList<>();\n        res.add(first);\n        while (true) {\n            List<List<String>> newRes = new ArrayList<>();\n            Set<String> localVisited = new HashSet<>();\n            boolean found = false;\n            for (int i=0; i<res.size(); i++) {\n                List<String> path = res.get(i);\n                String word = path.get(path.size()-1);\n                for (int j=0; j<word.length(); j++) {\n                    char[] chars = word.toCharArray();\n                    for (char ch='a'; ch<='z'; ch++) {\n                        chars[j] = ch;\n                        String newWord = new String(chars);\n                        if (newWord.equals(endWord)) found = true;\n                        if (!visited.contains(newWord) && wordDict.contains(newWord)) {\n                            List<String> newPath = new ArrayList<>(path);\n                            newPath.add(newWord);\n                            newRes.add(newPath);\n                            if (!newWord.equals(endWord)) localVisited.add(newWord);\n                            // wordDict.remove(newWord);\n                        }\n                    }\n                }\n            }\n            if (newRes.size() == 0) return newRes;\n            if (found) {\n                List<List<String>> returned = new ArrayList<>();\n                for (List<String> p: newRes) {\n                    if (p.get(p.size()-1).equals(endWord)) {\n                        returned.add(p);\n                    }\n                }\n                return returned;\n            }\n            res = newRes;\n            visited.addAll(localVisited);\n        }\n    }\n\n\n    /**\n     * https://leetcode.com/problems/word-ladder-ii/discuss/40477/Super-fast-Java-solution-(two-end-BFS)\n     */\n    public List<List<String>> findLadders2(String start, String end, List<String> wordList) {\n      Set<String> dict = new HashSet<String>(wordList);\n        if (!dict.contains(end)) return new ArrayList<>();\n      // hash set for both ends\n      Set<String> set1 = new HashSet<String>();\n      Set<String> set2 = new HashSet<String>();\n      \n      // initial words in both ends\n      set1.add(start);\n      set2.add(end);\n      \n      // we use a map to help construct the final result\n      Map<String, List<String>> map = new HashMap<String, List<String>>();\n      \n      // build the map\n      helper(dict, set1, set2, map, false);\n      \n      List<List<String>> res = new ArrayList<List<String>>();\n      List<String> sol = new ArrayList<String>(Arrays.asList(start));\n      \n      // recursively build the final result\n      generateList(start, end, map, sol, res);\n      \n      return res;\n    }\n    \n    private boolean helper(Set<String> dict, Set<String> set1, Set<String> set2, Map<String, List<String>> map, boolean flip) {\n        if (set1.isEmpty()) {\n            return false;\n        }\n        \n        if (set1.size() > set2.size()) {\n            return helper(dict, set2, set1, map, !flip);\n        }\n        \n        // remove words on current both ends from the dict\n        dict.removeAll(set1);\n        dict.removeAll(set2);\n        \n        // as we only need the shortest paths\n        // we use a boolean value help early termination\n        boolean done = false;\n        \n        // set for the next level\n        Set<String> set = new HashSet<String>();\n        \n        // for each string in end 1\n        for (String str : set1) {\n            for (int i = 0; i < str.length(); i++) {\n                char[] chars = str.toCharArray();\n                \n                // change one character for every position\n                for (char ch = 'a'; ch <= 'z'; ch++) {\n                    chars[i] = ch;\n                    \n                    String word = new String(chars);\n                    \n                    // make sure we construct the tree in the correct direction\n                    String key = flip ? word : str;\n                    String val = flip ? str : word;\n                        \n                    List<String> list = map.containsKey(key) ? map.get(key) : new ArrayList<String>();\n                        \n                    if (set2.contains(word)) {\n                        done = true;\n                        \n                        list.add(val);\n                        map.put(key, list);\n                    } \n                    \n                    if (!done && dict.contains(word)) {\n                        set.add(word);\n                        \n                        list.add(val);\n                        map.put(key, list);\n                    }\n                }\n            }\n        }\n        \n        // early terminate if done is true\n        return done || helper(dict, set2, set, map, !flip);\n    }\n    \n    private void generateList(String start, String end, Map<String, List<String>> map, List<String> sol, List<List<String>> res) {\n        if (start.equals(end)) {\n            res.add(new ArrayList<String>(sol));\n            return;\n        }\n        \n        // need this check in case the diff between start and end happens to be one\n        // e.g \"a\", \"c\", {\"a\", \"b\", \"c\"}\n        if (!map.containsKey(start)) {\n            return;\n        }\n        \n        for (String word : map.get(start)) {\n            sol.add(word);\n            generateList(word, end, map, sol, res);\n            sol.remove(sol.size() - 1);\n        }\n    }\n\n\n    List<List<String>> ans = new ArrayList<>();\n    public List<List<String>> findLadders3(String beginWord, String endWord, List<String> wordList) {\n        // for each level,\n        // should NOT use the words in upper level\n        // should NOT add same words into queue\n        // however, should use the same word in current level\n        \n        Map<String, List<String>> map = new HashMap<>();\n        Set<String> unvisited = new HashSet<>(wordList);\n        Set<String> visited = new HashSet<>();\n        Deque<String> queue = new LinkedList<>();\n        queue.offer(beginWord);\n        visited.add(beginWord);\n        unvisited.remove(beginWord);\n        boolean found = false;\n        while(!found && !queue.isEmpty()){\n            \n            // begin each level\n            int size = queue.size();\n            visited.clear();\n            \n            for(int k = 0; k < size; k++){\n                String word = queue.poll();\n                for(int i = 0; i < word.length(); i++){\n                    StringBuilder sb = new StringBuilder(word);\n                    for(char c = 'a'; c < 'z'; c++){\n                        sb.setCharAt(i, c);\n                        String newWord = sb.toString();\n                        if(unvisited.contains(newWord)){\n                            if(visited.add(newWord)){\n                                queue.offer(newWord);\n                            }\n                            \n                            if(map.containsKey(newWord)){\n                                map.get(newWord).add(word);\n                            }else{\n                                List<String> adj = new ArrayList<>();\n                                adj.add(word);\n                                map.put(newWord, adj);\n                            }\n                            if(newWord.equals(endWord)){\n                                found = true;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            // end of each level\n            unvisited.removeAll(visited);\n        }\n        \n        List<String> path = new ArrayList<>();\n        path.add(endWord);\n        dfs(beginWord, path, map);\n        return ans;\n        \n    }\n    \n    private void dfs(String beginWord, List<String> path, Map<String, List<String>> map){\n        String word = path.get(0);\n        if(word.equals(beginWord)){\n            ans.add(new ArrayList<>(path));\n            return;\n        }\n        if(map.containsKey(word)){\n            for(String prevWord : map.get(word)){\n                path.add(0, prevWord);\n                dfs(beginWord, path, map);\n                path.remove(0);\n            }\n        }\n        \n    }\n\n}\n\n\n"
  },
  {
    "path": "src/WordPattern290.java",
    "content": "/**\n * Given a pattern and a string str, find if str follows the same pattern.\n * \n * Here follow means a full match, such that there is a bijection between a\n * letter in pattern and a non-empty word in str.\n * \n * Example 1:\n * Input: pattern = \"abba\", str = \"dog cat cat dog\"\n * Output: true\n * \n * Example 2:\n * Input:pattern = \"abba\", str = \"dog cat cat fish\"\n * Output: false\n * \n * Example 3:\n * Input: pattern = \"aaaa\", str = \"dog cat cat dog\"\n * Output: false\n * \n * Example 4:\n * Input: pattern = \"abba\", str = \"dog dog dog dog\"\n * Output: false\n * \n * Notes:\n * You may assume pattern contains only lowercase letters, and str contains\n * lowercase letters separated by a single space.\n */\n\npublic class WordPattern290 {\n    public boolean wordPattern(String pattern, String str) {\n        String[] words = str.trim().split(\"\\\\s+\");\n        if (pattern.length() != words.length) return false;\n        Map<Character, String> map = new HashMap<>();\n        int N = pattern.length();\n        for (int i=0; i<N; i++) {\n            String w = words[i];\n            Character ch = pattern.charAt(i);\n            if (map.containsKey(ch)) {\n                if (!map.get(ch).equals(w)) return false;\n            } else {\n                if (map.values().contains(w)) return false;\n                map.put(ch, w);\n            }\n        }\n        return true;\n    }\n\n\n    public boolean wordPattern2(String pattern, String str) {\n        String[] words = str.trim().split(\"\\\\s+\");\n        if (pattern.length() != words.length) return false;\n        String[] map = new String[26];\n        int N = pattern.length();\n        for (int i=0; i<N; i++) {\n            String w = words[i];\n            char ch = pattern.charAt(i);\n            int idx = ch - 'a';\n            if (map[idx] != null) {\n                if (!map[idx].equals(w)) return false;\n            } else {\n                if (contains(map, w)) return false;\n                map[idx] = w;\n            }\n        }\n        return true;\n    }\n    \n    private boolean contains(String[] map, String w) {\n        for (String m: map) {\n            if (m != null && m.equals(w)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n\n    public boolean wordPattern3(String pattern, String str) {\n        String[] words = str.trim().split(\"\\\\s+\");\n        if (pattern.length() != words.length) return false;\n        String[] map = new String[26];\n        Set<String> set = new HashSet<>();\n        int N = pattern.length();\n        for (int i=0; i<N; i++) {\n            String w = words[i];\n            char ch = pattern.charAt(i);\n            int idx = ch - 'a';\n            if (map[idx] != null) {\n                if (!map[idx].equals(w)) return false;\n            } else {\n                if (set.contains(w)) return false;\n                map[idx] = w;\n                set.add(w);\n            }\n        }\n        return true;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/word-pattern/discuss/73402/8-lines-simple-Java\n     */\n    public boolean wordPattern4(String pattern, String str) {\n        String[] words = str.split(\" \");\n        if (words.length != pattern.length())\n            return false;\n        Map index = new HashMap();\n        for (Integer i=0; i<words.length; ++i)\n            if (index.put(pattern.charAt(i), i) != index.put(words[i], i))\n                return false;\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "src/WordPatternII291.java",
    "content": "/**\n * Given a pattern and a string str, find if str follows the same pattern.\n * \n * Here follow means a full match, such that there is a bijection between a\n * letter in pattern and a non-empty substring in str.\n * \n * Example 1:\n * Input: pattern = \"abab\", str = \"redblueredblue\"\n * Output: true\n * \n * Example 2:\n * Input: pattern = pattern = \"aaaa\", str = \"asdasdasdasd\"\n * Output: true\n * \n * Example 3:\n * Input: pattern = \"aabb\", str = \"xyzabcxzyabc\"\n * Output: false\n * \n * Notes:\n * You may assume both pattern and str contains only lowercase letters.\n */\n\npublic class WordPatternII291 {\n    public boolean wordPatternMatch(String pattern, String str) {\n        if (pattern.length() == 0) return str.length() == 0;\n        if (str.length() == 0) return false;\n        return match(pattern, 0, str, 0, new String[26], new HashMap<>());\n    }\n\n    private boolean match(String pattern, int i, String str, int j, String[] p2s, Map<String, Character> s2p) {\n        if (i == pattern.length()) return j == str.length();\n        if (j == str.length()) return false; \n\n        char p = pattern.charAt(i);\n        if (p2s[p-'a'] != null) {\n            String sub = p2s[p-'a'];\n            if (!str.startsWith(sub, j)) return false;\n            if (match(pattern, i+1, str, j+sub.length(), p2s, s2p)) return true;\n        } else {\n            for (int k=j+1; k<=str.length(); k++) {\n                String sub = str.substring(j, k);\n                if (s2p.containsKey(sub)) {\n                    char p0 = s2p.get(sub);\n                    if (p0 != p) continue;\n                    if (match(pattern, i+1, str, j+sub.length(), p2s, s2p)) return true;\n                } else {\n                    p2s[p-'a'] = sub;\n                    s2p.put(sub, p);\n                    if (match(pattern, i+1, str, j+sub.length(), p2s, s2p)) return true;\n                    p2s[p-'a'] = null;\n                    s2p.remove(sub);\n                }\n            }\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "src/WordSearch79.java",
    "content": "/**\n * Given a 2D board and a word, find if the word exists in the grid.\n *\n * The word can be constructed from letters of sequentially adjacent cell,\n * where \"adjacent\" cells are those horizontally or vertically neighboring.\n * The same letter cell may not be used more than once.\n *\n * For example,\n * Given board =\n *\n * [\n *   ['A','B','C','E'],\n *   ['S','F','C','S'],\n *   ['A','D','E','E']\n * ]\n * word = \"ABCCED\", -> returns true,\n * word = \"SEE\", -> returns true,\n * word = \"ABCB\", -> returns false.\n *\n */\n\n\npublic class WordSearch79 {\n    public boolean exist(char[][] board, String word) {\n\n        if (word.length() == 0) {\n            return true;\n        }\n\n        if (board.length == 0) {\n            return false;\n        }\n\n        int m = board.length;\n        int n = board[0].length;\n\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < n; j++) {\n                boolean[][] visited = new boolean[m][n];\n                if (helper(i, j, 0, board, word, visited)) {\n                    return true;\n                }\n            }\n        }\n\n        return false;\n\n    }\n\n\n    private boolean helper(int i, int j, int index, char[][] board, String word, boolean[][] visited) {\n        if (index >= word.length()) {\n            return true;\n        }\n\n        if (i < 0 || i >= board.length || j < 0 || j >= board[0].length) {\n            return false;\n        }\n\n        if (visited[i][j] || board[i][j] != word.charAt(index)) {\n            return false;\n        }\n\n        visited[i][j] = true;\n\n        if (helper(i, j+1, index + 1, board, word, visited) ||\n                helper(i+1, j, index + 1, board, word, visited) ||\n                helper(i, j-1, index + 1, board, word, visited) ||\n                helper(i-1, j, index + 1, board, word, visited)) {\n            return true;\n        }\n\n        visited[i][j] = false;\n\n        return false;\n    }\n\n\n    /**\n     * https://discuss.leetcode.com/topic/7907/accepted-very-short-java-solution-no-additional-space\n     */\n    public boolean exist2(char[][] board, String word) {\n\n        if (word.length() == 0) {\n            return true;\n        }\n\n        if (board.length == 0) {\n            return false;\n        }\n\n        int m = board.length;\n        int n = board[0].length;\n\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < n; j++) {\n                if (helper(i, j, 0, board, word)) {\n                    return true;\n                }\n            }\n        }\n\n        return false;\n\n    }\n\n\n    private boolean helper(int i, int j, int index, char[][] board, String word) {\n        if (index >= word.length()) {\n            return true;\n        }\n\n        if (i < 0 || i >= board.length || j < 0 || j >= board[0].length) {\n            return false;\n        }\n\n        if (board[i][j] != word.charAt(index)) {\n            return false;\n        }\n\n        board[i][j] ^= 256;\n\n        if (helper(i, j+1, index + 1, board, word) ||\n                helper(i+1, j, index + 1, board, word) ||\n                helper(i, j-1, index + 1, board, word) ||\n                helper(i-1, j, index + 1, board, word)) {\n            return true;\n        }\n\n        board[i][j] ^= 256;\n\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "src/WordSearchII212.java",
    "content": "/**\n * Given a 2D board and a list of words from the dictionary, find all words in\n * the board.\n *\n * Each word must be constructed from letters of sequentially adjacent cell,\n * where \"adjacent\" cells are those horizontally or vertically neighboring.\n * The same letter cell may not be used more than once in a word.\n *\n * For example,\n * Given words = [\"oath\",\"pea\",\"eat\",\"rain\"] and board =\n *\n * [\n *   ['o','a','a','n'],\n *   ['e','t','a','e'],\n *   ['i','h','k','r'],\n *   ['i','f','l','v']\n * ]\n * Return [\"eat\",\"oath\"].\n * Note:\n * You may assume that all inputs are consist of lowercase letters a-z.\n *\n * Hint:\n * You would need to optimize your backtracking to pass the larger test. Could\n * you stop backtracking earlier?\n *\n * If the current candidate does not exist in all words' prefix, you could stop\n * backtracking immediately. What kind of data structure could answer such query\n * efficiently? Does a hash table work? Why or why not? How about a Trie? If\n * you would like to learn how to implement a basic trie, please work on this\n * problem: Implement Trie (Prefix Tree) first.\n *\n */\n\n\n\npublic class WordSearchII212 {\n    public List<String> findWords(char[][] board, String[] words) {\n        List<String> res = new ArrayList<>();\n        TrieNode root = buildTrie(words);\n        for (int i = 0; i < board.length; i++) {\n            for (int j = 0; j < board[0].length; j++) {\n                helper(board, i, j, root, res);\n            }\n        }\n        return res;\n    }\n\n    private void helper(char[][] board, int i, int j, TrieNode node, List<String> res) {\n        if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] == '#' || !node.containsKey(board[i][j])) {\n            return;\n        }\n        char curr = board[i][j];\n\n        node = node.get(curr);\n        if (node.containsWord()) {\n            res.add(node.getWord());\n            node.setWord(null);\n        }\n\n        board[i][j] = '#';\n        helper(board, i, j+1, node, res);\n        helper(board, i+1, j, node, res);\n        helper(board, i, j-1, node, res);\n        helper(board, i-1, j, node, res);\n        board[i][j] = curr;\n    }\n\n    public TrieNode buildTrie(String[] words) {\n        TrieNode root = new TrieNode();\n        for (String w : words) {\n            TrieNode node = root;\n            for (int i = 0; i < w.length(); i++) {\n                char c = w.charAt(i);\n                if (!node.containsKey(c)) {\n                    node.put(c, new TrieNode());\n                }\n                node = node.get(c);\n            }\n            node.setWord(w);\n        }\n        return root;\n    }\n\n    class TrieNode {\n\n        // R links to node children\n        private TrieNode[] links;\n\n        private final int R = 26;\n\n        private String word;\n\n        public TrieNode() {\n            links = new TrieNode[R];\n        }\n\n        public boolean containsKey(char c) {\n            return links[c -'a'] != null;\n        }\n        public TrieNode get(char c) {\n            return links[c -'a'];\n        }\n        public void put(char c, TrieNode node) {\n            links[c -'a'] = node;\n        }\n        public void setWord(String w) {\n            word = w;\n        }\n        public String getWord() {\n            return word;\n        }\n        public boolean containsWord() {\n            return word != null;\n        }\n    }\n\n\n    private int[][] dirs = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};\n    public List<String> findWords2(char[][] board, String[] words) {\n        if (board == null || board.length == 0 || board[0].length == 0 || words.length == 0) return new ArrayList<>();\n        int M = board.length;\n        int N = board[0].length;\n        Trie trie = constructTrie(words);\n        \n        Set<String> set = new HashSet<>();\n        boolean[][] visited = new boolean[M][N];\n        for (int i=0; i<M; i++) {\n            for (int j=0; j<N; j++) {\n                dfs(board, visited, trie, i, j, M, N, set);\n            }\n        }\n        \n        return new ArrayList<>(set);\n    }\n\n    \n    private void dfs(char[][] board, boolean[][] visited, Trie trie, int i, int j, int M, int N, Set<String> set) {\n        if (trie == null) return;\n        if (trie.word != null) set.add(trie.word);\n        if (i < 0 || j < 0 || i >= M || j >= N || visited[i][j]) return;\n        visited[i][j] = true;\n        char c = board[i][j];\n        Trie next = trie.get(c);\n        // if (next == null) return;\n        for (int[] d: dirs) {\n            dfs(board, visited, next, i+d[0], j+d[1], M, N, set);\n        }\n        visited[i][j] = false;\n    }\n    \n    \n    private Trie constructTrie(String[] words) {\n        Trie t = new Trie();\n        for (String word: words) t.addWord(word);\n        return t;\n    }\n\n    class Trie {\n        Trie[] children = new Trie[26];\n        String word = null;\n    \n        public void addWord(String word) {\n            addWord(word.toCharArray(), 0);\n        }\n\n        public void addWord(char[] chars, int i) {\n            if (i == chars.length) {\n                word = new String(chars);\n                return;\n            }\n            if (children[chars[i]-'a'] == null) {\n                children[chars[i]-'a'] = new Trie();\n            }\n            children[chars[i]-'a'].addWord(chars, i+1);\n        }\n        \n        public Trie get(char c) {\n            return children[c-'a'];\n        }\n        \n    }\n\n    /**\n     * https://leetcode.com/problems/word-search-ii/discuss/59780/Java-15ms-Easiest-Solution-(100.00)\n     * \n     * 59ms: Use search and startsWith in Trie class like this popular solution.\n     * 33ms: Remove Trie class which unnecessarily starts from root in every dfs call.\n     * 30ms: Use w.toCharArray() instead of w.charAt(i).\n     * 22ms: Use StringBuilder instead of c1 + c2 + c3.\n     * 20ms: Remove StringBuilder completely by storing word instead of boolean in TrieNode.\n     * 20ms: Remove visited[m][n] completely by modifying board[i][j] = '#' directly.\n     * 18ms: check validity, e.g., if(i > 0) dfs(...), before going to the next dfs.\n     * 17ms: De-duplicate c - a with one variable i.\n     * 15ms: Remove HashSet completely. dietpepsi's idea is awesome.\n     */\n    public List<String> findWords3(char[][] board, String[] words) {\n        List<String> res = new ArrayList<>();\n        TrieNode root = buildTrie2(words);\n        for (int i = 0; i < board.length; i++) {\n            for (int j = 0; j < board[0].length; j++) {\n                dfs (board, i, j, root, res);\n            }\n        }\n        return res;\n    }\n    \n    public void dfs(char[][] board, int i, int j, TrieNode p, List<String> res) {\n        char c = board[i][j];\n        if (c == '#' || p.next[c - 'a'] == null) return;\n        p = p.next[c - 'a'];\n        if (p.word != null) {   // found one\n            res.add(p.word);\n            p.word = null;     // de-duplicate\n        }\n    \n        board[i][j] = '#';\n        if (i > 0) dfs(board, i - 1, j ,p, res); \n        if (j > 0) dfs(board, i, j - 1, p, res);\n        if (i < board.length - 1) dfs(board, i + 1, j, p, res); \n        if (j < board[0].length - 1) dfs(board, i, j + 1, p, res); \n        board[i][j] = c;\n    }\n    \n    public TrieNode buildTrie2(String[] words) {\n        TrieNode root = new TrieNode();\n        for (String w : words) {\n            TrieNode p = root;\n            for (char c : w.toCharArray()) {\n                int i = c - 'a';\n                if (p.next[i] == null) p.next[i] = new TrieNode();\n                p = p.next[i];\n           }\n           p.word = w;\n        }\n        return root;\n    }\n    \n    class TrieNode {\n        TrieNode[] next = new TrieNode[26];\n        String word;\n    }\n\n}\n"
  },
  {
    "path": "src/WordSquares425.java",
    "content": "/**\n * Given a set of words (without duplicates), find all word squares you can\n * build from them.\n * \n * A sequence of words forms a valid word square if the kth row and column read\n * the exact same string, where 0 ≤ k < max(numRows, numColumns).\n * \n * For example, the word sequence [\"ball\",\"area\",\"lead\",\"lady\"] forms a word\n * square because each word reads the same both horizontally and vertically.\n * \n * b a l l\n * a r e a\n * l e a d\n * l a d y\n * \n * Note:\n * - There are at least 1 and at most 1000 words.\n * - All words will have the exact same length.\n * - Word length is at least 1 and at most 5.\n * - Each word contains only lowercase English alphabet a-z.\n * \n * Example 1:\n * \n * Input:\n * [\"area\",\"lead\",\"wall\",\"lady\",\"ball\"]\n * \n * Output:\n * [\n *   [ \"wall\",\n *     \"area\",\n *     \"lead\",\n *     \"lady\"\n *   ],\n *   [ \"ball\",\n *     \"area\",\n *     \"lead\",\n *     \"lady\"\n *   ]\n * ]\n * \n * Explanation:\n * The output consists of two word squares. The order of output does not matter\n * (just the order of words in each word square matters).\n * \n * Example 2:\n * \n * Input:\n * [\"abat\",\"baba\",\"atan\",\"atal\"]\n * \n * Output:\n * [\n *   [ \"baba\",\n *     \"abat\",\n *     \"baba\",\n *     \"atan\"\n *   ],\n *   [ \"baba\",\n *     \"abat\",\n *     \"baba\",\n *     \"atal\"\n *   ]\n * ]\n * \n * Explanation:\n * The output consists of two word squares. The order of output does not matter\n * (just the order of words in each word square matters).\n */\n\nimport java.util.List;\nimport java.util.ArrayList;\nimport java.util.Arrays;\n\npublic class WordSquares425 {\n    public List<List<String>> wordSquares(String[] words) {\n        List<List<String>> res = new ArrayList<>();\n        if (words == null || words.length == 0 || words[0].length() == 0) return res;\n\n        int len = words[0].length();\n        TrieNode root = new TrieNode();\n        for (String word: words) root.addWord(word);\n\n        helper(new char[len][len], root, 0, len, new ArrayList<String>(), res);\n        return res;\n    }\n\n    private void helper(char[][] square, TrieNode root, int pos, int len, List<String> sqr, List<List<String>> res) {\n        if (pos == len) {\n            if (sqr.size() == len) {\n                List<String> newSqr = new ArrayList<String>();\n                for (String s: sqr) {\n                    newSqr.add(s);\n                }\n                res.add(newSqr);\n            }\n            return;\n        }\n        List<String> finds = root.search(Arrays.copyOfRange(square[pos], 0, pos), len);\n\n        if (finds.size() == 0) return;\n        for (String w: finds) {\n            sqr.add(w);\n            for (int j=pos; j<len; j++) square[j][pos] = w.charAt(j);\n            helper(square, root, pos+1, len, sqr, res);\n            sqr.remove(sqr.size() - 1);\n        }\n    }\n\n\n    class TrieNode {\n        boolean isWord = false;\n        String word = null;\n        TrieNode[] children = new TrieNode[26];\n    \n        public void addWord(String word) {\n            addWord(word.toCharArray(), 0);\n        }\n    \n        public void addWord(char[] chars, int i) {\n            if (i == chars.length) {\n                this.isWord = true;\n                this.word = new String(chars);\n                return;\n            }\n            int idx = chars[i] - 'a';\n            if (children[idx] == null) {\n                TrieNode t = new TrieNode();\n                children[idx] = t;\n            }\n            children[idx].addWord(chars, i+1);\n        }\n    \n        public List<String> search(char[] prefix, int length) {\n            List<String> res = new ArrayList<String>();\n            search(prefix, length, 0, res);\n            return res;\n        }\n\n        public void search(char[] prefix, int length, int i, List<String> res) {\n            if (i == length) {\n                if (word != null) res.add(word);\n                return;\n            }\n            if (i < prefix.length) {\n                if (children[prefix[i] - 'a'] == null) return;\n                children[prefix[i] - 'a'].search(prefix, length, i+1, res);\n            } else {\n                for (TrieNode child: children) {\n                    if (child != null) child.search(prefix, length, i+1, res);\n                }\n            }\n        }\n    }\n\n\n    public List<List<String>> wordSquares2(String[] words) {\n        Arrays.sort(words);\n        List<List<String>> res = new ArrayList<>();\n        int W = words[0].length();\n        char[][] board = new char[W][W];\n        helper(board, 0, words, res, W);\n        return res;\n    }\n\n    private void helper(char[][] board, int i, String[] words, List<List<String>> res, int W) {\n        if (i >= W) {\n            List<String> r = new ArrayList<>();\n            for (int j=0; j<W; j++) {\n                r.add(new String(board[j]));\n            }\n            res.add(r);\n            return;\n        }\n        for (int j=i; j<W; j++) {\n            board[i][j] = 'a';\n        }\n        String start = new String(board[i]);\n        String prefix = new String(board[i], 0, i);\n        int idx = Arrays.binarySearch(words, start);\n        if (idx < 0) idx = - (idx + 1);\n        for (int k=idx; k<words.length; k++) {\n            String key = words[k];\n            if (!key.startsWith(prefix)) break;\n            char[] chars = key.toCharArray();\n            for (int j=0; j<W; j++) {\n                board[i][j] = chars[j];\n            }\n            for (int j=0; j<W; j++) {\n                board[j][i] = chars[j];\n            }\n            helper(board, i+1, words, res, W);\n        }\n    }\n\n}\n\n\n\n\n"
  },
  {
    "path": "src/ZeroOneMatrix542.java",
    "content": "/**\n * Given a matrix consists of 0 and 1, find the distance of the nearest 0 for\n * each cell.\n * \n * The distance between two adjacent cells is 1.\n * \n * Example 1: \n * Input:\n * 0 0 0\n * 0 1 0\n * 0 0 0\n * Output:\n * 0 0 0\n * 0 1 0\n * 0 0 0\n * \n * Example 2: \n * Input:\n * 0 0 0\n * 0 1 0\n * 1 1 1\n * Output:\n * 0 0 0\n * 0 1 0\n * 1 2 1\n * Note:\n * The number of elements of the given matrix will not exceed 10,000.\n * There are at least one 0 in the given matrix.\n * The cells are adjacent in only four directions: up, down, left and right.\n */\n\npublic class ZeroOneMatrix542 {\n    private int[][] directions = new int[][]{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};\n    public int[][] updateMatrix(int[][] matrix) {\n        int M = matrix.length;\n        int N = matrix[0].length;\n        Queue<int[]> q = new LinkedList<>();\n        for (int i=0; i<M; i++) {\n            for (int j=0; j<N; j++) {\n                if (matrix[i][j] == 1) {\n                    matrix[i][j] = Integer.MAX_VALUE;\n                } else {\n                    q.add(new int[]{i, j});\n                }\n            }\n        }\n        \n        while (!q.isEmpty()) {\n            int[] curr = q.poll();\n            int i = curr[0];\n            int j = curr[1];\n            for (int[] dir: directions) {\n                int x = i + dir[0];\n                int y = j + dir[1];\n                if (x < 0 || y < 0 || x >= M || y >= N || matrix[x][y] <= matrix[i][j] || matrix[x][y] == 0) continue;\n                q.add(new int[]{x, y});\n                matrix[x][y] = matrix[i][j] + 1;\n            }            \n        }\n        return matrix;\n    }\n\n\n    /**\n     * https://leetcode.com/problems/01-matrix/discuss/101051/Simple-Java-solution-beat-99-(use-DP)\n     */\n    public int[][] updateMatrix2(int[][] matrix) {\n        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {\n            return matrix;\n        }\n        int[][] dis = new int[matrix.length][matrix[0].length];\n        int range = matrix.length * matrix[0].length;\n\n        for (int i = 0; i < matrix.length; i++) {\n            for (int j = 0; j < matrix[0].length; j++) {\n                if (matrix[i][j] == 0) {\n                    dis[i][j] = 0;\n                } else {\n                    int upCell = (i > 0) ? dis[i - 1][j] : range;\n                    int leftCell = (j > 0) ? dis[i][j - 1] : range;\n                    dis[i][j] = Math.min(upCell, leftCell) + 1;\n                }\n            }\n        }\n\n        for (int i = matrix.length - 1; i >= 0; i--) {\n            for (int j = matrix[0].length - 1; j >= 0; j--) {\n                if (matrix[i][j] == 0) {\n                    dis[i][j] = 0;\n                } else {\n                    int downCell = (i < matrix.length - 1) ? dis[i + 1][j] : range;\n                    int rightCell = (j < matrix[0].length - 1) ? dis[i][j + 1] : range;\n                    dis[i][j] = Math.min(Math.min(downCell, rightCell) + 1, dis[i][j]);\n                }\n            }\n        }\n        \n        return dis;\n    }\n\n}\n"
  },
  {
    "path": "src/ZigzagIterator281.java",
    "content": "/**\n * Given two 1d vectors, implement an iterator to return their elements alternately.\n * \n * Example:\n * Input:\n * v1 = [1,2]\n * v2 = [3,4,5,6] \n * Output: [1,3,2,4,5,6]\n * Explanation: By calling next repeatedly until hasNext returns false, \n *              the order of elements returned by next should be: [1,3,2,4,5,6].\n * \n * Follow up: What if you are given k 1d vectors? How well can your code be\n * extended to such cases?\n * \n * Clarification for the follow up question:\n * The \"Zigzag\" order is not clearly defined and is ambiguous for k > 2 cases.\n * If \"Zigzag\" does not look right to you, replace \"Zigzag\" with \"Cyclic\".\n * \n * For example:\n * Input:\n * [1,2,3]\n * [4,5,6,7]\n * [8,9]\n * Output: [1,4,8,2,5,9,3,6,7].\n */\n\npublic class ZigzagIterator281 {\n    class ZigzagIterator {\n        private int total;\n        private int k;\n        private int pos = 0;\n        private int index = 0;\n        private List<Integer>[] cache;\n        \n        public ZigzagIterator(List<Integer> v1, List<Integer> v2) {\n            this.cache = new List[2];\n            this.cache[0] = v1;\n            this.cache[1] = v2;\n            this.total = v1.size() + v2.size();\n            this.k = 2;\n        }\n      \n        public int next() {\n            int x = this.index % k;\n            int y = this.index / k;\n            while (y >= this.cache[x].size()) {\n                this.index++;\n                x = this.index % k;\n                y = this.index / k;\n            }\n            int res = this.cache[x].get(y);\n            this.index++;\n            this.pos++;\n            return res;\n        }\n      \n        public boolean hasNext() {\n            return this.pos < this.total;\n        }\n    }\n\n    /**\n     * https://leetcode.com/problems/zigzag-iterator/discuss/71779/Simple-Java-solution-for-K-vector\n     */\n    class ZigzagIterator2 {\n        LinkedList<Iterator> list;\n        public ZigzagIterator(List<Integer> v1, List<Integer> v2) {\n            list = new LinkedList<Iterator>();\n            if(!v1.isEmpty()) list.add(v1.iterator());\n            if(!v2.isEmpty()) list.add(v2.iterator());\n        }\n    \n        public int next() {\n            Iterator poll = list.remove();\n            int result = (Integer)poll.next();\n            if(poll.hasNext()) list.add(poll);\n            return result;\n        }\n    \n        public boolean hasNext() {\n            return !list.isEmpty();\n        }\n    }\n\n    /**\n     * https://leetcode.com/problems/zigzag-iterator/discuss/71781/Short-Java-O(1)-space\n     */\n    class ZigzagIterator3 {\n        private Iterator<Integer> i, j, tmp;\n    \n        public ZigzagIterator(List<Integer> v1, List<Integer> v2) {\n            i = v2.iterator();\n            j = v1.iterator();\n        }\n    \n        public int next() {\n            if (j.hasNext()) { tmp = j; j = i; i = tmp; }\n            return i.next();\n        }\n    \n        public boolean hasNext() {\n            return i.hasNext() || j.hasNext();\n        }\n    }\n\n/**\n * Your ZigzagIterator object will be instantiated and called as such:\n * ZigzagIterator i = new ZigzagIterator(v1, v2);\n * while (i.hasNext()) v[f()] = i.next();\n */\n\n}\n\n"
  },
  {
    "path": "src/data-structures/BinaryIndexedTree.java",
    "content": "/**\n * https://www.topcoder.com/community/competitive-programming/tutorials/binary-indexed-trees/\n * https://www.geeksforgeeks.org/binary-indexed-tree-or-fenwick-tree-2/\n */\n\npublic class BinaryIndexedTree {\n    private int[] tree;\n    private int N;\n\n    public BinaryIndexedTree(int[] nums) {\n        if (nums == null) return;\n        this.N = nums.length;\n        this.tree = new int[N+1];\n        constructBIT(nums);\n    }\n\n    public BinaryIndexedTree(int N) {\n        this.N = N;\n        this.tree = new int[N+1];\n    }\n\n    private void constructBIT(int[] nums) {\n        int N = nums.length;\n        for (int i=0; i<N; i++) {\n            update(i, nums[i]);\n        }\n    }\n\n    public void update(int i, int delta) {\n        int k = i + 1;\n        while (k <= this.N) {\n            this.tree[k] += delta;\n            k += lowBit(k);\n        }\n    }\n\n    public int query(int i) {\n        int k = i + 1;\n        int res = 0;\n        while (k > 0) {\n            res += this.tree[k];\n            k -= lowBit(k);\n        }\n        return res;\n    }\n\n    private int lowBit(int x) {\n        return x & (-x);\n    }\n\n}\n"
  },
  {
    "path": "src/data-structures/BinarySearchTree.java",
    "content": "public class BinarySearchTree {\n    private Node root;\n\n    BinarySearchTree() { \n    }\n\n    public Node search(int x) {\n        return search(this.root, x);\n        // return searchIteratively(this.root, x);\n    }\n\n    private Node search(Node node, int x) {\n        if (node == null || node.val == x) return node;\n        if (node.val > x) {\n            return search(node.left, x);\n        } else {\n            return search(node.right, x);\n        }\n    }\n\n    private Node searchIteratively(Node node, int x) {\n        Node res = node;\n        while (res != null && res.val != x) {\n            if (res.val > x) {\n                res = res.left;\n            } else {\n                res = res.right;\n            }\n        }\n        return res;\n    }\n\n\n    public void insert(int x) {\n        this.root = insert(this.root, x);\n        // this.root = insertIteratively(this.root, x);\n    }\n\n    public Node insert(Node node, int x) {\n        if (node == null) return new Node(x);\n        if (node.val > x) {\n            node.left = insert(node.left, x);\n        } else if (node.val < x) {\n            node.right = insert(node.right, x);\n        }\n        return node;\n    }\n\n    public Node insertIteratively(Node node, int x) {\n        Node newNode = new Node(x);\n        if (node == null) return newNode;\n        Node res = node;\n        while (res != null && res.val != x) {\n            if (res.val > x) {\n                if (res.left == null) {\n                    res.left = newNode;\n                } else {\n                    res = res.left;\n                }\n            } else {\n                if (res.right == null) {\n                    res.right = newNode;\n                } else {\n                    res = res.right;\n                }\n            }\n        }\n        return node;\n    }\n\n    /**\n     * 1) Node to be deleted is leaf: Simply remove from the tree.\n     * \n     * 2) Node to be deleted has only one child: Copy the child to the node and\n     * delete the child\n     * \n     * 3) Node to be deleted has two children: Find inorder successor of the node.\n     * Copy contents of the inorder successor to the node and delete the inorder\n     * successor. Note that inorder predecessor can also be used.\n     * \n     * The important thing to note is, inorder successor is needed only when right\n     * child is not empty. In this particular case, inorder successor can be\n     * obtained by finding the minimum value in right child of the node.\n     */\n    public void delete(int x) {\n        this.root = delete(this.root, x);\n    }\n\n    public Node delete(Node node, int x) {\n        if (node == null) return null;\n        if (node.val == x) {\n            if (node.left == null) {\n                return node.right;\n            } else if (node.right == null) {\n                return node.left;\n            } else {\n                Node succ = node.right;\n                while (succ.left != null) {\n                    succ = succ.left;\n                }\n                node.val = succ.val;\n                node.right = delete(node.right, node.val);\n            }\n        } else if (node.val > x) {\n            node.left = delete(node.left, x);\n        } else {\n            node.right = delete(node.right, x);\n        }\n        return node;\n    }\n\n    public Node getRoot() {\n        return this.root;\n    }\n\n    class Node {\n        int val;\n        Node left;\n        Node right;\n        Node(int x) {\n            this.val = x;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/data-structures/BinarySearchTreeWithParent.java",
    "content": "/**\n * This class is having two more methods that BinarySearchTree: inorderSuccessor and inorderPredecessor\n */\n\npublic class BinarySearchTreeWithParent {\n    private Node root;\n\n    BinarySearchTree() { \n    }\n\n    public Node search(int x) {\n        return search(this.root, x);\n        // return searchIteratively(this.root, x);\n    }\n\n    private Node search(Node node, int x) {\n        if (node == null || node.val == x) return node;\n        if (node.val > x) {\n            return search(node.left, x);\n        } else {\n            return search(node.right, x);\n        }\n    }\n\n    private Node searchIteratively(Node node, int x) {\n        Node res = node;\n        while (res != null && res.val != x) {\n            if (res.val > x) {\n                res = res.left;\n            } else {\n                res = res.right;\n            }\n        }\n        return res;\n    }\n\n\n    public void insert(int x) {\n        this.root = insert(this.root, x);\n        // this.root = insertIteratively(this.root, x);\n    }\n\n    public Node insert(Node node, int x) {\n        if (node == null) return new Node(x);\n        if (node.val > x) {\n            node.left = insert(node.left, x);\n        } else if (node.val < x) {\n            node.right = insert(node.right, x);\n        }\n        return node;\n    }\n\n    public Node insertIteratively(Node node, int x) {\n        Node newNode = new Node(x);\n        if (node == null) return newNode;\n        Node res = node;\n        while (res != null && res.val != x) {\n            if (res.val > x) {\n                if (res.left == null) {\n                    res.left = newNode;\n                } else {\n                    res = res.left;\n                }\n            } else {\n                if (res.right == null) {\n                    res.right = newNode;\n                } else {\n                    res = res.right;\n                }\n            }\n        }\n        return node;\n    }\n\n    /**\n     * 1) Node to be deleted is leaf: Simply remove from the tree.\n     * \n     * 2) Node to be deleted has only one child: Copy the child to the node and\n     * delete the child\n     * \n     * 3) Node to be deleted has two children: Find inorder successor of the node.\n     * Copy contents of the inorder successor to the node and delete the inorder\n     * successor. Note that inorder predecessor can also be used.\n     * \n     * The important thing to note is, inorder successor is needed only when right\n     * child is not empty. In this particular case, inorder successor can be\n     * obtained by finding the minimum value in right child of the node.\n     */\n    public void delete(int x) {\n        this.root = delete(this.root, x);\n    }\n\n    public Node delete(Node node, int x) {\n        if (node == null) return null;\n        if (node.val == x) {\n            if (node.left == null) {\n                return node.right;\n            } else if (node.right == null) {\n                return node.left;\n            } else {\n                Node succ = node.right;\n                while (succ.left != null) {\n                    succ = succ.left;\n                }\n                node.val = succ.val;\n                node.right = delete(node.right, node.val);\n            }\n        } else if (node.val > x) {\n            node.left = delete(node.left, x);\n        } else {\n            node.right = delete(node.right, x);\n        }\n        return node;\n    }\n\n    public Node getRoot() {\n        return this.root;\n    }\n\n    class Node {\n        int val;\n        Node left;\n        Node right;\n        Node parent;\n\n        Node(int x) {\n            this.val = x;\n        }\n\n        Node(int x, Node p) {\n            this.val = x;\n            this.parent = p;\n        }\n\n        public Node inorderSuccessor() {\n            if (this.right == null) {\n                Node res = this;\n                while (res.parent != null && res.parent.right == res) {\n                    res = res.parent;\n                }\n                return res.parent;\n            } else {\n                Node res = this.right;\n                while (res.left != null) {\n                    res = res.left;\n                }\n                return res;\n            }\n        }\n        \n        public Node inorderPredecessor() {\n            if (this.left == null) {\n                Node res = this;\n                while (res.parent != null && res.parent.left == res) {\n                    res = res.parent;\n                }\n                return res.parent;\n            } else {\n                Node res = this.left;\n                while (res.right != null) {\n                    res = res.right;\n                }\n                return res;\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "src/data-structures/DisjointSet.java",
    "content": "/**\n * A.K.A.: Union-Find with Path Compression and Union by Rank\n */\n\npublic class DisjointSet {\n\n    private int[] parent;\n    private int[] rank;\n\n    public DisjointSet(int v) {\n        this.parent = new int[v];\n        for (int i=0; i<v; i++) {\n            this.parent[i] = i;\n        }\n        this.rank = new int[v];\n    }\n\n    public int find(int x) {\n        if (this.parent[x] != x) {\n            this.parent[x] = find(this.parent[x]);\n        }\n        return this.parent[x];\n    }\n\n    public void union(int x, int y) {\n        int xx = find(x);\n        int yy = find(y);\n\n        if (this.rank[xx] < this.rank[yy]) {\n            this.parent[xx] = yy;\n        } else if (this.rank[xx] > this.rank[yy]) {\n            this.parent[yy] = xx;\n        } else {\n            this.parent[xx] = yy;\n            this.parent[yy]++;\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/data-structures/LFUCache.java",
    "content": "/**\n * \n */\n\npublic class LFUCache {\n    private FreqNode head;\n    private Map<Integer, FreqNode> freqMap = new HashMap<>();\n    private Map<Integer, ItemNode> itemMap = new HashMap<>();\n    private int capacity;\n\n    public LFUCache(int capacity) {\n        this.capacity = capacity;\n        this.head = new FreqNode();\n        this.head.next = this.head;\n        this.head.prev = this.head;\n    }\n\n    public int get(int key) {\n        if (!this.itemMap.containsKey(key)) return -1;\n        ItemNode item = this.itemMap.get(key);\n        updateNodeFreq(item);\n        return item.val;\n    }\n\n    private void updateNodeFreq(ItemNode item) {\n        dislinkNode(item);\n        Integer freq = item.freq;\n        item.freq++;\n        FreqNode currFreqNode = freqMap.get(freq);\n        FreqNode newFreqNode = freqMap.get(freq+1);\n        if (newFreqNode == null) {\n            newFreqNode = new FreqNode(freq+1);\n            freqMap.put(freq+1, newFreqNode);\n            addAfter(currFreqNode, newFreqNode);\n        }\n        addBefore(newFreqNode.itemHead, item);\n\n        if (itemNodeIsEmpty(currFreqNode.itemHead)) {\n            removeNode(currFreqNode);\n        }\n    }\n    \n    private boolean itemNodeIsEmpty(ItemNode node) {\n        return node.next == node;\n    }\n\n    private void removeNode(FreqNode node) {\n        dislinkNode(node);\n        this.freqMap.remove(node.freq);\n    }\n\n    private void removeNode(ItemNode node) {\n        dislinkNode(node);\n        this.itemMap.remove(node.key);\n    }\n\n    private void dislinkNode(FreqNode node) {\n        node.prev.next = node.next;\n        node.next.prev = node.prev;\n    }\n\n    private void dislinkNode(ItemNode node) {\n        node.prev.next = node.next;\n        node.next.prev = node.prev;\n    }\n\n    private void addAfter(FreqNode currNode, FreqNode newNode) {\n        newNode.next = currNode.next;\n        newNode.prev = currNode;\n        currNode.next.prev = newNode;\n        currNode.next = newNode;\n    }\n    \n    private void addAfter(ItemNode currNode, ItemNode newNode) {\n        newNode.next = currNode.next;\n        newNode.prev = currNode;\n        currNode.next.prev = newNode;\n        currNode.next = newNode;\n    }\n\n    private void addBefore(ItemNode currNode, ItemNode newNode) {\n        newNode.next = currNode;\n        newNode.prev = currNode.prev;\n        currNode.prev.next = newNode;\n        currNode.prev = newNode;\n    }\n\n    public void put(int key, int value) {\n        if (this.capacity == 0) return;\n        if (this.itemMap.containsKey(key)) {\n            ItemNode item = this.itemMap.get(key);\n            item.val = value;\n            updateNodeFreq(item);\n            return;\n        }\n\n        if (this.itemMap.size() == this.capacity) {\n            FreqNode first = this.head.next;\n            ItemNode toBeRemoved = first.itemHead.next;\n            removeNode(toBeRemoved);\n            if (itemNodeIsEmpty(first.itemHead)) {\n                removeNode(first);\n            }\n        }\n\n        FreqNode newFreqNode = freqMap.get(1);\n        if (newFreqNode == null) {\n            newFreqNode = new FreqNode(1);\n            freqMap.put(1, newFreqNode);\n            addAfter(this.head, newFreqNode);\n        }\n        ItemNode newItem = new ItemNode(key, value, 1);\n        addBefore(newFreqNode.itemHead, newItem);\n        this.itemMap.put(key, newItem);\n    }\n\n    private ItemNode newItemHead() {\n        ItemNode head = new ItemNode();\n        head.prev = head;\n        head.next = head;\n        return head;\n    }\n\n    class ItemNode extends Node {\n        ItemNode next;\n        ItemNode prev;\n        int key;\n        int val;\n        int freq;\n        ItemNode(int key, int val, int freq) {\n            this.key = key;\n            this.val = val;\n            this.freq = freq;\n        }\n        ItemNode() {\n            this.key = -1;\n            this.val = -1;\n            this.freq = -1;\n        }\n    }\n\n    class FreqNode extends Node {\n        FreqNode next;\n        FreqNode prev;\n        int freq;\n        ItemNode itemHead;\n        FreqNode(int freq) {\n            this.freq = freq;\n            this.itemHead = newItemHead();\n        }\n        FreqNode() {\n            this.freq = -1;\n        }\n    }\n\n    abstract class Node {\n        Node next;\n        Node prev;\n    }\n}\n"
  },
  {
    "path": "src/data-structures/LRUCache.java",
    "content": "/**\n * 146. LRU Cache\n *\n * Design and implement a data structure for Least Recently Used (LRU) cache.\n * https://en.wikipedia.org/wiki/Cache_replacement_policies#LRU\n *\n * It should support the following operations: get and put.\n *\n * get(key) - Get the value (will always be positive) of the key if the key\n *            exists in the cache, otherwise return -1.\n * put(key, value) - Set or insert the value if the key is not already present.\n *                   When the cache reached its capacity, it should invalidate\n *                   the least recently used item before inserting a new item.\n *\n * Follow up:\n * Could you do both operations in O(1) time complexity?\n *\n * Example:\n *\n * LRUCache cache = new LRUCache( 2 ); // capacity\n *\n * cache.put(1, 1);\n * cache.put(2, 2);\n * cache.get(1);       // returns 1\n * cache.put(3, 3);    // evicts key 2\n * cache.get(2);       // returns -1 (not found)\n * cache.put(4, 4);    // evicts key 1\n * cache.get(1);       // returns -1 (not found)\n * cache.get(3);       // returns 3\n * cache.get(4);       // returns 4\n */\n\n/**\n * Your LRUCache object will be instantiated and called as such:\n * LRUCache obj = new LRUCache(capacity);\n * int param_1 = obj.get(key);\n * obj.put(key,value);\n */\n\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\npublic class LRUCache {\n\n    private Map<Integer, Node> map = new HashMap<>();\n    private Node head = new Node(0, 0);\n    private int capacity;\n    \n    public LRUCache(int capacity) {\n        head.next = head;\n        head.prev = head;\n        this.capacity = capacity;\n    }\n    \n    public int get(int key) {\n        Node curr = map.get(key);\n        if (curr == null) {\n            return -1;\n        }\n        \n        delete(curr);\n        moveToEnd(curr);\n        return curr.value;\n    }\n    \n    private void delete(Node node) {\n        node.prev.next = node.next;\n        node.next.prev = node.prev;\n    }\n        \n    private void moveToEnd(Node node) {\n        head.prev.next = node;\n        node.next = head;\n        node.prev = head.prev;\n        head.prev = node;\n    }\n    \n    public void put(int key, int value) {\n        Node curr = map.get(key);\n        if (curr == null) {\n            Node newNode = new Node(key, value);\n            moveToEnd(newNode);\n            map.put(key, newNode);\n            if (map.size() > capacity) {\n                Node toRemove = head.next;\n                delete(toRemove);\n                map.remove(toRemove.key);\n            }\n            return;\n        }\n    \n        curr.value = value;\n        delete(curr);\n        moveToEnd(curr);\n    }\n    \n    class Node {\n        int key;\n        int value;\n        Node next;\n        Node prev;\n        Node (int k, int v) {\n            this.key = k;\n            this.value = v;\n        }\n    }\n}\n"
  },
  {
    "path": "src/data-structures/MinHeap.java",
    "content": "import java.util.NoSuchElementException;\n\npublic class MinHeap {\n\n    private int size;\n    private int capacity;\n    private int[] arr;\n\n    public MinHeap(int capacity) {\n        this.size = 0;\n        this.capacity = capacity;\n        this.arr = new int[capacity];\n    }\n\n    public int getMin() {\n        if (this.size == 0) throw new NoSuchElementException();\n        return this.arr[0];\n    }\n\n    public int extractMin() {\n        if (this.size == 0) throw new NoSuchElementException();\n        if (this.size == 1) {\n            this.size--;\n            return this.arr[0];\n        }\n        int minVal = this.arr[0];\n        this.arr[0] = this.arr[this.size - 1];\n        this.size--;\n        heapify(0);\n        return minVal;\n    }\n\n    private void heapify(int idx) {\n        heapify(this.arr, this.size, idx);\n    }\n\n    private void heapify(int[] A, int size, int idx) {\n        int l = left(idx);\n        int r = right(idx);\n        int minIdx = idx;\n        if (l < size && A[l] < A[minIdx]) minIdx = l;\n        if (r < size && A[r] < A[minIdx]) minIdx = r;\n        if (minIdx != idx) {\n            swap(A, minIdx, idx);\n            heapify(minIdx);\n        }\n    }\n\n    private void swap(int[] A, int i, int j) {\n        int temp = A[i];\n        A[i] = A[j];\n        A[j] = temp;\n    }\n\n    public void decreaseKey(int idx, int x) {\n        if (this.size <= idx) throw new NoSuchElementException();\n        this.arr[idx] = x;\n        popUp(idx);\n    }\n\n\n    public void insert(int x) {\n        if (this.size >= this.capacity) throw new StackOverflowError(); \n        this.arr[this.size++] = x;\n        popUp(this.size - 1);\n    }\n\n    private void popUp(int idx) {\n        int i = idx;\n        while (i > 0 && this.arr[i] < this.arr[parent(i)]) {\n            swap(this.arr, i, parent(i));\n            i = parent(i);\n        }\n    }\n\n    public int delete(int idx) {\n        decreaseKey(idx, Integer.MIN_VALUE);\n        return extractMin();\n    }\n\n\n    public void buildHeap(int[] A) {\n        for (int i = parent(A.length-1); i >= 0; i--) {\n            heapify(A, A.length, i);\n        }\n    }\n\n    // Heap Sort in Descending Order\n    public void sort(int[] A) {\n        buildHeap(A);\n        for (int i = 0; i < A.length; i++) {\n            swap(A, i, A.length - 1);\n            heapify(A, A.length - i - 1, 0);\n        }\n    }\n\n\n    private int parent(int i) {\n        return (i - 1) / 2;\n    }\n\n    private int left(int i) {\n        return i * 2 + 1;\n    }\n\n    private int right(int i) {\n        return i * 2 + 2;\n    }\n\n}\n"
  },
  {
    "path": "src/data-structures/Trie.java",
    "content": "/**\n * 208. Implement Trie (Prefix Tree)\n *\n * Implement a trie with insert, search, and startsWith methods.\n *\n * Note:\n * You may assume that all inputs are consist of lowercase letters a-z.\n */\n\n/**\n * For Recursive version of the Trie implementation, see\n * https://github.com/fluency03/leetcode-java/blob/master/src/ImplementTriePrefixTree208.java\n */\n\npublic class Trie {\n\n    private TrieNode root;\n\n    /** Initialize your data structure here. */\n    public Trie() {\n        root = new TrieNode();\n    }\n\n    /** Inserts a word into the trie. */\n    public void insert(String word) {\n        TrieNode node = root;\n        for (int i = 0; i < word.length(); i++) {\n            char c = word.charAt(i);\n            if (!node.containsKey(c)) {\n                node.put(c, new TrieNode());\n            }\n            node = node.get(c);\n        }\n        node.setLeaf();\n    }\n\n    /** Returns if the word is in the trie. */\n    public boolean search(String word) {\n        TrieNode node = root;\n        for (int i = 0; i < word.length(); i++) {\n            char c = word.charAt(i);\n            if (!node.containsKey(c)) {\n                return false;\n            }\n            node = node.get(c);\n        }\n        return node.isLeaf();\n    }\n\n    /** Returns if there is any word in the trie that starts with the given prefix. */\n    public boolean startsWith(String prefix) {\n        TrieNode node = root;\n        for (int i = 0; i < prefix.length(); i++) {\n            char c = prefix.charAt(i);\n            if (!node.containsKey(c)) {\n                return false;\n            }\n            node = node.get(c);\n        }\n        return true;\n    }\n}\n\n/**\n * Your Trie object will be instantiated and called as such:\n * Trie obj = new Trie();\n * obj.insert(word);\n * boolean param_2 = obj.search(word);\n * boolean param_3 = obj.startsWith(prefix);\n */\n"
  },
  {
    "path": "src/data-structures/TrieNode.java",
    "content": "/**\n * Definition for a trie (prefix tree) node.\n *\n * https://leetcode.com/articles/implement-trie-prefix-tree/\n */\n\npublic class TrieNode {\n\n    // R links to node children\n    private TrieNode[] links;\n\n    private final int R = 26;\n\n    private boolean isLeaf;\n\n    public TrieNode() {\n        links = new TrieNode[R];\n    }\n\n    public boolean containsKey(char c) {\n        return links[c -'a'] != null;\n    }\n    public TrieNode get(char c) {\n        return links[c -'a'];\n    }\n    public void put(char c, TrieNode node) {\n        links[c -'a'] = node;\n    }\n    public void setLeaf() {\n        isLeaf = true;\n    }\n    public boolean isLeaf() {\n        return isLeaf;\n    }\n}\n"
  },
  {
    "path": "src/graph/Dijkstra.java",
    "content": "/**\n * References:\n * https://www.geeksforgeeks.org/greedy-algorithms-set-6-dijkstras-shortest-path-algorithm/\n * https://www.geeksforgeeks.org/greedy-algorithms-set-7-dijkstras-algorithm-for-adjacency-list-representation/\n * https://www.geeksforgeeks.org/printing-paths-dijkstras-shortest-path-algorithm/\n * https://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-using-set-in-stl/\n */\n\n/**\n * All edge weights are non-negative.\n */\npublic class Dijkstra {\n    // Adjacency Matrix Representation\n    /**\n     * Output shortest paths distance from the source to all the vertices.\n     */\n    public int[] shortestDistancesFrom(int[][] graph, int src) {\n        if (graph == null || graph.length == 0 || graph[0].length == 0) return new int[0];\n        int len = graph.length;\n        int[] dist = new int[len];\n        Set<Integer> sptSet = new HashSet[len];\n\n        // initialization\n        for (int i = 0; i < len; i++) {\n            dist[i] = Integer.MAX_VALUE;\n        }\n        dist[src] = 0;\n\n        while (sptSet.size() < len) {\n            int u = extractMin(dist, sptSet);\n            sptSet.add(u);\n\n            for (int v=0; v<len; v++) {\n                // relaxation\n                if (!sptSet.contains(v) && graph[u][v] > 0 &&\n                        dist[u] != Integer.MAX_VALUE &&\n                        dist[u] + graph[u][v] < dist[v]) {\n                    dist[v] = dist[u] + graph[u][v];\n                }\n            }\n        }\n\n        return dist;\n    }\n\n    // This can be optimized by MinHeap\n    private int extractMin(int[] dist, Set<Integer> sptSet) {\n        int minIdx = -1;\n        int minVal = Integer.MAX_VALUE;\n        for (int i=0; i<dist.length; i++) {\n            if (!sptSet.contains(i) && dist[i] < minVal) {\n                minIdx = i;\n                minVal = dist[i];\n            }\n        }\n        return minIdx;\n    }\n\n    /**\n     * Output the shortest path distance from the source to the destination.\n     */\n    public int shortestDistance(int[][] graph, int src, int dest) {\n        if (graph == null || graph.length == 0 || graph[0].length == 0) return new int[0];\n        int len = graph.length;\n        int[] dist = new int[len];\n        Set<Integer> sptSet = new HashSet[len];\n\n        // initialization\n        for (int i = 0; i < len; i++) {\n            dist[i] = Integer.MAX_VALUE;\n        }\n        dist[src] = 0;\n\n        while (sptSet.size() < len) {\n            int u = minDistance(dist, sptSet);\n            // early return when you fidn the target\n            if (u = target) return dist[u];\n            sptSet.add(u);\n\n            for (int v=0; v<len; v++) {\n                // relaxation\n                if (!sptSet.contains(v) && graph[u][v] > 0 &&\n                        dist[u] != Integer.MAX_VALUE &&\n                        dist[u] + graph[u][v] < dist[v]) {\n                    dist[v] = dist[u] + graph[u][v];\n                }\n            }\n        }\n\n        return -1;\n    }\n\n    /**\n     * Output shortest path from the source to the destination.\n     */\n    public List<Integer> shortestPath(int[][] graph, int src, int dest) {\n        if (graph == null || graph.length == 0 || graph[0].length == 0) return new int[0];\n        int len = graph.length;\n        int[] dist = new int[len];\n        int[] parent = new int[len];\n        Set<Integer> sptSet = new HashSet[len];\n\n        // initialization\n        for (int i = 0; i < len; i++) {\n            dist[i] = Integer.MAX_VALUE;\n            parent[i] = i;\n        }\n        dist[src] = 0;\n\n        while (sptSet.size() < len) {\n            int u = extractMin(dist, sptSet);\n            if (u = target) return constructShortestPath(parent, src, dest);\n            sptSet.add(u);\n\n            for (int v=0; v<len; v++) {\n                // relaxation\n                if (!sptSet.contains(v) && graph[u][v] > 0 &&\n                        dist[u] != Integer.MAX_VALUE &&\n                        dist[u] + graph[u][v] < dist[v]) {\n                    dist[v] = dist[u] + graph[u][v];\n                    parent[v] = u;\n                }\n            }\n        }\n\n        return dist;\n    }\n\n    private List<Integer> constructShortestPath(int[] parent, int src, int dest) {\n        LinkedList<Integer> path = new LinkedList<>();\n        path.add(dest);\n        while (path.getFirst() != src) {\n            int head = path.getFirst();\n            if (parent[head] == head) return new LinkedList<>();\n            path.addFirst(parent[head]);\n        }\n        return path;\n    }\n\n}\n"
  },
  {
    "path": "src/graph/README.md",
    "content": "# Graph\n\nReference: https://www.geeksforgeeks.org/graph-data-structure-and-algorithms/\n\n## Representations\n\nAssume the labels are integers from 0 to n.\n\n\n### Adjacency Matrix\n\n```java\npublic class GraphInAdjacencyMatrix {\n    int V;\n    int[][] graph;\n    GraphInAdjacencyMatrix(int v) {\n        this.V = v;\n        this.graph = new int[v][v];\n    }\n}\n```\n\n\n### Adjacency List\n\n```java\npublic class GraphInAdjacencyList {\n    int V;\n    List<Integer>[] graph;\n    GraphInAdjacencyList(int v) {\n        this.V = v;\n        this.graph = new LinkedList[v];\n        for (int i=0; i<v; i++) {\n            this.graph.add(new LinkedList<>());\n        }\n    }\n}\n```\n\n\n### Adjacency Set\n\n```java\npublic class GraphInAdjacencySet {\n    int V;\n    Set<Integer>[] graph;\n    GraphInAdjacencySet(int v) {\n        this.V = v;\n        this.graph = new HashSet[v];\n        for (int i=0; i<v; i++) {\n            this.graph.add(new HashSet<>());\n        }\n    }\n}\n```\n\n\n\n"
  },
  {
    "path": "src/graph/StrongConnectivity.java",
    "content": "/**\n * For Directed Graph. (It is easy for Undirected graph, we can just do a BFS\n * and DFS starting from any vertex. If BFS or DFS visits all vertices, then\n * the given undirected graph is connected.)\n * \n * References:\n * https://www.geeksforgeeks.org/strongly-connected-components/\n * https://www.geeksforgeeks.org/connectivity-in-a-directed-graph/\n * https://www.geeksforgeeks.org/tarjan-algorithm-find-strongly-connected-components/\n */\n\npublic class StrongConnectivity {\n    // Kosaraju's algorithm\n    public boolean isStronglyConnected(Set<Integer>[] graph) {\n        if (graph == null) return false;\n        if (graph.length == 0) return true;\n        int len = graph.length;\n        boolean[] visited = new boolean[len];\n\n        dfs(graph, 0, visited);\n        for (boolean vz: visited) {\n            if (!vz) return false;\n        }\n\n        Set<Integer>[] graphT = transpose(graph);\n        for (int i=0; i<len; i++) visited[i] = false;\n        dfs(graphT, 0, visited);\n        for (boolean vz: visited) {\n            if (!vz) return false;\n        }\n\n        return true;\n    }\n\n    private void dfs(Set<Integer>[] graph, int i, boolean[] visited) {\n        if (visited[i]) return;\n        visited[i] = true;\n        for (int next: graph[i]) {\n            if (!visited[next]) {\n                dfs(graph, next, visited);\n            }\n        }\n    }\n\n    private Set<Integer>[] transpose(Set<Integer>[] graph) {\n        if (graph == null) return null;\n        if (graph.length == 0) return new Set[0];\n\n        int len = graph.length;\n        Set<Integer>[] newGraph = new Set[len];\n        for (int i=0; i<len; i++) newGraph[i] = new HashSet<>();\n        for (int i=0; i<len; i++) {\n            for (int next: graph[i]) {\n                newGraph[next].add(i);\n            }\n        }\n        return newGraph;\n    }\n\n\n    // Kosaraju's algorithm\n    public List<Set<Integer>> stronglyConnectedComponents(Set<Integer>[] graph) {\n        if (graph == null) return null;\n        List<Set<Integer>> res = new ArrayList<>();\n        if (graph.length == 0) return res;\n\n        int len = graph.length;\n        boolean[] visited = new boolean[len];\n        Stack<Integer> stack = new Stack<>();\n\n        for (int i=0; i<len; i++) {\n            if (!visited[i]) {\n                traverseComponent(graph, i, visited, stack);\n            }\n        }\n\n        Set<Integer>[] graphT = transpose(graph);\n        for (int i=0; i<len; i++) visited[i] = false;\n\n        while (!stack.isEmpty()) {\n            int i = stack.pop();\n            if (!visited[i]) {\n                Set<Integer> newC = new HashSet<>();\n                getComponent(graphT, i, visited, newC);\n                res.add(newC);\n            }\n        }\n\n        return res;\n    }\n\n    private void traverseComponent(Set<Integer>[] graph, int i, boolean[] visited, Stack<Integer> stack) {\n        if (visited[i]) return;\n        visited[i] = true;\n        for (int next: graph[i]) {\n            if (!visited[next]) {\n                traverseComponent(graph, next, visited, stack);\n            }\n        }\n        stack.add(i);\n    }\n\n    private void getComponent(Set<Integer>[] graph, int i, boolean[] visited, Set<Integer> res) {\n        if (visited[i]) return;\n        visited[i] = true;\n        res.add(i);\n        for (int next: graph[i]) {\n            if (!visited[next]) {\n                getComponent(graph, next, visited, res);\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "src/graph/TopologicalSort.java",
    "content": "/**\n * For Directed Acyclic Graph (DAG)\n * \n * References:\n * https://www.geeksforgeeks.org/topological-sorting/\n * https://www.geeksforgeeks.org/topological-sorting-indegree-based-solution/\n */\n\npublic class TopologicalSort {\n    public List<Integer> sortByStack(Set<Integer>[] graph) {\n        if (graph == null || graph.length == 0) return new ArrayList<>();\n        int len = graph.length;\n        boolean[] visited = new boolean[len];\n        LinkedList<Integer> ll = new LinkedList<>();\n\n        for (int i=0; i<len; i++) {\n            if (!visited[i]) {\n                sortByStack(graph, i, visited, stack);\n            }\n        }\n        return ll;\n    }\n\n    public void sortByStack(Set<Integer>[] graph, int i, int[] visited, LinkedList<Integer> ll) {\n        if (visited[i]) return;\n        visited[i] = true;\n\n        for (int j: graph[i]) {\n            if (!visited[j]) {\n                sortByStack(graph, j, visited, stack);\n            }\n        }\n\n        ll.addFirst(i);\n    }\n\n\n    public List<Integer> sortByIndegree(Set<Integer>[] graph) {\n        if (graph == null || graph.length == 0) return new ArrayList<>();\n        int len = graph.length;\n        int[] indegree = new int[len];\n        for (int i=0; i<len; i++) {\n            for (int d: graph[i]) {\n                indegree[d]++;\n            }\n        }\n\n        Queue<Integer> q = new LinkedList<>();\n        for (int i=0; i<len; i++) {\n            if (indegree[i] == 0) {\n                q.offer(i);\n            }\n        }\n\n        List<Integer> sorted = new ArrayList<>();\n        int count = 0;\n        while (!q.isEmpty()) {\n            int curr = q.poll();\n            for (int d: graph[curr]) {\n                indegree[d]--;\n                if (indegree[d] == 0) {\n                    q.add(d);\n                }\n            }\n            count++;\n            sorted.add(curr);\n        }\n        if (count != len) return new ArrayList<>();\n        return sorted;\n    }\n\n\n}\n"
  },
  {
    "path": "src/knapsack/CompleteKnapsack.java",
    "content": "/**\n * There are N objects and a bag with capacity of V. Evey type of object can be\n * used with unlimited number of times.\n * The ith object is having costs[i] and weights[i].\n * Find out which objects can be put into the bag in order to have maximum value.\n */\n\n\npublic class CompleteKnapsack {\n\n    /**\n     * dp[i][v] = max{dp[i-1][v], dp[i][v-c[i]] + w[i]}\n     */\n    public int maxValue(int[] costs, int[] weights, int V) {\n        if (costs == null || weights == null) return 0;\n        int N = costs.length;\n        int[][] dp = new int[N + 1][V + 1];\n\n        for (int i=1; i<=N; i++) {\n            for (int v=1; v<=V; v++) {\n                if (v < costs[i-1]) {\n                    dp[i][v] = dp[i-1][v];\n                } else {\n                    dp[i][v] = Math.max(dp[i-1][v], dp[i][v - costs[i-1]] + weights[i-1]);\n                }\n            }\n        }\n        return dp[N][V];\n    }\n\n\n    /**\n     * dp[v] = max{dp[v], dp[v-c[i]] + w[i]}\n     */\n    public int maxValue2(int[] costs, int[] weights, int V) {\n        if (costs == null || weights == null) return 0;\n        int N = costs.length;\n        int[] dp = new int[V + 1];\n\n        for (int i=0; i<N; i++) {\n            for (int v=costs[i]; v<=V; v++) {\n                dp[v] = Math.max(dp[v], dp[v - costs[i]] + weights[i]);\n            }\n        }\n        return dp[V];\n    }\n\n\n    public static void main(String[] args) {\n        CompleteKnapsack slt = new CompleteKnapsack();\n\n        int[] costs = new int[]{};\n        int[] weights = new int[]{};\n        System.out.println(slt.maxValue(costs, weights, 10));\n        System.out.println(slt.maxValue2(costs, weights, 10));\n\n        costs = new int[]{2};\n        weights = new int[]{2};\n        System.out.println(slt.maxValue(costs, weights, 2));\n        System.out.println(slt.maxValue2(costs, weights, 2));\n\n        costs = new int[]{2};\n        weights = new int[]{2};\n        System.out.println(slt.maxValue(costs, weights, 3));\n        System.out.println(slt.maxValue2(costs, weights, 3));\n\n        costs = new int[]{2};\n        weights = new int[]{2};\n        System.out.println(slt.maxValue(costs, weights, 1));\n        System.out.println(slt.maxValue2(costs, weights, 1));\n\n\n\n\n\n    }\n\n\n    // procedure CompletePack(cost,weight)\n    // for v=cost..V\n    //     f[v]=max{f[v],f[v-c[i]]+w[i]}\n\n}\n"
  },
  {
    "path": "src/knapsack/MultipleKnapsack.java",
    "content": "/**\n * There are N objects and a bag with capacity of V.\n * The ith object is having costs[i] and weights[i].\n * The ith object can be used with n[i] times.\n * Find out which objects can be put into the bag in order to have maximum value.\n */\n\npublic class MultipleKnapsack {\n\n    /**\n     * dp[][] = dp[][]\n     */\n    public int maxValue(int[] costs, int[] weights, int[] limits, int V) {\n\n\n\n      \n    }\n  \n\n\n    // procedure MultiplePack(cost,weight,amount)\n    // if cost*amount>=V\n    //     CompletePack(cost,weight)\n    //     return\n    // integer k=1\n    // while k<amount\n    //     ZeroOnePack(k*cost,k*weight)\n    //     amount=amount-k\n    //     k=k*2\n    // ZeroOnePack(amount*cost,amount*weight)\n\n\n}\n"
  },
  {
    "path": "src/knapsack/README.md",
    "content": "# Knapsack Problem\n\nReference: https://www.kancloud.cn/kancloud/pack/70124\n\n| Knapsack Problem |\n|:----------------------------------------------------------------------------------:|\n| [ZeroOneKnapsack](https://github.com/fluency03/leetcode-java/blob/master/src/knapsack/ZeroOneKnapsack.java) |\n| [CompleteKnapsack](https://github.com/fluency03/leetcode-java/blob/master/src/knapsack/CompleteKnapsack.java) |\n\n\n"
  },
  {
    "path": "src/knapsack/ZeroOneKnapsack.java",
    "content": "/**\n * \n */\n\n\npublic class ZeroOneKnapsack {\n\n    /*\n        Q1. V 的起始点为 Ci 还是 0？ Ci 起始是否有效？ 为什么？\n        Q2. V 起始 bound 为 bound = max(V - sum(Ci ... Cn), Ci)。 为什么？\n        Q3. 初始化值，恰好装满背包 vs 没有要求必须把背包装满？\n    */\n\n    /**\n     * dp[i][v] = max{dp[i-1][v], dp[i-1][v-c[i]] + w[i]}\n     */\n    public int maxValue(int[] costs, int[] weights, int V) {\n        if (costs == null || weights == null) return 0;\n        int N = costs.length;\n        int[][] dp = new int[N + 1][V + 1];\n        for (int i=1; i<=N; i++) {\n            for (int v=1; v<=V; v++) {\n                if (v < costs[i-1]) {\n                    dp[i][v] = dp[i-1][v];\n                } else {\n                    dp[i][v] = Math.max(dp[i-1][v], dp[i-1][v - costs[i-1]] + weights[i-1]);\n                }\n            }\n        }\n        return dp[N][V];\n    }\n\n\n    /**\n     * dp[v] = max{dp[v], dp[v-c[i]] + w[i]}\n     */\n    public int maxValue2(int[] costs, int[] weights, int V) {\n        if (costs == null || weights == null) return 0;\n        int N = costs.length;\n        int[] dp = new int[V + 1];\n\n        for (int i=0; i<N; i++) {\n            for (int v=V; v>=costs[i]; v--) {\n                dp[v] = Math.max(dp[v], dp[v - costs[i]] + weights[i]);\n            }\n        }\n        return dp[V];\n    }\n\n\n    public static void main(String[] args) {\n        ZeroOneKnapsack slt = new ZeroOneKnapsack();\n\n        int[] costs = new int[]{10, 20, 30};\n        int[] weights = new int[]{60, 100, 120};\n        System.out.println(slt.maxValue(costs, weights, 50));\n        System.out.println(slt.maxValue2(costs, weights, 50));\n\n        costs = new int[]{10, 20, 30};\n        weights = new int[]{60, 100, 10};\n        System.out.println(slt.maxValue(costs, weights, 50));\n        System.out.println(slt.maxValue2(costs, weights, 50));\n\n        costs = new int[]{2, 2, 6, 5, 4};\n        weights = new int[]{6, 3, 5, 4, 6};\n        System.out.println(slt.maxValue(costs, weights, 10));\n        System.out.println(slt.maxValue2(costs, weights, 10));\n\n        costs = new int[]{2, 2, 6, 5, 4};\n        weights = new int[]{6, 3, 10, 4, 6};\n        System.out.println(slt.maxValue(costs, weights, 10));\n        System.out.println(slt.maxValue2(costs, weights, 10));\n\n        costs = new int[]{5, 5, 5, 5, 4};\n        weights = new int[]{6, 3, 5, 4, 6};\n        System.out.println(slt.maxValue(costs, weights, 10));\n        System.out.println(slt.maxValue2(costs, weights, 10));\n\n        costs = new int[]{2, 2, 6, 5, 4};\n        weights = new int[]{6, 3, 5, 4, 6};\n        System.out.println(slt.maxValue(costs, weights, 10));\n        System.out.println(slt.maxValue2(costs, weights, 10));\n\n        costs = new int[]{};\n        weights = new int[]{};\n        System.out.println(slt.maxValue(costs, weights, 10));\n        System.out.println(slt.maxValue2(costs, weights, 10));\n\n        costs = new int[]{2};\n        weights = new int[]{2};\n        System.out.println(slt.maxValue(costs, weights, 2));\n        System.out.println(slt.maxValue2(costs, weights, 2));\n\n        costs = new int[]{2};\n        weights = new int[]{2};\n        System.out.println(slt.maxValue(costs, weights, 3));\n        System.out.println(slt.maxValue2(costs, weights, 3));\n\n        costs = new int[]{2};\n        weights = new int[]{2};\n        System.out.println(slt.maxValue(costs, weights, 1));\n        System.out.println(slt.maxValue2(costs, weights, 1));\n    }\n\n\n    // for i=1..N\n    // ZeroOnePack(c[i],w[i]);\n    // procedure ZeroOnePack(cost,weight)\n    // for v=V..cost\n    //     f[v]=max{f[v],f[v-cost]+weight}\n\n\n}\n"
  },
  {
    "path": "src/search/BinarySearch.java",
    "content": "/**\n * LinearSearch: search a sorted array by resursively dividing the array into half.\n *\n * Time complexity: O(Logn).\n * Space complexity:\n *    - Recursively: O(Logn).\n *    - Iteratively: O(1).\n *\n * Every time, compare x with the middle element of the array.\n *    - If x matches with the middle element, return the mid index;\n *    - Else if x is greater than the mid element, go to right half of the array;\n *    - Otherwise, go to the left half.\n *\n */\n\n\npublic class BinarySearch {\n    public static int searchRecursively(int arr[], int x) {\n        return binarySearch(arr, 0, arr.length - 1, x);\n    }\n\n    public static int searchIteratively(int arr[], int x) {\n        return binarySearch(arr, x);\n    }\n\n    // Recursively\n    public static int binarySearch(int arr[], int l, int r, int x) {\n        if (r >= l) {\n            int mid = l + (r - l)/2;\n\n            if (arr[mid] == x) return mid;\n\n            if (arr[mid] > x) return binarySearch(arr, l, mid-1, x);\n\n            return binarySearch(arr, mid+1, r, x);\n        }\n\n        return -1;\n    }\n\n    // Iteratively\n    public static int binarySearch(int arr[], int x) {\n        int l = 0;\n        int r = arr.length - 1;\n        while (l <= r) {\n            int m = l + (r-l)/2;\n\n            if (arr[m] == x) return m;\n\n            if (arr[m] > x) {\n                r = m - 1;\n            } else {\n                l = m + 1;\n            }\n        }\n\n        return -1;\n    }\n\n    public static void main(String[] args) {\n        int[] arr = {3, 5, 7, 10, 15, 20};\n        System.out.println(BinarySearch.search(arr, 10));\n        System.out.println(BinarySearch.search(arr, 1));\n    }\n\n}\n"
  },
  {
    "path": "src/search/ExponentialSearch.java",
    "content": "/**\n * ExponentialSearch: 1. Find range where element is present;\n *                    2. Do Binary Search in above found range.\n *\n * Time complexity: O(Logn).\n * Space complexity:\n *    - Recursively: O(Logn).\n *    - Iteratively: O(1).\n *\n *\n * Different from JumpSearch, where every jump is having fixed number of steps,\n * ExponentialSearch is having jumps with exponentially increasing number of steps.\n *\n * The target x will be within the range (i/2, i), where arr[i/2] < x < arr[i].\n *\n */\n\nimport java.util.Arrays;\n\npublic class ExponentialSearch {\n    public static int search(int arr[], int x) {\n        int n = arr.length;\n        if (arr[0] == x) return 0;\n\n        int i = 1;\n        while (i < n && arr[i] <= x) i *= 2;\n\n        return Arrays.binarySearch(arr, i/2, Math.min(i, n), x);\n    }\n\n    public static void main(String[] args) {\n        int[] arr = {3, 5, 7, 10, 15, 20};\n        System.out.println(ExponentialSearch.search(arr, 10));\n        System.out.println(ExponentialSearch.search(arr, 1));\n    }\n\n}\n"
  },
  {
    "path": "src/search/InterpolationSearch.java",
    "content": "/**\n * InterpolationSearch: search x from a sorted array of n uniformly distributed values.\n *\n * Time complexity:\n *    - If elements are uniformly distributed, O(log(logn));\n *    - Worst case: O(n).\n * Space complexity: O(1).\n *\n * The Interpolation Search is an improvement over Binary Search, where the\n * values in a sorted array are uniformly distributed. Instead of always going\n * to the middle element, interpolation search may go to a different location\n * based on the value of value being searched. For example, if the value is\n * closer to the last element, interpolation search is likely to start search\n * toward the end side.\n *\n * To find the position to be searched, instead of\n *    mid = l + (r-l)/2\n * it uses following formula:\n *    pos = lo + [ (hi-lo) / (arr[hi]-arr[Lo]) * (x-arr[lo])]\n *\n */\n\n\npublic class InterpolationSearch {\n    public static int search(int[] arr, int x) {\n        int lo = 0;\n        int hi = arr.length - 1;\n\n        while (lo <= hi && x >= arr[lo] && x <= arr[hi]) {\n            int pos = lo + (((hi-lo)/(arr[hi]-arr[lo]))*(x-arr[lo]));\n\n            if (arr[pos] == x) return pos;\n\n            if (arr[pos] > x) {\n                hi = pos - 1;\n            } else {\n                lo = pos + 1;\n            }\n        }\n        return -1;\n    }\n\n    public static void main(String[] args) {\n        int[] arr = {3, 5, 7, 10, 15, 20};\n        System.out.println(InterpolationSearch.search(arr, 10));\n        System.out.println(InterpolationSearch.search(arr, 1));\n    }\n\n}\n"
  },
  {
    "path": "src/search/JumpSearch.java",
    "content": "/**\n * JumpSearch: search from an sorted array by jumping ahead fixed number of steps every time.\n *\n * Time complexity:\n *    - O(√n). Between Linear Search O(n) and Binary Search O(Logn).\n *    - Wosrt case: (n/m) + m-1, where n is number of elements, m is number of steps every time.\n * Space complexity: O(1).\n *\n * Start from the leftmost element of the array, and jump m number of elements\n * every time then compare x with current element.\n *    - If found, return the index;\n *    - Else if current is less than x, keep jumping;\n *    - Else if current is larger than x, do linear search between last element and current one;\n *    - Otherwise, not found, return -1.\n *\n */\n\n\npublic class JumpSearch {\n    public static int search(int[] arr, int x) {\n        int n = arr.length;\n        int step = (int)Math.floor(Math.sqrt(n));\n\n        int last = 0;\n        int now = step;\n        while (arr[Math.min(now, n)-1] < x) {\n            last = now;\n            now += step;\n            if (last >= n) return -1;\n        }\n\n        while (arr[last] < x) {\n            last++;\n            if (last == Math.min(now, n)) return -1;\n        }\n\n        if (arr[last] == x) return last;\n\n        return -1;\n    }\n\n    public static void main(String[] args) {\n        int[] arr = {3, 5, 7, 10, 15, 20};\n        System.out.println(JumpSearch.search(arr, 10));\n        System.out.println(JumpSearch.search(arr, 1));\n    }\n\n}\n"
  },
  {
    "path": "src/search/LinearSearch.java",
    "content": "/**\n * LinearSearch: search an array of int linearly.\n *\n * Time complexity: O(n).\n * Space complexity: O(1).\n *\n * Start from the leftmost element of the array and one by one compare x with\n * each element.\n *    - If found, return the index;\n *    - Otherwise, not found, return -1.\n *\n */\n\n\npublic class LinearSearch {\n    public static int search(int arr[], int x) {\n        for (int i = 0; i < arr.length; i++) {\n            if (arr[i] == x) return i;\n        }\n\n        return -1;\n    }\n\n    public static void main(String[] args) {\n        int[] arr = {3, 5, 7, 10, 15, 20};\n        System.out.println(LinearSearch.search(arr, 10));\n        System.out.println(LinearSearch.search(arr, 1));\n    }\n\n}\n"
  },
  {
    "path": "src/search/README.md",
    "content": "# search\n\nReference: http://www.geeksforgeeks.org/fundamentals-of-algorithms/#SearchingandSorting\n"
  },
  {
    "path": "src/search/TernarySearch.java",
    "content": "/**\n * LinearSearch: search a sorted array by resursively dividing the array into half.\n *\n * Time complexity: O(Logn).\n * Space complexity:\n *    - Recursively: O(Logn).\n *    - Iteratively: O(1).\n *\n * Every time, compare x with the middle element of the array.\n *    - If x matches with the middle element, return the mid index;\n *    - Else if x is greater than the mid element, go to right half of the array;\n *    - Otherwise, go to the left half.\n *\n */\n\n\npublic class TernarySearch {\n    public static int searchRecursively(int arr[], int x) {\n        return ternarySearch(arr, 0, arr.length - 1, x);\n    }\n\n    public static int searchIteratively(int arr[], int x) {\n        return ternarySearch(arr, x);\n    }\n\n    // Recursively\n    public static int ternarySearch(int arr[], int l, int r, int x) {\n        if (r >= l) {\n            int mid1 = l + (r - l)/3;\n            int mid2 = mid1 + (r - l)/3;\n\n            if (arr[mid1] == x)  return mid1;\n            if (arr[mid2] == x)  return mid2;\n            if (arr[mid1] > x) return ternarySearch(arr, l, mid1-1, x);\n            if (arr[mid2] < x) return ternarySearch(arr, mid2+1, r, x);\n            return ternarySearch(arr, mid1+1, mid2-1, x);\n        }\n        return -1;\n    }\n\n    // Iteratively\n    public static int ternarySearch(int arr[], int x) {\n        int l = 0;\n        int r = arr.length - 1;\n        while (l <= r) {\n            int mid1 = l + (r - l)/3;\n            int mid2 = mid1 + (r - l)/3;\n\n            if (arr[mid1] == x)  return mid1;\n            if (arr[mid2] == x)  return mid2;\n\n            if (arr[mid1] > x) {\n                r = mid1 - 1;\n                continue;\n            }\n\n            if (arr[mid2] < x) {\n                l = mid2 + 1;\n                continue;\n            }\n        }\n\n        return -1;\n    }\n\n    public static void main(String[] args) {\n        int[] arr = {3, 5, 7, 10, 15, 20};\n        System.out.println(TernarySearch.searchIteratively(arr, 10));\n        System.out.println(TernarySearch.searchIteratively(arr, 1));\n    }\n\n}\n"
  },
  {
    "path": "src/sort/BubbleSort.java",
    "content": "/**\n * BubbleSort: sort an array by repeatedly swapping the adjacent elements if\n * they are in wrong order.\n *\n * Worst and Average Case Time Complexity: O(n^2).\n * Best Case Time Complexity: O(n).\n * Space Complexity: O(1)\n *\n */\n\n\nimport java.util.Arrays;\n\npublic class BubbleSort {\n    public static void sort(int[] arr) {\n        for (int i = 0; i < arr.length-1; i++) {\n            for (int j = 0; j < arr.length-i-1; j++)\n                if (arr[j] > arr[j+1]) swap(arr, j, j+1);\n        }\n    }\n\n    public static void sortEarlyStop(int[] arr) {\n        boolean swapped = false;\n        for (int i = 0; i < arr.length-1; i++) {\n            for (int j = 0; j < arr.length-i-1; j++) {\n                if (arr[j] > arr[j+1]) {\n                    swap(arr, j, j+1);\n                    swapped = true;\n                }\n            }\n            if (swapped == false) break;\n        }\n    }\n\n    private static void swap(int[] arr, int i, int j) {\n        int temp = arr[i];\n        arr[i] = arr[j];\n        arr[j] = temp;\n    }\n\n    public static void main(String[] args) {\n        int[] arr1 = {10, 3, 7, 5, 1, 15, 20};\n        BubbleSort.sortEarlyStop(arr1);\n        System.out.println(Arrays.toString(arr1));\n\n        int[] arr2 = {};\n        BubbleSort.sortEarlyStop(arr2);\n        System.out.println(Arrays.toString(arr2));\n\n        int[] arr3 = {10};\n        BubbleSort.sortEarlyStop(arr3);\n        System.out.println(Arrays.toString(arr3));\n    }\n\n}\n"
  },
  {
    "path": "src/sort/BucketSort.java",
    "content": "/**\n * BucketSort: mainly sort an array with elements uniformly distributed over a range.\n *\n * Worst Case Time Complexity: O(n^2).\n * Best and Average Case Time Complexity: O(n + k).\n * Space Complexity: O(n * k).\n *\n */\n\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.ArrayList;\n\n/**\n * http://www.growingwiththeweb.com/2015/06/bucket-sort.html\n */\npublic class BucketSort {\n\n    private static final int DEFAULT_BUCKET_SIZE = 5;\n\n    public static void sort(int[] arr) {\n        bucketSort(arr, DEFAULT_BUCKET_SIZE);\n    }\n\n    public static void bucketSort(int arr[], int size) {\n        if (arr.length == 0) return;\n\n        Integer minValue = arr[0];\n        Integer maxValue = arr[0];\n        for (int i = 1; i < arr.length; i++) {\n            if (arr[i] < minValue) {\n                minValue = arr[i];\n            } else if (arr[i] > maxValue) {\n                maxValue = arr[i];\n            }\n        }\n\n        int bucketCount = (maxValue - minValue) / size + 1;\n        List<List<Integer>> buckets = new ArrayList<List<Integer>>(bucketCount);\n        for (int i = 0; i < bucketCount; i++) {\n            buckets.add(new ArrayList<Integer>());\n        }\n\n        for (int i = 0; i < arr.length; i++) {\n            buckets.get((arr[i] - minValue) / size).add(arr[i]);\n        }\n\n        int currentIndex = 0;\n        for (int i = 0; i < buckets.size(); i++) {\n            Integer[] bucketArray = new Integer[buckets.get(i).size()];\n            bucketArray = buckets.get(i).toArray(bucketArray);\n            InsertionSort.sort(bucketArray);\n            for (int j = 0; j < bucketArray.length; j++) {\n                arr[currentIndex++] = bucketArray[j];\n            }\n        }\n    }\n\n    public static void main(String[] args) {\n        int[] arr1 = {10, 3, 7, 5, 1, 15, 20};\n        BucketSort.sort(arr1);\n        System.out.println(Arrays.toString(arr1));\n\n        int[] arr2 = {};\n        BucketSort.sort(arr2);\n        System.out.println(Arrays.toString(arr2));\n\n        int[] arr3 = {10};\n        BucketSort.sort(arr3);\n        System.out.println(Arrays.toString(arr3));\n    }\n\n}\n"
  },
  {
    "path": "src/sort/CountingSort.java",
    "content": "/**\n * CountingSort: sort an array based on keys between a specific range. It works\n * by counting the number of objects having distinct key values, and based on\n * the counts, calculate the position of each element in the output array.\n *\n * It only works if you already know the range (of the distinct elements) of\n * your input array.\n *\n * Time Complexity: O(n+k).\n * Space Complexity: O(n+k).\n *\n * n is the number of elements in input array and k is the range of input.\n *\n * The following implementation is only working on non-negative keys.\n *\n */\n\nimport java.util.Arrays;\n\npublic class CountingSort {\n    public static void sort(int arr[], int range) {\n        int n = arr.length;\n        int output[] = new int[n];\n        final int R = range;\n\n        int count[] = new int[R];\n        for (int i=0; i<n; ++i)\n            ++count[arr[i]];\n\n        for (int i=1; i<=R-1; ++i)\n            count[i] += count[i-1];\n\n        for (int i = n-1; i>=0; i--) {\n            output[count[arr[i]]-1] = arr[i];\n            --count[arr[i]];\n        }\n\n        for (int i = 0; i<n; ++i)\n            arr[i] = output[i];\n    }\n\n    public static void main(String[] args) {\n        int[] arr1 = {10, 3, 7, 5, 20, 15, 1};\n        CountingSort.sort(arr1, 100);\n        System.out.println(Arrays.toString(arr1));\n\n        int[] arr2 = {};\n        CountingSort.sort(arr2, 100);\n        System.out.println(Arrays.toString(arr2));\n\n        int[] arr3 = {10};\n        CountingSort.sort(arr3, 100);\n        System.out.println(Arrays.toString(arr3));\n    }\n}\n"
  },
  {
    "path": "src/sort/HeapSort.java",
    "content": "/**\n * HeapSort: a sort algorithm based on max heap, where the largest item is\n * stored at the root of the heap.\n *\n * Time Complexity: O(Logn).\n * Space Complexity: O(n).\n *\n */\n\nimport java.util.Arrays;\n\n/**\n * http://www.geeksforgeeks.org/heap-sort/\n */\npublic class HeapSort {\n    public static void sort(int[] arr) {\n        int n = arr.length;\n        for (int i = n/2 - 1; i >= 0; i--)\n            heapify(arr, n, i);\n\n        for (int i=n-1; i>=0; i--) {\n            swap(arr, 0, i);\n            heapify(arr, i, 0);\n        }\n    }\n\n    private static void heapify(int arr[], int n, int i) {\n        int largest = i;\n        int l = 2*i + 1;\n        int r = 2*i + 2;\n\n        if (l < n && arr[l] > arr[largest]) largest = l;\n        if (r < n && arr[r] > arr[largest]) largest = r;\n\n        if (largest != i) {\n            swap(arr, i, largest);\n            heapify(arr, n, largest);\n        }\n    }\n\n    private static void swap(int[] nums, int i, int j) {\n        int temp = nums[i];\n        nums[i] = nums[j];\n        nums[j] = temp;\n    }\n\n    public static void main(String[] args) {\n        int[] arr1 = {10, 3, 7, 5, 20, 15, 1};\n        HeapSort.sort(arr1);\n        System.out.println(Arrays.toString(arr1));\n\n        int[] arr2 = {};\n        HeapSort.sort(arr2);\n        System.out.println(Arrays.toString(arr2));\n\n        int[] arr3 = {10};\n        HeapSort.sort(arr3);\n        System.out.println(Arrays.toString(arr3));\n    }\n\n}\n"
  },
  {
    "path": "src/sort/InsertionSort.java",
    "content": "/**\n * InsertionSort: for every element in the array, insert it into sorted sequence iteratively.\n *\n * Time Complexity: O(n^2).\n * Space Complexity: O(1).\n *\n */\n\n\nimport java.util.Arrays;\n\npublic class InsertionSort {\n    public static void sort(int[] arr) {\n        for (int i=1; i < arr.length; i++) {\n            int curr = arr[i];\n            int j = i-1;\n\n            while (j >= 0 && arr[j] > curr) {\n                arr[j+1] = arr[j];\n                j--;\n            }\n            arr[j+1] = curr;\n        }\n    }\n\n    public static void sort(Integer[] arr) {\n        for (int i=1; i < arr.length; i++) {\n            int curr = arr[i];\n            int j = i-1;\n\n            while (j >= 0 && arr[j] > curr) {\n                arr[j+1] = arr[j];\n                j--;\n            }\n            arr[j+1] = curr;\n        }\n    }\n\n    public static void main(String[] args) {\n        int[] arr1 = {10, 3, 7, 5, 1, 15, 20};\n        InsertionSort.sort(arr1);\n        System.out.println(Arrays.toString(arr1));\n\n        int[] arr2 = {};\n        InsertionSort.sort(arr2);\n        System.out.println(Arrays.toString(arr2));\n\n        int[] arr3 = {10};\n        InsertionSort.sort(arr3);\n        System.out.println(Arrays.toString(arr3));\n    }\n\n}\n"
  },
  {
    "path": "src/sort/MergeSort.java",
    "content": "/**\n * MergeSort: It divides input array in two halves, calls itself for the two\n * halves and then merges the two sorted halves.\n *\n * Time Complexity: O(nLogn) in all 3 cases (worst, average and best).\n * Space Complexity: O(n).\n *\n */\n\nimport java.util.Arrays;\n\npublic class MergeSort {\n    public static void sort(int[] arr) {\n        mergeSort(arr, 0, arr.length-1);\n        // int[] helper = new int[arr.length];\n        // mergeSort(arr, helper, 0, arr.length-1);\n    }\n\n    private static void mergeSort(int[] arr, int l, int r) {\n        if (l >= r) return;\n\n        int m = (l+r)/2;\n        mergeSort(arr, l, m);\n        mergeSort(arr, m+1, r);\n\n        merge(arr, l, m, r);\n    }\n\n    private static void merge(int[] arr, int l, int m, int r) {\n        int len1 = m - l + 1;\n        int len2 = r - m;\n\n        int L[] = new int [len1];\n        int R[] = new int [len2];\n\n        for (int i=0; i < len1; i++)\n            L[i] = arr[l + i];\n        for (int j=0; j < len2; j++)\n            R[j] = arr[m + 1 + j];\n\n        int i = 0;\n        int j = 0;\n        int k = l;\n        while (i < len1 && j < len2) {\n            if (L[i] <= R[j]) {\n                arr[k] = L[i];\n                i++;\n            } else {\n                arr[k] = R[j];\n                j++;\n            }\n            k++;\n        }\n\n        while (i < len1) {\n            arr[k] = L[i];\n            i++;\n            k++;\n        }\n\n        while (j < len2) {\n            arr[k] = R[j];\n            j++;\n            k++;\n        }\n    }\n\n    //\n    private static void mergeSort(int[] arr, int[] helper, int l, int r) {\n        if (l >= r) return;\n\n        int m = (l+r)/2;\n        mergeSort(arr, helper, l, m);\n        mergeSort(arr, helper, m+1, r);\n\n        merge(arr, helper, l, m, r);\n    }\n\n    private static void merge(int[] arr, int[] helper, int l, int m, int r) {\n        for (int i = l; i <= r; i++) {\n            helper[i] = arr[i];\n        }\n\n        int i = l;\n        int j = m + 1;\n        int k = l;\n        while (i <= m && j <= r) {\n            if (helper[i] <= helper[j]) {\n                arr[k] = helper[i];\n                i++;\n            } else {\n                arr[k] = helper[j];\n                j++;\n            }\n            k++;\n        }\n\n        while (i <= m) {\n            arr[k] = helper[i];\n            k++;\n            i++;\n        }\n    }\n\n    public static void main(String[] args) {\n        int[] arr1 = {10, 3, 7, 5, 20, 15, 1};\n        MergeSort.sort(arr1);\n        System.out.println(Arrays.toString(arr1));\n\n        int[] arr2 = {};\n        MergeSort.sort(arr2);\n        System.out.println(Arrays.toString(arr2));\n\n        int[] arr3 = {10};\n        MergeSort.sort(arr3);\n        System.out.println(Arrays.toString(arr3));\n    }\n\n}\n"
  },
  {
    "path": "src/sort/QuickSort.java",
    "content": "/**\n * QuickSort: every time, it picks one element as a pivot and partitions the\n * array to two parts, where the elements of the first part before pivot are\n * always less or equal to the pivot, and the elements of the second part after.\n *\n * Worst Case Time Complexity: O(n^2).\n * Best and Average Case Time Complexity: O(nlogn).\n * Space Complexity: O(n).\n *\n * Different ways of picking the pivot:\n *\n *    - Always pick first element as pivot.\n *    - Always pick last element as pivot (implemented below)\n *    - Pick a random element as pivot.\n *    - Pick median as pivot.\n *\n */\n\nimport java.util.Arrays;\n\npublic class QuickSort {\n    public static void sortRecursively(int[] nums) {\n        quickSortRecursively(nums, 0, nums.length - 1);\n    }\n\n    public static void sortIteratively(int[] nums) {\n        if (nums.length == 0 || nums.length == 1) return;\n        quickSortIteratively(nums, 0, nums.length - 1);\n    }\n\n    private static void quickSortRecursively(int[] nums, int left, int right) {\n        if (left >= right) return;\n\n        int p = partition(nums, left, right);\n        quickSortRecursively(nums, left, p - 1);\n        quickSortRecursively(nums, p + 1, right);\n    }\n\n    private static void quickSortIteratively(int arr[], int l, int h) {\n        int stack[] = new int[h-l+1];\n\n        int top = -1;\n        stack[++top] = l;\n        stack[++top] = h;\n\n        while (top >= 0) {\n            h = stack[top--];\n            l = stack[top--];\n\n            int p = partition(arr, l, h);\n\n            if (p-1 > l) {\n                stack[++top] = l;\n                stack[++top] = p - 1;\n            }\n\n            if (p+1 < h) {\n                stack[++top] = p + 1;\n                stack[++top] = h;\n            }\n       }\n    }\n\n    private static int partition(int[] nums, int left, int right) {\n        int pivot = nums[right];\n        int i = (left - 1);\n        for (int j = left; j < right; j++) {\n            if (nums[j] <= pivot) {\n                i++;\n                swap(nums, i, j);\n            }\n        }\n        swap(nums, i+1, right);\n        return (i + 1);\n    }\n\n\n    private static int partition2(int[] nums, int left, int right) {\n        int pivot = nums[right];\n        int i = left;\n        for (int j=left; j<right; j++) {\n            if (nums[j] <= pivot) {\n                swap(nums, i, j);\n                i++;\n            }\n        }\n        swap(nums, i, right);\n        return i;\n    }\n\n    private static int partition3(int[] nums, int left, int right) {\n        int pivot = nums[left];\n        int i = left+1;\n        int j = right;\n        while (true) {\n            while (i <= j && nums[i] <= pivot) i++;\n            while (i <= j && nums[j] > pivot) j--;\n            if (i >= j) break;\n            swap(nums, i, j);\n        }\n        swap(nums, left, j);\n        return j;\n    }\n\n\n    private static void swap(int[] nums, int i, int j) {\n        int temp = nums[i];\n        nums[i] = nums[j];\n        nums[j] = temp;\n    }\n\n    public static void main(String[] args) {\n        int[] arr1 = {10, 3, 7, 5, 20, 15, 1};\n        QuickSort.sortIteratively(arr1);\n        System.out.println(Arrays.toString(arr1));\n\n        int[] arr2 = {};\n        QuickSort.sortIteratively(arr2);\n        System.out.println(Arrays.toString(arr2));\n\n        int[] arr3 = {10};\n        QuickSort.sortIteratively(arr3);\n        System.out.println(Arrays.toString(arr3));\n    }\n}\n"
  },
  {
    "path": "src/sort/README.md",
    "content": "# sort\n\nReference: http://www.geeksforgeeks.org/fundamentals-of-algorithms/#SearchingandSorting\n"
  },
  {
    "path": "src/sort/RadixSort.java",
    "content": "/**\n * RadixSort: sort an array of integers digit by digit sort starting from least\n * significant digit to most significant digit. For every single digit, counting\n * sort is considered.\n *\n * Time Complexity: O(wn) for n keys which are integers of word size w.\n * Space Complexity: O(w + N).\n *\n */\n\nimport java.util.Arrays;\n\npublic class RadixSort {\n    public static void sort(int[] arr) {\n        radixSort(arr, arr.length);\n    }\n\n    private static void radixSort(int arr[], int n) {\n        int m = getMax(arr, n);\n\n        for (int exp = 1; m/exp > 0; exp *= 10)\n            countSort(arr, n, exp);\n    }\n\n    private static int getMax(int arr[], int n) {\n        int mx = arr[0];\n        for (int i = 1; i < n; i++) {\n            if (arr[i] > mx) mx = arr[i];\n        }\n        return mx;\n    }\n\n    private static void countSort(int arr[], int n, int exp) {\n        int output[] = new int[n];\n        int i;\n        int count[] = new int[10];\n\n        for (i = 0; i < n; i++)\n            count[ (arr[i]/exp)%10 ]++;\n\n        for (i = 1; i < 10; i++)\n            count[i] += count[i-1];\n\n        for (i = n - 1; i >= 0; i--) {\n            output[count[ (arr[i]/exp)%10 ] - 1] = arr[i];\n            count[ (arr[i]/exp)%10 ]--;\n        }\n\n        for (i = 0; i < n; i++)\n            arr[i] = output[i];\n    }\n\n    public static void main(String[] args) {\n        int[] arr1 = {10, 3, 7, 5, 20, 15, 1};\n        MergeSort.sort(arr1);\n        System.out.println(Arrays.toString(arr1));\n\n        int[] arr2 = {};\n        MergeSort.sort(arr2);\n        System.out.println(Arrays.toString(arr2));\n\n        int[] arr3 = {10};\n        MergeSort.sort(arr3);\n        System.out.println(Arrays.toString(arr3));\n    }\n}\n"
  },
  {
    "path": "src/sort/SelectionSort.java",
    "content": "/**\n * SelectionSort: sorts an array by repeatedly finding the minimum element from\n * unsorted part and putting it at the beginning.\n *\n * Time Complexity: O(n^2).\n * Space Complexity: O(1).\n *\n */\n\nimport java.util.Arrays;\n\npublic class SelectionSort {\n    public static void sort(int[] arr) {\n        for (int i=0; i < arr.length-1; i++) {\n            int minIndex = i;\n            for (int j = i+1; j < arr.length-1; j++) {\n                if (arr[j] < arr[minIndex]) minIndex = j;\n            }\n            swap(arr, i, minIndex);\n        }\n    }\n\n    private static void swap(int[] arr, int i, int j) {\n        int temp = arr[i];\n        arr[i] = arr[j];\n        arr[j] = temp;\n    }\n\n    public static void main(String[] args) {\n        int[] arr1 = {10, 3, 7, 5, 1, 15, 20};\n        SelectionSort.sort(arr1);\n        System.out.println(Arrays.toString(arr1));\n\n        int[] arr2 = {};\n        SelectionSort.sort(arr2);\n        System.out.println(Arrays.toString(arr2));\n\n        int[] arr3 = {10};\n        SelectionSort.sort(arr3);\n        System.out.println(Arrays.toString(arr3));\n    }\n\n}\n"
  }
]