├── .gitignore └── src ├── p1 └── sliding │ ├── LongestSubstringKDistinct.java │ ├── LongestSubstringKDistinctAns.java │ ├── MaxSumSubArrayOfSizeK.java │ ├── MaxSumSubArrayOfSizeKAns.java │ ├── MinSizeSubArraySum.java │ ├── MinSizeSubArraySumAns.java │ └── README.md ├── p10 └── subsets │ ├── Permutations.java │ ├── PermutationsAns.java │ ├── README.md │ ├── SubsetWithDuplicates.java │ ├── SubsetWithDuplicatesAns.java │ ├── Subsets.java │ └── SubsetsAns.java ├── p11 └── bisearch │ └── README.md ├── p12 └── bitxor │ └── README.md ├── p13 └── topk │ └── README.md ├── p14 └── kwaymerge │ └── README.md ├── p15 └── 01knapsack │ └── README.md ├── p16 └── topological │ └── README.md ├── p17 └── miscellaneous │ └── README.md ├── p2 └── twopointer │ └── README.md ├── p3 └── fastslow │ └── README.md ├── p4 └── merge │ ├── InsertInterval.java │ ├── InsertIntervalAns.java │ ├── Interval.java │ ├── MergeIntervals.java │ ├── MergeIntervalsAns.java │ ├── README.md │ └── media │ ├── 15806091958144.jpg │ └── 15806101620309.jpg ├── p5 └── cyclicsort │ └── README.md ├── p6 └── linkedlist │ └── README.md ├── p7 └── bfs │ └── README.md ├── p8 └── dfs │ └── README.md └── p9 └── twoheap └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Java template 3 | # Compiled class file 4 | *.class 5 | 6 | # Log file 7 | *.log 8 | 9 | # BlueJ files 10 | *.ctxt 11 | 12 | # Mobile Tools for Java (J2ME) 13 | .mtj.tmp/ 14 | 15 | # Package Files # 16 | *.jar 17 | *.war 18 | *.nar 19 | *.ear 20 | *.zip 21 | *.tar.gz 22 | *.rar 23 | 24 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 25 | hs_err_pid* 26 | 27 | ### JetBrains template 28 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 29 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 30 | 31 | /.idea/ 32 | *.iml 33 | 34 | # User-specific stuff 35 | .idea/**/workspace.xml 36 | .idea/**/tasks.xml 37 | .idea/**/usage.statistics.xml 38 | .idea/**/dictionaries 39 | .idea/**/shelf 40 | 41 | # Generated files 42 | .idea/**/contentModel.xml 43 | 44 | # Sensitive or high-churn files 45 | .idea/**/dataSources/ 46 | .idea/**/dataSources.ids 47 | .idea/**/dataSources.local.xml 48 | .idea/**/sqlDataSources.xml 49 | .idea/**/dynamic.xml 50 | .idea/**/uiDesigner.xml 51 | .idea/**/dbnavigator.xml 52 | 53 | # Gradle 54 | .idea/**/gradle.xml 55 | .idea/**/libraries 56 | 57 | # Gradle and Maven with auto-import 58 | # When using Gradle or Maven with auto-import, you should exclude module files, 59 | # since they will be recreated, and may cause churn. Uncomment if using 60 | # auto-import. 61 | # .idea/artifacts 62 | # .idea/compiler.xml 63 | # .idea/modules.xml 64 | # .idea/*.iml 65 | # .idea/modules 66 | # *.iml 67 | # *.ipr 68 | 69 | # CMake 70 | cmake-build-*/ 71 | 72 | # Mongo Explorer plugin 73 | .idea/**/mongoSettings.xml 74 | 75 | # File-based project format 76 | *.iws 77 | 78 | # IntelliJ 79 | out/ 80 | 81 | # mpeltonen/sbt-idea plugin 82 | .idea_modules/ 83 | 84 | # JIRA plugin 85 | atlassian-ide-plugin.xml 86 | 87 | # Cursive Clojure plugin 88 | .idea/replstate.xml 89 | 90 | # Crashlytics plugin (for Android Studio and IntelliJ) 91 | com_crashlytics_export_strings.xml 92 | crashlytics.properties 93 | crashlytics-build.properties 94 | fabric.properties 95 | 96 | # Editor-based Rest Client 97 | .idea/httpRequests 98 | 99 | # Android studio 3.1+ serialized cache file 100 | .idea/caches/build_file_checksums.ser 101 | 102 | -------------------------------------------------------------------------------- /src/p1/sliding/LongestSubstringKDistinct.java: -------------------------------------------------------------------------------- 1 | package p1.sliding; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * Given a string, find the length of the longest substring in it with no more than K distinct characters. 7 | * 8 | * Example 1: 9 | * 10 | * Input: String="araaci", K=2 11 | * Output: 4 12 | * Explanation: The longest substring with no more than '2' distinct characters is "araa". 13 | * 14 | * Example 2: 15 | * 16 | * Input: String="araaci", K=1 17 | * Output: 2 18 | * Explanation: The longest substring with no more than '1' distinct characters is "aa". 19 | * 20 | * Example 3: 21 | * 22 | * Input: String="cbbebi", K=3 23 | * Output: 5 24 | * Explanation: The longest substrings with no more than '3' distinct characters are "cbbeb" & "bbebi". 25 | */ 26 | public class LongestSubstringKDistinct { 27 | public static int findLength(String str, int k) { 28 | if (str == null || str.length() < k) { 29 | return 0; 30 | } 31 | 32 | int maxLength = 0, windowStart = 0; 33 | HashMap map = new HashMap<>(); 34 | for (int windowEnd = 0; windowEnd < str.length(); windowEnd++) { 35 | char cur = str.charAt(windowEnd); 36 | while (map.size() > k) { 37 | char startStr = str.charAt(windowStart++); 38 | if (map.get(startStr) == 1) { 39 | map.remove(startStr); 40 | } else { 41 | map.put(startStr, map.get(startStr) - 1); 42 | } 43 | } 44 | if (map.size() == k) { 45 | maxLength = Math.max(maxLength, windowEnd - windowStart); 46 | } 47 | map.put(cur, map.containsKey(cur) ? map.get(cur) + 1 : 1); 48 | } 49 | return maxLength; 50 | } 51 | 52 | public static void main(String[] args) { 53 | System.out.println("Length of the longest substring: " + LongestSubstringKDistinct.findLength("araaci", 2)); 54 | System.out.println("Length of the longest substring: " + LongestSubstringKDistinct.findLength("araaci", 1)); 55 | System.out.println("Length of the longest substring: " + LongestSubstringKDistinct.findLength("cbbebi", 3)); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/p1/sliding/LongestSubstringKDistinctAns.java: -------------------------------------------------------------------------------- 1 | package p1.sliding; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class LongestSubstringKDistinctAns { 7 | public static int findLength(String str, int k) { 8 | if (str == null || str.length() == 0 || str.length() < k) 9 | throw new IllegalArgumentException(); 10 | 11 | int windowStart = 0, maxLength = 0; 12 | Map charFrequencyMap = new HashMap<>(); 13 | // in the following loop we'll try to extend the range [windowStart, windowEnd] 14 | for (int windowEnd = 0; windowEnd < str.length(); windowEnd++) { 15 | char rightChar = str.charAt(windowEnd); 16 | charFrequencyMap.put(rightChar, charFrequencyMap.getOrDefault(rightChar, 0) + 1); 17 | // shrink the sliding window, until we are left with 'k' distinct characters in the frequency map 18 | while (charFrequencyMap.size() > k) { 19 | char leftChar = str.charAt(windowStart); 20 | charFrequencyMap.put(leftChar, charFrequencyMap.get(leftChar) - 1); 21 | if (charFrequencyMap.get(leftChar) == 0) { 22 | charFrequencyMap.remove(leftChar); 23 | } 24 | windowStart++; // shrink the window 25 | } 26 | maxLength = Math.max(maxLength, windowEnd - windowStart + 1); // remember the maximum length so far 27 | } 28 | 29 | return maxLength; 30 | } 31 | 32 | public static void main(String[] args) { 33 | System.out.println("Length of the longest substring: " + LongestSubstringKDistinct.findLength("araaci", 2)); 34 | System.out.println("Length of the longest substring: " + LongestSubstringKDistinct.findLength("araaci", 1)); 35 | System.out.println("Length of the longest substring: " + LongestSubstringKDistinct.findLength("cbbebi", 3)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/p1/sliding/MaxSumSubArrayOfSizeK.java: -------------------------------------------------------------------------------- 1 | package p1.sliding; 2 | 3 | /** 4 | * Given an array of positive numbers and a positive number ‘k’, 5 | * find the maximum sum of any contiguous subarray of size ‘k’. 6 | * 7 | * Example 1: 8 | * 9 | * Input: [2, 1, 5, 1, 3, 2], k=3 10 | * Output: 9 11 | * Explanation: Subarray with maximum sum is [5, 1, 3]. 12 | * 13 | * Example 2: 14 | * 15 | * Input: [2, 3, 4, 1, 5], k=2 16 | * Output: 7 17 | * Explanation: Subarray with maximum sum is [3, 4]. 18 | */ 19 | public class MaxSumSubArrayOfSizeK { 20 | public static int findMaxSumSubArray(int k, int[] arr) { 21 | if (k <= 0 || arr == null || arr.length == 0 || arr.length < k) { 22 | return -1; 23 | } 24 | 25 | int res = Integer.MIN_VALUE; 26 | int sum = arr[0]; 27 | for (int i = 1; i < arr.length; i++) { 28 | sum += arr[i]; 29 | if (i >= k) { 30 | sum -= arr[i - k]; 31 | if (sum > res) { 32 | res = sum; 33 | } 34 | } 35 | } 36 | return res; 37 | } 38 | 39 | public static void main(String[] args) { 40 | System.out.println("Maximum sum of a subarray of size K: " 41 | + MaxSumSubArrayOfSizeK.findMaxSumSubArray(3, new int[] { 2, 1, 5, 1, 3, 2 })); 42 | System.out.println("Maximum sum of a subarray of size K: " 43 | + MaxSumSubArrayOfSizeK.findMaxSumSubArray(2, new int[] { 2, 3, 4, 1, 5 })); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/p1/sliding/MaxSumSubArrayOfSizeKAns.java: -------------------------------------------------------------------------------- 1 | package p1.sliding; 2 | 3 | public class MaxSumSubArrayOfSizeKAns { 4 | public static int findMaxSumSubArray(int k, int[] arr) { 5 | int maxSum = 0, windowSum; 6 | for (int i = 0; i <= arr.length - k; i++) { 7 | windowSum = 0; 8 | for (int j = i; j < i + k; j++) { 9 | windowSum += arr[j]; 10 | } 11 | maxSum = Math.max(maxSum, windowSum); 12 | } 13 | 14 | return maxSum; 15 | } 16 | 17 | public static void main(String[] args) { 18 | System.out.println("Maximum sum of a subarray of size K: " 19 | + MaxSumSubArrayOfSizeK.findMaxSumSubArray(3, new int[] { 2, 1, 5, 1, 3, 2 })); 20 | System.out.println("Maximum sum of a subarray of size K: " 21 | + MaxSumSubArrayOfSizeK.findMaxSumSubArray(2, new int[] { 2, 3, 4, 1, 5 })); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/p1/sliding/MinSizeSubArraySum.java: -------------------------------------------------------------------------------- 1 | package p1.sliding; 2 | 3 | /** 4 | * Given an array of positive numbers and a positive number ‘S’, find the length of the 5 | * smallest contiguous subarray whose sum is greater than or equal to ‘S’. Return 0, 6 | * if no such subarray exists. 7 | * 8 | * Example 1: 9 | * 10 | * Input: [2, 1, 5, 2, 3, 2], S=7 11 | * Output: 2 12 | * Explanation: The smallest subarray with a sum great than or equal to '7' is [5, 2]. 13 | * 14 | * Example 2: 15 | * 16 | * Input: [2, 1, 5, 2, 8], S=7 17 | * Output: 1 18 | * Explanation: The smallest subarray with a sum greater than or equal to '7' is [8]. 19 | * 20 | * Example 3: 21 | * 22 | * Input: [3, 4, 1, 1, 6], S=8 23 | * Output: 3 24 | * Explanation: Smallest subarrays with a sum greater than or equal to '8' are [3, 4, 1] or [1, 1, 6]. 25 | */ 26 | public class MinSizeSubArraySum { 27 | public static int findMinSubArray(int S, int[] arr) { 28 | if (arr == null || arr.length == 0) { 29 | return 0; 30 | } 31 | 32 | int res = Integer.MAX_VALUE; 33 | int curBegin = 0; 34 | int sum = arr[0]; 35 | int curEnd = 1; 36 | while (curEnd < arr.length) { 37 | if (sum < S) { 38 | sum += arr[curEnd++]; 39 | } else { 40 | res = Math.min(res, curEnd - curBegin); 41 | sum -= arr[curBegin++]; 42 | } 43 | } 44 | 45 | if (sum < S) { 46 | return 0; 47 | } 48 | while (sum >= S && curBegin < curEnd) { 49 | res = Math.min(res, curEnd - curBegin); 50 | sum -= arr[curBegin++]; 51 | } 52 | return res; 53 | } 54 | 55 | public static void main(String[] args) { 56 | int result = MinSizeSubArraySum.findMinSubArray(7, new int[] { 2, 1, 5, 2, 3, 2 }); 57 | System.out.println("Smallest subarray length: " + result); 58 | result = MinSizeSubArraySum.findMinSubArray(7, new int[] { 2, 1, 5, 2, 8 }); 59 | System.out.println("Smallest subarray length: " + result); 60 | result = MinSizeSubArraySum.findMinSubArray(8, new int[] { 3, 4, 1, 1, 6 }); 61 | System.out.println("Smallest subarray length: " + result); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/p1/sliding/MinSizeSubArraySumAns.java: -------------------------------------------------------------------------------- 1 | package p1.sliding; 2 | 3 | public class MinSizeSubArraySumAns { 4 | public static int findMinSubArray(int S, int[] arr) { 5 | int windowSum = 0, minLength = Integer.MAX_VALUE; 6 | int windowStart = 0; 7 | for (int windowEnd = 0; windowEnd < arr.length; windowEnd++) { 8 | windowSum += arr[windowEnd]; // add the next element 9 | // shrink the window as small as possible until the 'windowSum' is smaller than 'S' 10 | while (windowSum >= S) { 11 | minLength = Math.min(minLength, windowEnd - windowStart + 1); 12 | windowSum -= arr[windowStart]; // subtract the element going out 13 | windowStart++; // slide the window ahead 14 | } 15 | } 16 | 17 | return minLength == Integer.MAX_VALUE ? 0 : minLength; 18 | } 19 | 20 | public static void main(String[] args) { 21 | int result = MinSizeSubArraySumAns.findMinSubArray(7, new int[] { 2, 1, 5, 2, 3, 2 }); 22 | System.out.println("Smallest subarray length: " + result); 23 | result = MinSizeSubArraySum.findMinSubArray(7, new int[] { 2, 1, 5, 2, 8 }); 24 | System.out.println("Smallest subarray length: " + result); 25 | result = MinSizeSubArraySum.findMinSubArray(8, new int[] { 3, 4, 1, 1, 6 }); 26 | System.out.println("Smallest subarray length: " + result); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/p1/sliding/README.md: -------------------------------------------------------------------------------- 1 | # 模式一:滑动窗口 2 | 3 | ## 概述 4 | 5 | 滑动窗口类型的题目经常是用来执行数组或是链表上某个区间(窗口)上的操作。比如找最长的全为1的子数组长度。滑动窗口一般从第一个元素开始,一直往右边一个一个元素挪动。当然了,根据题目要求,我们可能有固定窗口大小的情况,也有窗口的大小变化的情况。 6 | 7 | 8 | 该图中,我们的窗子不断往右一格一个移动 9 | 10 | 题目特点: 11 | - 问题的输入是一些线性数据结构:链表、数组、字符串 12 | - 要求解最长/最短子字符串或是某些特定的长度要求 13 | 14 | 15 | 16 | ## 例题 17 | 18 | ### Maximum Sum Subarray of Size K (easy) 19 | 20 | #### 问题 21 | 22 | Given an array of positive numbers and a positive number ‘k’, find the **maximum sum of any contiguous subarray of size ‘k’.** 23 | 24 | **Example 1:** 25 | 26 | ``` 27 | Input: [2, 1, 5, 1, 3, 2], k=3 28 | Output: 9 29 | Explanation: Subarray with maximum sum is [5, 1, 3]. 30 | ``` 31 | 32 | **Example 2:** 33 | 34 | ``` 35 | Input: [2, 3, 4, 1, 5], k=2 36 | Output: 7 37 | Explanation: Subarray with maximum sum is [3, 4]. 38 | ``` 39 | 40 | #### 题解 41 | 42 | #### 代码 43 | 44 | ### Smallest Subarray with a given sum (easy) 45 | 46 | #### 问题 47 | 48 | #### 题解 49 | 50 | #### 代码 51 | 52 | ### Longest Substring with K Distinct Characters (medium) 53 | 54 | #### 问题 55 | 56 | #### 题解 57 | 58 | #### 代码 59 | 60 | ### Fruits into Baskets (medium) 61 | 62 | #### 问题 63 | 64 | #### 题解 65 | 66 | #### 代码 67 | 68 | ### No-repeat Substring (hard) 69 | 70 | #### 问题 71 | 72 | #### 题解 73 | 74 | #### 代码 75 | 76 | ### Longest Substring with Same Letters after Replacement (hard) 77 | 78 | #### 问题 79 | 80 | #### 题解 81 | 82 | #### 代码 83 | 84 | ### Longest Subarray with Ones after Replacement (hard) 85 | 86 | #### 问题 87 | 88 | #### 题解 89 | 90 | #### 代码 91 | 92 | 93 | ## 练习 94 | 95 | ### Problem Challenge 1 96 | 97 | #### 问题 98 | 99 | #### 题解 100 | 101 | #### 代码 102 | 103 | ### Problem Challenge 2 104 | 105 | #### 问题 106 | 107 | #### 题解 108 | 109 | #### 代码 110 | 111 | ### Problem Challenge 3 112 | 113 | #### 问题 114 | 115 | #### 题解 116 | 117 | #### 代码 118 | 119 | ### Problem Challenge 4 120 | 121 | #### 问题 122 | 123 | #### 题解 124 | 125 | #### 代码 126 | 127 | -------------------------------------------------------------------------------- /src/p10/subsets/Permutations.java: -------------------------------------------------------------------------------- 1 | package p10.subsets; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * Given a set of distinct numbers, find all of its permutations. 7 | * 8 | * Permutation is defined as the re-arranging of the elements of the set. For example, {1, 2, 3} has the following six permutations: 9 | * 10 | * {1, 2, 3} 11 | * {1, 3, 2} 12 | * {2, 1, 3} 13 | * {2, 3, 1} 14 | * {3, 1, 2} 15 | * {3, 2, 1} 16 | * If a set has ‘n’ distinct elements it will have n!n! permutations. 17 | * 18 | * Example 1: 19 | * 20 | * Input: [1,3,5] 21 | * Output: [1,3,5], [1,5,3], [3,1,5], [3,5,1], [5,1,3], [5,3,1] 22 | * 23 | * 24 | * 字典序全排列算法:(只是在这记录一下这个算法,下面并没有使用该算法) 25 | * 26 | * 采用字典序排列生成算法,按照字典序升序一个一个的生成排列,比如对于 [1,2,3],它的生成顺序应为: 27 | * [1,2,3] -> [1,3,2] -> [2,1,3] -> [2,3,1] -> [3,1,2] -> [3,2,1] 28 | * 29 | * 1. 从最右开始,找到第一个升序对中较小的数字,假设为 m; 30 | * 2. 再从最右开始,找到 m 右边比 m 大的数字,假设为 n; 31 | * 3. 将 m 和 n 对调,即 [x1, x2, m, x3, x4, n, x5, x6] -> [x1, x2, n, x3, x4, m, x5, x6]; 32 | * 4. 最后将 n 后面的数字逆序,即 [x1, x2, n, x3, x4, m, x5, x6] -> [x1, x2, n, x6, x5, m, x4, x3]。 33 | * 34 | * [x1, x2, n, x6, x5, m, x4, x3] 就是 [x1, x2, m, x3, x4, n, x5, x6] 的下一个字典序排列。 35 | */ 36 | public class Permutations { 37 | 38 | public static List> findPermutations(int[] nums) { 39 | List> resultList = new ArrayList<>(); 40 | resultList.add(new ArrayList<>()); 41 | for (int i = 0; i < nums.length; i++) { 42 | int size = resultList.size(); 43 | for (int j = 0; j < size; j++) { 44 | List halfResult = resultList.get(0); 45 | for (int k = 0; k <= halfResult.size(); k++) { 46 | List nextResult = new ArrayList<>(halfResult); 47 | nextResult.add(k, nums[i]); 48 | resultList.add(nextResult); 49 | } 50 | resultList.remove(0); 51 | } 52 | } 53 | return resultList; 54 | } 55 | 56 | public static void main(String[] args) { 57 | List> result = Permutations.findPermutations(new int[] { 1, 3, 5 }); 58 | System.out.print("Here are all the permutations: " + result); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/p10/subsets/PermutationsAns.java: -------------------------------------------------------------------------------- 1 | package p10.subsets; 2 | 3 | import java.util.*; 4 | 5 | public class PermutationsAns { 6 | 7 | public static List> findPermutationsAns(int[] nums) { 8 | List> result = new ArrayList<>(); 9 | Queue> PermutationsAns = new LinkedList<>(); 10 | PermutationsAns.add(new ArrayList<>()); 11 | for (int currentNumber : nums) { 12 | // we will take all existing PermutationsAns and add the current number to create new PermutationsAns 13 | int n = PermutationsAns.size(); 14 | for (int i = 0; i < n; i++) { 15 | List oldPermutation = PermutationsAns.poll(); 16 | // create a new permutation by adding the current number at every position 17 | for (int j = 0; j <= oldPermutation.size(); j++) { 18 | List newPermutation = new ArrayList(oldPermutation); 19 | newPermutation.add(j, currentNumber); 20 | if (newPermutation.size() == nums.length) 21 | result.add(newPermutation); 22 | else 23 | PermutationsAns.add(newPermutation); 24 | } 25 | } 26 | } 27 | return result; 28 | } 29 | 30 | public static void main(String[] args) { 31 | List> result = PermutationsAns.findPermutationsAns(new int[] { 1, 3, 5 }); 32 | System.out.print("Here are all the PermutationsAns: " + result); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/p10/subsets/README.md: -------------------------------------------------------------------------------- 1 | # 模式十:子集合 2 | 3 | ## 概述 4 | 5 | 6 | ## 例题 7 | 8 | ### Subsets (easy) 9 | 10 | #### 问题 11 | 12 | #### 题解 13 | 14 | #### 代码 15 | 16 | ### Subsets With Duplicates (easy) 17 | 18 | #### 问题 19 | 20 | #### 题解 21 | 22 | #### 代码 23 | 24 | ### Permutations (medium) 25 | 26 | #### 问题 27 | 28 | #### 题解 29 | 30 | #### 代码 31 | 32 | ### String Permutations by changing case (medium) 33 | 34 | #### 问题 35 | 36 | #### 题解 37 | 38 | #### 代码 39 | 40 | ### Balanced Parentheses (hard) 41 | 42 | #### 问题 43 | 44 | #### 题解 45 | 46 | #### 代码 47 | 48 | ### Unique Generalized Abbreviations (hard) 49 | 50 | #### 问题 51 | 52 | #### 题解 53 | 54 | #### 代码 55 | 56 | ## 练习 57 | 58 | ### Problem Challenge 1 59 | 60 | #### 问题 61 | 62 | #### 题解 63 | 64 | #### 代码 65 | 66 | ### Problem Challenge 2 67 | 68 | #### 问题 69 | 70 | #### 题解 71 | 72 | #### 代码 73 | 74 | ### Problem Challenge 3 75 | 76 | #### 问题 77 | 78 | #### 题解 79 | 80 | #### 代码 81 | -------------------------------------------------------------------------------- /src/p10/subsets/SubsetWithDuplicates.java: -------------------------------------------------------------------------------- 1 | package p10.subsets; 2 | 3 | import java.util.*; 4 | 5 | public class SubsetWithDuplicates { 6 | public static List> findSubsets(int[] nums) { 7 | List> subsets = new ArrayList<>(); 8 | if (nums == null || nums.length == 0) { 9 | return subsets; 10 | } 11 | 12 | Arrays.sort(nums); 13 | 14 | subsets.add(new ArrayList<>()); 15 | subsets.add(Arrays.asList(nums[0])); 16 | for (int i = 1; i < nums.length; i++) { 17 | int n = subsets.size(); 18 | int startIndex = nums[i] != nums[i - 1] ? 0 : n / 2; 19 | for (int j = startIndex; j < n; j++) { 20 | List curList = new ArrayList<>(subsets.get(j)); 21 | curList.add(nums[i]); 22 | subsets.add(curList); 23 | } 24 | } 25 | return subsets; 26 | } 27 | 28 | public static void main(String[] args) { 29 | List> result = SubsetWithDuplicates.findSubsets(new int[] { 1, 3, 3 }); 30 | System.out.println("Here is the list of subsets: " + result); 31 | 32 | try { 33 | Thread.sleep(20000); 34 | } catch (InterruptedException e) { 35 | e.printStackTrace(); 36 | } 37 | 38 | result = SubsetWithDuplicates.findSubsets(new int[] { 1, 5, 3, 3 }); 39 | System.out.println("Here is the list of subsets: " + result); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/p10/subsets/SubsetWithDuplicatesAns.java: -------------------------------------------------------------------------------- 1 | package p10.subsets; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | public class SubsetWithDuplicatesAns { 8 | 9 | public static List> findSubsets(int[] nums) { 10 | // sort the numbers to handle duplicates 11 | Arrays.sort(nums); 12 | List> subsets = new ArrayList<>(); 13 | subsets.add(new ArrayList<>()); 14 | int startIndex = 0, endIndex = 0; 15 | for (int i = 0; i < nums.length; i++) { 16 | startIndex = 0; 17 | // if current and the previous elements are same, create new subsets only from the subsets 18 | // added in the previous step 19 | if (i > 0 && nums[i] == nums[i - 1]) 20 | startIndex = endIndex + 1; 21 | endIndex = subsets.size() - 1; 22 | for (int j = startIndex; j <= endIndex; j++) { 23 | // create a new subset from the existing subset and add the current element to it 24 | List set = new ArrayList<>(subsets.get(j)); 25 | set.add(nums[i]); 26 | subsets.add(set); 27 | } 28 | } 29 | return subsets; 30 | } 31 | 32 | public static void main(String[] args) { 33 | List> result = SubsetWithDuplicatesAns.findSubsets(new int[] { 1, 3, 3 }); 34 | System.out.println("Here is the list of subsets: " + result); 35 | 36 | result = SubsetWithDuplicatesAns.findSubsets(new int[] { 1, 5, 3, 3 }); 37 | System.out.println("Here is the list of subsets: " + result); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/p10/subsets/Subsets.java: -------------------------------------------------------------------------------- 1 | package p10.subsets; 2 | 3 | import java.util.*; 4 | 5 | public class Subsets { 6 | 7 | public static List> findSubsets(int[] nums) { 8 | List> subsets = new ArrayList<>(); 9 | subsets.add(new ArrayList<>()); 10 | for (int num : nums) { 11 | int curLen = subsets.size(); 12 | for (int i = 0; i < curLen; i++) { 13 | List curList = new ArrayList<>(subsets.get(i)); 14 | curList.add(num); 15 | subsets.add(curList); 16 | } 17 | } 18 | return subsets; 19 | } 20 | 21 | public static void main(String[] args) { 22 | List> result = Subsets.findSubsets(new int[] { 1, 3 }); 23 | System.out.println("Here is the list of subsets: " + result); 24 | 25 | result = Subsets.findSubsets(new int[] { 1, 5, 3 }); 26 | System.out.println("Here is the list of subsets: " + result); 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/p10/subsets/SubsetsAns.java: -------------------------------------------------------------------------------- 1 | package p10.subsets; 2 | 3 | import java.util.*; 4 | 5 | class SubsetsAns { 6 | 7 | public static List> findSubsetsAns(int[] nums) { 8 | List> SubsetsAns = new ArrayList<>(); 9 | // start by adding the empty subset 10 | SubsetsAns.add(new ArrayList<>()); 11 | for (int currentNumber : nums) { 12 | // we will take all existing SubsetsAns and insert the current number in them to create new SubsetsAns 13 | int n = SubsetsAns.size(); 14 | for (int i = 0; i < n; i++) { 15 | // create a new subset from the existing subset and insert the current element to it 16 | List set = new ArrayList<>(SubsetsAns.get(i)); 17 | set.add(currentNumber); 18 | SubsetsAns.add(set); 19 | } 20 | } 21 | return SubsetsAns; 22 | } 23 | 24 | public static void main(String[] args) { 25 | List> result = SubsetsAns.findSubsetsAns(new int[] { 1, 3 }); 26 | System.out.println("Here is the list of SubsetsAns: " + result); 27 | 28 | result = SubsetsAns.findSubsetsAns(new int[] { 1, 5, 3 }); 29 | System.out.println("Here is the list of SubsetsAns: " + result); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/p11/bisearch/README.md: -------------------------------------------------------------------------------- 1 | # 模式十一:二分查找变种 2 | 3 | ## 概述 4 | 5 | 6 | ## 例题 7 | 8 | ### Order-agnostic Binary Search (easy) 9 | 10 | #### 问题 11 | 12 | #### 题解 13 | 14 | #### 代码 15 | 16 | ### Ceiling of a Number (medium) 17 | 18 | #### 问题 19 | 20 | #### 题解 21 | 22 | #### 代码 23 | 24 | ### Next Letter (medium) 25 | 26 | #### 问题 27 | 28 | #### 题解 29 | 30 | #### 代码 31 | 32 | ### Number Range (medium) 33 | 34 | #### 问题 35 | 36 | #### 题解 37 | 38 | #### 代码 39 | 40 | ### Search in a Sorted Infinite Array (medium) 41 | 42 | #### 问题 43 | 44 | #### 题解 45 | 46 | #### 代码 47 | 48 | ### Minimum Difference Element (medium) 49 | 50 | #### 问题 51 | 52 | #### 题解 53 | 54 | #### 代码 55 | 56 | ### Bitonic Array Maximum (easy) 57 | 58 | #### 问题 59 | 60 | #### 题解 61 | 62 | #### 代码 63 | 64 | ## 练习 65 | 66 | ### Problem Challenge 1 67 | 68 | #### 问题 69 | 70 | #### 题解 71 | 72 | #### 代码 73 | 74 | ### Problem Challenge 2 75 | 76 | #### 问题 77 | 78 | #### 题解 79 | 80 | #### 代码 81 | 82 | ### Problem Challenge 3 83 | 84 | #### 问题 85 | 86 | #### 题解 87 | 88 | #### 代码 89 | -------------------------------------------------------------------------------- /src/p12/bitxor/README.md: -------------------------------------------------------------------------------- 1 | # 模式十二:按位异或 2 | 3 | ## 概述 4 | 5 | 6 | ## 例题 7 | 8 | ### Single Number (easy) 9 | 10 | #### 问题 11 | 12 | #### 题解 13 | 14 | #### 代码 15 | 16 | ### Two Single Numbers (medium) 17 | 18 | #### 问题 19 | 20 | #### 题解 21 | 22 | #### 代码 23 | 24 | ### Complement of Base 10 Number (medium) 25 | 26 | #### 问题 27 | 28 | #### 题解 29 | 30 | #### 代码 31 | 32 | ## 练习 33 | 34 | ### Problem Challenge 1 35 | 36 | #### 问题 37 | 38 | #### 题解 39 | 40 | #### 代码 41 | -------------------------------------------------------------------------------- /src/p13/topk/README.md: -------------------------------------------------------------------------------- 1 | # 模式十三:Top K 问题 2 | 3 | ## 概述 4 | 5 | 6 | ## 例题 7 | 8 | ### Top 'K' Numbers (easy) 9 | 10 | #### 问题 11 | 12 | #### 题解 13 | 14 | #### 代码 15 | 16 | ### Kth Smallest Number (easy) 17 | 18 | #### 问题 19 | 20 | #### 题解 21 | 22 | #### 代码 23 | 24 | ### 'K' Closest Points to the Origin (easy) 25 | 26 | #### 问题 27 | 28 | #### 题解 29 | 30 | #### 代码 31 | 32 | ### Connect Ropes (easy) 33 | 34 | #### 问题 35 | 36 | #### 题解 37 | 38 | #### 代码 39 | 40 | ### Top 'K' Frequent Numbers (medium) 41 | 42 | #### 问题 43 | 44 | #### 题解 45 | 46 | #### 代码 47 | 48 | ### Frequency Sort (medium) 49 | 50 | #### 问题 51 | 52 | #### 题解 53 | 54 | #### 代码 55 | 56 | ### Kth Largest Number in a Stream (medium) 57 | 58 | #### 问题 59 | 60 | #### 题解 61 | 62 | #### 代码 63 | 64 | ### 'K' Closest Numbers (medium) 65 | 66 | #### 问题 67 | 68 | #### 题解 69 | 70 | #### 代码 71 | 72 | ### Maximum Distinct Elements (medium) 73 | 74 | #### 问题 75 | 76 | #### 题解 77 | 78 | #### 代码 79 | 80 | ### Sum of Elements (medium) 81 | 82 | #### 问题 83 | 84 | #### 题解 85 | 86 | #### 代码 87 | 88 | ### Rearrange String (hard) 89 | 90 | #### 问题 91 | 92 | #### 题解 93 | 94 | #### 代码 95 | 96 | ## 练习 97 | 98 | ### Problem Challenge 1 99 | 100 | #### 问题 101 | 102 | #### 题解 103 | 104 | #### 代码 105 | 106 | ### Problem Challenge 2 107 | 108 | #### 问题 109 | 110 | #### 题解 111 | 112 | #### 代码 113 | 114 | ### Problem Challenge 3 115 | 116 | #### 问题 117 | 118 | #### 题解 119 | 120 | #### 代码 121 | -------------------------------------------------------------------------------- /src/p14/kwaymerge/README.md: -------------------------------------------------------------------------------- 1 | # 模式十四:K 路归并 2 | 3 | ## 概述 4 | 5 | 6 | ## 例题 7 | 8 | ### Merge K Sorted Lists (medium) 9 | 10 | #### 问题 11 | 12 | #### 题解 13 | 14 | #### 代码 15 | 16 | ### Kth Smallest Number in M Sorted Lists (Medium) 17 | 18 | #### 问题 19 | 20 | #### 题解 21 | 22 | #### 代码 23 | 24 | ### Kth Smallest Number in a Sorted Matrix (Hard) 25 | 26 | #### 问题 27 | 28 | #### 题解 29 | 30 | #### 代码 31 | 32 | ### Smallest Number Range (Hard) 33 | 34 | #### 问题 35 | 36 | #### 题解 37 | 38 | #### 代码 39 | 40 | ## 练习 41 | 42 | ### Problem Challenge 1 43 | 44 | #### 问题 45 | 46 | #### 题解 47 | 48 | #### 代码 49 | -------------------------------------------------------------------------------- /src/p15/01knapsack/README.md: -------------------------------------------------------------------------------- 1 | # 模式十五:0/1 背包(动态规划) 2 | 3 | ## 概述 4 | 5 | 6 | ## 例题 7 | 8 | ### 0/1 Knapsack (medium) 9 | 10 | #### 问题 11 | 12 | #### 题解 13 | 14 | #### 代码 15 | 16 | ### Equal Subset Sum Partition (medium) 17 | 18 | #### 问题 19 | 20 | #### 题解 21 | 22 | #### 代码 23 | 24 | ### Subset Sum (medium) 25 | 26 | #### 问题 27 | 28 | #### 题解 29 | 30 | #### 代码 31 | 32 | ### Minimum Subset Sum Difference (hard) 33 | 34 | #### 问题 35 | 36 | #### 题解 37 | 38 | #### 代码 39 | 40 | ## 练习 41 | 42 | ### Problem Challenge 1 43 | 44 | #### 问题 45 | 46 | #### 题解 47 | 48 | #### 代码 49 | 50 | ### Problem Challenge 2 51 | 52 | #### 问题 53 | 54 | #### 题解 55 | 56 | #### 代码 57 | -------------------------------------------------------------------------------- /src/p16/topological/README.md: -------------------------------------------------------------------------------- 1 | # 模式十六:拓扑排序(图) 2 | 3 | ## 概述 4 | 5 | 6 | ## 例题 7 | 8 | ### Topological Sort (medium) 9 | 10 | #### 问题 11 | 12 | #### 题解 13 | 14 | #### 代码 15 | 16 | ### Tasks Scheduling (medium) 17 | 18 | #### 问题 19 | 20 | #### 题解 21 | 22 | #### 代码 23 | 24 | ### Tasks Scheduling Order (medium) 25 | 26 | #### 问题 27 | 28 | #### 题解 29 | 30 | #### 代码 31 | 32 | ### All Tasks Scheduling Orders (hard) 33 | 34 | #### 问题 35 | 36 | #### 题解 37 | 38 | #### 代码 39 | 40 | ### Alien Dictionary (hard) 41 | 42 | #### 问题 43 | 44 | #### 题解 45 | 46 | #### 代码 47 | 48 | ## 练习 49 | 50 | ### Problem Challenge 1 51 | 52 | #### 问题 53 | 54 | #### 题解 55 | 56 | #### 代码 57 | 58 | ### Problem Challenge 2 59 | 60 | #### 问题 61 | 62 | #### 题解 63 | 64 | #### 代码 65 | -------------------------------------------------------------------------------- /src/p17/miscellaneous/README.md: -------------------------------------------------------------------------------- 1 | # 模式十七:其他 2 | 3 | ## 概述 4 | 5 | 6 | ## 例题 7 | 8 | ### Kth Smallest Number (hard) 9 | 10 | #### 问题 11 | 12 | #### 题解 13 | 14 | #### 代码 15 | 16 | ## 练习 17 | 18 | ### Problem Challenge 1 19 | 20 | #### 问题 21 | 22 | #### 题解 23 | 24 | #### 代码 25 | -------------------------------------------------------------------------------- /src/p2/twopointer/README.md: -------------------------------------------------------------------------------- 1 | # 模式二:双指针 2 | 3 | ## 概述 4 | 5 | 6 | ## 例题 7 | 8 | ### Pair with Target Sum (easy) 9 | 10 | #### 问题 11 | 12 | #### 题解 13 | 14 | #### 代码 15 | 16 | ### Remove Duplicates (easy) 17 | 18 | #### 问题 19 | 20 | #### 题解 21 | 22 | #### 代码 23 | 24 | ### Squaring a Sorted Array (easy) 25 | 26 | #### 问题 27 | 28 | #### 题解 29 | 30 | #### 代码 31 | 32 | ### Triplet Sum to Zero (medium) 33 | 34 | #### 问题 35 | 36 | #### 题解 37 | 38 | #### 代码 39 | 40 | ### Triplet Sum Close to Target (medium) 41 | 42 | #### 问题 43 | 44 | #### 题解 45 | 46 | #### 代码 47 | 48 | ### Triplets with Smaller Sum (medium) 49 | 50 | #### 问题 51 | 52 | #### 题解 53 | 54 | #### 代码 55 | 56 | ### Subarrays with Product Less than a Target (medium) 57 | 58 | #### 问题 59 | 60 | #### 题解 61 | 62 | #### 代码 63 | 64 | ### Dutch National Flag Problem (medium) 65 | 66 | #### 问题 67 | 68 | #### 题解 69 | 70 | #### 代码 71 | 72 | ## 练习 73 | 74 | ### Problem Challenge 1 75 | 76 | #### 问题 77 | 78 | #### 题解 79 | 80 | #### 代码 81 | 82 | ### Problem Challenge 2 83 | 84 | #### 问题 85 | 86 | #### 题解 87 | 88 | #### 代码 89 | 90 | ### Problem Challenge 3 91 | 92 | #### 问题 93 | 94 | #### 题解 95 | 96 | #### 代码 97 | 98 | -------------------------------------------------------------------------------- /src/p3/fastslow/README.md: -------------------------------------------------------------------------------- 1 | # 模式三:快 & 慢指针 2 | 3 | ## 概述 4 | 5 | 6 | ## 例题 7 | 8 | ### LinkedList Cycle (easy) 9 | 10 | #### 问题 11 | 12 | #### 题解 13 | 14 | #### 代码 15 | 16 | ### Start of LinkedList Cycle (medium) 17 | 18 | #### 问题 19 | 20 | #### 题解 21 | 22 | #### 代码 23 | 24 | ### Happy Number (medium) 25 | 26 | #### 问题 27 | 28 | #### 题解 29 | 30 | #### 代码 31 | 32 | ### Middle of the LinkedList (easy) 33 | 34 | #### 问题 35 | 36 | #### 题解 37 | 38 | #### 代码 39 | 40 | ## 练习 41 | 42 | ### Problem Challenge 1 43 | 44 | #### 问题 45 | 46 | #### 题解 47 | 48 | #### 代码 49 | 50 | ### Problem Challenge 2 51 | 52 | #### 问题 53 | 54 | #### 题解 55 | 56 | #### 代码 57 | 58 | ### Problem Challenge 3 59 | 60 | #### 问题 61 | 62 | #### 题解 63 | 64 | #### 代码 65 | -------------------------------------------------------------------------------- /src/p4/merge/InsertInterval.java: -------------------------------------------------------------------------------- 1 | package p4.merge; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | /** 9 | * Given a list of non-overlapping intervals sorted by their start time, insert a given interval at the correct 10 | * position and merge all necessary intervals to produce a list that has only mutually exclusive intervals. 11 | * 12 | * Example 1: 13 | * 14 | * Input: Intervals=[[1,3], [5,7], [8,12]], New Interval=[4,6] 15 | * Output: [[1,3], [4,7], [8,12]] 16 | * Explanation: After insertion, since [4,6] overlaps with [5,7], we merged them into one [4,7]. 17 | * 18 | * Example 2: 19 | * 20 | * Input: Intervals=[[1,3], [5,7], [8,12]], New Interval=[4,10] 21 | * Output: [[1,3], [4,12]] 22 | * Explanation: After insertion, since [4,10] overlaps with [5,7] & [8,12], we merged them into [4,12]. 23 | * 24 | * Example 3: 25 | * 26 | * Input: Intervals=[[2,3],[5,7]], New Interval=[1,4] 27 | * Output: [[1,4], [5,7]] 28 | * Explanation: After insertion, since [1,4] overlaps with [2,3], we merged them into one [1,4]. 29 | */ 30 | public class InsertInterval { 31 | 32 | public static List insert(List intervals, Interval newInterval) { 33 | if (intervals == null || intervals.size() == 0) { 34 | return Arrays.asList(newInterval); 35 | } 36 | 37 | List mergedIntervals = new ArrayList<>(); 38 | int i = 0; 39 | while (i < intervals.size() && intervals.get(i).end < newInterval.start) { 40 | mergedIntervals.add(intervals.get(i++)); 41 | } 42 | 43 | 44 | while (i < intervals.size() && intervals.get(i).start <= newInterval.end) { 45 | newInterval.start = Math.min(newInterval.start, intervals.get(i).start); 46 | newInterval.end = Math.max(newInterval.end, intervals.get(i).end); 47 | i++; 48 | } 49 | mergedIntervals.add(newInterval); 50 | 51 | while (i < intervals.size()) { 52 | mergedIntervals.add(intervals.get(i++)); 53 | } 54 | 55 | return mergedIntervals; 56 | } 57 | 58 | public static void main(String[] args) { 59 | List input = new ArrayList(); 60 | input.add(new Interval(1, 3)); 61 | input.add(new Interval(5, 7)); 62 | input.add(new Interval(8, 12)); 63 | System.out.print("Intervals after inserting the new interval: "); 64 | for (Interval interval : InsertInterval.insert(input, new Interval(4, 6))) 65 | System.out.print("[" + interval.start + "," + interval.end + "] "); 66 | System.out.println(); 67 | 68 | input = new ArrayList(); 69 | input.add(new Interval(1, 3)); 70 | input.add(new Interval(5, 7)); 71 | input.add(new Interval(8, 12)); 72 | System.out.print("Intervals after inserting the new interval: "); 73 | for (Interval interval : InsertInterval.insert(input, new Interval(4, 10))) 74 | System.out.print("[" + interval.start + "," + interval.end + "] "); 75 | System.out.println(); 76 | 77 | input = new ArrayList(); 78 | input.add(new Interval(2, 3)); 79 | input.add(new Interval(5, 7)); 80 | System.out.print("Intervals after inserting the new interval: "); 81 | for (Interval interval : InsertInterval.insert(input, new Interval(1, 4))) 82 | System.out.print("[" + interval.start + "," + interval.end + "] "); 83 | System.out.println(); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/p4/merge/InsertIntervalAns.java: -------------------------------------------------------------------------------- 1 | package p4.merge; 2 | 3 | import java.util.*; 4 | 5 | class InsertIntervalAns { 6 | 7 | public static List insert(List intervals, Interval newInterval) { 8 | if (intervals == null || intervals.isEmpty()) 9 | return Arrays.asList(newInterval); 10 | 11 | List mergedIntervals = new ArrayList<>(); 12 | 13 | int i = 0; 14 | // skip (and add to output) all intervals that come before the 'newInterval' 15 | while (i < intervals.size() && intervals.get(i).end < newInterval.start) 16 | mergedIntervals.add(intervals.get(i++)); 17 | 18 | // merge all intervals that overlap with 'newInterval' 19 | while (i < intervals.size() && intervals.get(i).start <= newInterval.end) { 20 | newInterval.start = Math.min(intervals.get(i).start, newInterval.start); 21 | newInterval.end = Math.max(intervals.get(i).end, newInterval.end); 22 | i++; 23 | } 24 | 25 | // insert the newInterval 26 | mergedIntervals.add(newInterval); 27 | 28 | // add all the remaining intervals to the output 29 | while (i < intervals.size()) 30 | mergedIntervals.add(intervals.get(i++)); 31 | 32 | return mergedIntervals; 33 | } 34 | 35 | public static void main(String[] args) { 36 | List input = new ArrayList(); 37 | input.add(new Interval(1, 3)); 38 | input.add(new Interval(5, 7)); 39 | input.add(new Interval(8, 12)); 40 | System.out.print("Intervals after inserting the new interval: "); 41 | for (Interval interval : InsertIntervalAns.insert(input, new Interval(4, 6))) 42 | System.out.print("[" + interval.start + "," + interval.end + "] "); 43 | System.out.println(); 44 | 45 | input = new ArrayList(); 46 | input.add(new Interval(1, 3)); 47 | input.add(new Interval(5, 7)); 48 | input.add(new Interval(8, 12)); 49 | System.out.print("Intervals after inserting the new interval: "); 50 | for (Interval interval : InsertIntervalAns.insert(input, new Interval(4, 10))) 51 | System.out.print("[" + interval.start + "," + interval.end + "] "); 52 | System.out.println(); 53 | 54 | input = new ArrayList(); 55 | input.add(new Interval(2, 3)); 56 | input.add(new Interval(5, 7)); 57 | System.out.print("Intervals after inserting the new interval: "); 58 | for (Interval interval : InsertIntervalAns.insert(input, new Interval(1, 4))) 59 | System.out.print("[" + interval.start + "," + interval.end + "] "); 60 | System.out.println(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/p4/merge/Interval.java: -------------------------------------------------------------------------------- 1 | package p4.merge; 2 | 3 | class Interval { 4 | int start; 5 | int end; 6 | 7 | public Interval(int start, int end) { 8 | this.start = start; 9 | this.end = end; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/p4/merge/MergeIntervals.java: -------------------------------------------------------------------------------- 1 | package p4.merge; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | 8 | /** 9 | * Given a list of intervals, merge all the overlapping intervals to produce a list that has only mutually exclusive intervals. 10 | * 11 | * Example 1: 12 | * 13 | * Intervals: [[1,4], [2,5], [7,9]] 14 | * Output: [[1,5], [7,9]] 15 | * Explanation: Since the first two intervals [1,4] and [2,5] overlap, we merged them into one [1,5]. 16 | * 17 | * Example 2: 18 | * 19 | * Intervals: [[6,7], [2,4], [5,9]] 20 | * Output: [[2,4], [5,9]] 21 | * Explanation: Since the intervals [6,7] and [5,9] overlap, we merged them into one [5,9]. 22 | * 23 | * Example 3: 24 | * 25 | * Intervals: [[1,4], [2,6], [3,5]] 26 | * Output: [[1,6]] 27 | * Explanation: Since all the given intervals overlap, we merged them into one. 28 | */ 29 | public class MergeIntervals { 30 | public static List merge(List intervals) { 31 | if (intervals.size() < 2) { 32 | return intervals; 33 | } 34 | 35 | Collections.sort(intervals, (a, b) -> Integer.compare(a.start, b.start)); 36 | 37 | List mergedIntervals = new LinkedList(); 38 | mergedIntervals.add(new Interval(intervals.get(0).start, intervals.get(0).start)); 39 | for (Interval interval : intervals) { 40 | Interval cur = mergedIntervals.get(mergedIntervals.size() - 1); 41 | if (interval.start > cur.end) { 42 | mergedIntervals.add(interval); 43 | } else if (interval.end > cur.end) { 44 | cur.end = interval.end; 45 | } 46 | } 47 | return mergedIntervals; 48 | } 49 | 50 | public static void main(String[] args) { 51 | List input = new ArrayList(); 52 | input.add(new Interval(1, 4)); 53 | input.add(new Interval(2, 5)); 54 | input.add(new Interval(7, 9)); 55 | System.out.print("Merged intervals: "); 56 | for (Interval interval : MergeIntervals.merge(input)) 57 | System.out.print("[" + interval.start + "," + interval.end + "] "); 58 | System.out.println(); 59 | 60 | input = new ArrayList(); 61 | input.add(new Interval(6, 7)); 62 | input.add(new Interval(2, 4)); 63 | input.add(new Interval(5, 9)); 64 | System.out.print("Merged intervals: "); 65 | for (Interval interval : MergeIntervals.merge(input)) 66 | System.out.print("[" + interval.start + "," + interval.end + "] "); 67 | System.out.println(); 68 | 69 | input = new ArrayList(); 70 | input.add(new Interval(1, 4)); 71 | input.add(new Interval(2, 6)); 72 | input.add(new Interval(3, 5)); 73 | System.out.print("Merged intervals: "); 74 | for (Interval interval : MergeIntervals.merge(input)) 75 | System.out.print("[" + interval.start + "," + interval.end + "] "); 76 | System.out.println(); 77 | 78 | /* Output: 79 | Merged intervals: [1,5] [7,9] 80 | Merged intervals: [2,4] [5,9] 81 | Merged intervals: [1,6] 82 | */ 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/p4/merge/MergeIntervalsAns.java: -------------------------------------------------------------------------------- 1 | package p4.merge; 2 | 3 | import java.util.*; 4 | 5 | public class MergeIntervalsAns { 6 | 7 | public static List merge(List intervals) { 8 | if (intervals.size() < 2) 9 | return intervals; 10 | 11 | // sort the intervals by start time 12 | Collections.sort(intervals, (a, b) -> Integer.compare(a.start, b.start)); 13 | 14 | List mergedIntervals = new LinkedList(); 15 | Iterator intervalItr = intervals.iterator(); 16 | Interval interval = intervalItr.next(); 17 | int start = interval.start; 18 | int end = interval.end; 19 | 20 | while (intervalItr.hasNext()) { 21 | interval = intervalItr.next(); 22 | if (interval.start <= end) { // overlapping intervals, adjust the 'end' 23 | end = Math.max(interval.end, end); 24 | } else { // non-overlapping interval, add the previous interval and reset 25 | mergedIntervals.add(new Interval(start, end)); 26 | start = interval.start; 27 | end = interval.end; 28 | } 29 | } 30 | // add the last interval 31 | mergedIntervals.add(new Interval(start, end)); 32 | 33 | return mergedIntervals; 34 | } 35 | 36 | public static void main(String[] args) { 37 | List input = new ArrayList(); 38 | input.add(new Interval(1, 4)); 39 | input.add(new Interval(2, 5)); 40 | input.add(new Interval(7, 9)); 41 | System.out.print("Merged intervals: "); 42 | for (Interval interval : MergeIntervalsAns.merge(input)) 43 | System.out.print("[" + interval.start + "," + interval.end + "] "); 44 | System.out.println(); 45 | 46 | input = new ArrayList(); 47 | input.add(new Interval(6, 7)); 48 | input.add(new Interval(2, 4)); 49 | input.add(new Interval(5, 9)); 50 | System.out.print("Merged intervals: "); 51 | for (Interval interval : MergeIntervalsAns.merge(input)) 52 | System.out.print("[" + interval.start + "," + interval.end + "] "); 53 | System.out.println(); 54 | 55 | input = new ArrayList(); 56 | input.add(new Interval(1, 4)); 57 | input.add(new Interval(2, 6)); 58 | input.add(new Interval(3, 5)); 59 | System.out.print("Merged intervals: "); 60 | for (Interval interval : MergeIntervalsAns.merge(input)) 61 | System.out.print("[" + interval.start + "," + interval.end + "] "); 62 | System.out.println(); 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /src/p4/merge/README.md: -------------------------------------------------------------------------------- 1 | # 模式四:合并区间 (Merge Intervals) 2 | 3 | 这类题目一般会给出一组区间数据,如我们给出如下 4 个区间: 4 | 5 | ![](media/15806091958144.jpg) 6 | 7 | 它们之间的位置关系,只有以下 6 种情况: 8 | 9 | ![](media/15806101620309.jpg) 10 | 11 | 而我们做区间合并,就是对以上 6 种情况进行考虑,给出每种情况下的合并算法。 12 | 13 | 牢记这 6 种模式,以防处理时出现遗漏。 -------------------------------------------------------------------------------- /src/p4/merge/media/15806091958144.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangBean/grokking-the-coding-interview/b1fcfb8106b8d3efa69bedc7ff80ca9804692dc4/src/p4/merge/media/15806091958144.jpg -------------------------------------------------------------------------------- /src/p4/merge/media/15806101620309.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TangBean/grokking-the-coding-interview/b1fcfb8106b8d3efa69bedc7ff80ca9804692dc4/src/p4/merge/media/15806101620309.jpg -------------------------------------------------------------------------------- /src/p5/cyclicsort/README.md: -------------------------------------------------------------------------------- 1 | # 模式五:循环排序 2 | 3 | ## 概述 4 | 5 | 6 | ## 例题 7 | 8 | ### Cyclic Sort (easy) 9 | 10 | #### 问题 11 | 12 | #### 题解 13 | 14 | #### 代码 15 | 16 | ### Find the Missing Number (easy) 17 | 18 | #### 问题 19 | 20 | #### 题解 21 | 22 | #### 代码 23 | 24 | ### Find all Missing Numbers (easy) 25 | 26 | #### 问题 27 | 28 | #### 题解 29 | 30 | #### 代码 31 | 32 | ### Find the Duplicate Number (easy) 33 | 34 | #### 问题 35 | 36 | #### 题解 37 | 38 | #### 代码 39 | 40 | ### Find all Duplicate Numbers (easy) 41 | 42 | #### 问题 43 | 44 | #### 题解 45 | 46 | #### 代码 47 | 48 | ## 练习 49 | 50 | ### Problem Challenge 1 51 | 52 | #### 问题 53 | 54 | #### 题解 55 | 56 | #### 代码 57 | 58 | ### Problem Challenge 2 59 | 60 | #### 问题 61 | 62 | #### 题解 63 | 64 | #### 代码 65 | 66 | ### Problem Challenge 3 67 | 68 | #### 问题 69 | 70 | #### 题解 71 | 72 | #### 代码 73 | -------------------------------------------------------------------------------- /src/p6/linkedlist/README.md: -------------------------------------------------------------------------------- 1 | # 模式六:原地翻转链表 2 | 3 | ## 概述 4 | 5 | 6 | ## 例题 7 | 8 | ### Reverse a LinkedList (easy) 9 | 10 | #### 问题 11 | 12 | #### 题解 13 | 14 | #### 代码 15 | 16 | ### Reverse a Sub-list (medium) 17 | 18 | #### 问题 19 | 20 | #### 题解 21 | 22 | #### 代码 23 | 24 | ### Reverse every K-element Sub-list (medium) 25 | 26 | #### 问题 27 | 28 | #### 题解 29 | 30 | #### 代码 31 | 32 | ## 练习 33 | 34 | ### Problem Challenge 1 35 | 36 | #### 问题 37 | 38 | #### 题解 39 | 40 | #### 代码 41 | 42 | ### Problem Challenge 2 43 | 44 | #### 问题 45 | 46 | #### 题解 47 | 48 | #### 代码 49 | -------------------------------------------------------------------------------- /src/p7/bfs/README.md: -------------------------------------------------------------------------------- 1 | # 模式七:BFS(广度优先搜索) 2 | 3 | ## 概述 4 | 5 | 6 | ## 例题 7 | 8 | ### Binary Tree Level Order Traversal (easy) 9 | 10 | #### 问题 11 | 12 | #### 题解 13 | 14 | #### 代码 15 | 16 | ### Reverse Level Order Traversal (easy) 17 | 18 | #### 问题 19 | 20 | #### 题解 21 | 22 | #### 代码 23 | 24 | ### Zigzag Traversal (medium) 25 | 26 | #### 问题 27 | 28 | #### 题解 29 | 30 | #### 代码 31 | 32 | ### Level Averages in a Binary Tree (easy) 33 | 34 | #### 问题 35 | 36 | #### 题解 37 | 38 | #### 代码 39 | 40 | ### Minimum Depth of a Binary Tree (easy) 41 | 42 | #### 问题 43 | 44 | #### 题解 45 | 46 | #### 代码 47 | 48 | ### Level Order Successor (easy) 49 | 50 | #### 问题 51 | 52 | #### 题解 53 | 54 | #### 代码 55 | 56 | ### Connect Level Order Siblings (medium) 57 | 58 | #### 问题 59 | 60 | #### 题解 61 | 62 | #### 代码 63 | 64 | ## 练习 65 | 66 | ### Problem Challenge 1 67 | 68 | #### 问题 69 | 70 | #### 题解 71 | 72 | #### 代码 73 | 74 | ### Problem Challenge 2 75 | 76 | #### 问题 77 | 78 | #### 题解 79 | 80 | #### 代码 81 | 82 | ### Problem Challenge 3 83 | 84 | #### 问题 85 | 86 | #### 题解 87 | 88 | #### 代码 89 | -------------------------------------------------------------------------------- /src/p8/dfs/README.md: -------------------------------------------------------------------------------- 1 | # 模式八:DFS(深度优先搜索) 2 | 3 | ## 概述 4 | 5 | 6 | ## 例题 7 | 8 | ### Binary Tree Path Sum (easy) 9 | 10 | #### 问题 11 | 12 | #### 题解 13 | 14 | #### 代码 15 | 16 | ### All Paths for a Sum (medium) 17 | 18 | #### 问题 19 | 20 | #### 题解 21 | 22 | #### 代码 23 | 24 | ### Sum of Path Numbers (medium) 25 | 26 | #### 问题 27 | 28 | #### 题解 29 | 30 | #### 代码 31 | 32 | ### Path With Given Sequence (medium) 33 | 34 | #### 问题 35 | 36 | #### 题解 37 | 38 | #### 代码 39 | 40 | ### Count Paths for a Sum (medium) 41 | 42 | #### 问题 43 | 44 | #### 题解 45 | 46 | #### 代码 47 | 48 | ## 练习 49 | 50 | ### Problem Challenge 1 51 | 52 | #### 问题 53 | 54 | #### 题解 55 | 56 | #### 代码 57 | 58 | ### Problem Challenge 2 59 | 60 | #### 问题 61 | 62 | #### 题解 63 | 64 | #### 代码 65 | -------------------------------------------------------------------------------- /src/p9/twoheap/README.md: -------------------------------------------------------------------------------- 1 | # 模式九:两个堆 2 | 3 | ## 概述 4 | 5 | 6 | ## 例题 7 | 8 | ### Find the Median of a Number Stream (medium) 9 | 10 | #### 问题 11 | 12 | #### 题解 13 | 14 | #### 代码 15 | 16 | ### Sliding Window Median (hard) 17 | 18 | #### 问题 19 | 20 | #### 题解 21 | 22 | #### 代码 23 | 24 | ### Maximize Capital (hard) 25 | 26 | #### 问题 27 | 28 | #### 题解 29 | 30 | #### 代码 31 | 32 | ## 练习 33 | 34 | ### Problem Challenge 1 35 | 36 | #### 问题 37 | 38 | #### 题解 39 | 40 | #### 代码 41 | --------------------------------------------------------------------------------