From 7e2b425745bbe67848815eb04cf3e993cde92df7 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Wed, 20 Mar 2019 19:44:31 +0800 Subject: [PATCH 01/33] =?UTF-8?q?322coin=E9=97=AE=E9=A2=98=EF=BC=8C?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92=E7=9A=84=E5=BC=80=E5=A7=8B?= =?UTF-8?q?=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + src/Q322CoinChange.java | 112 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 src/Q322CoinChange.java diff --git a/README.md b/README.md index 0baf590..4d99998 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,7 @@ Medium [287](https://leetcode.com/problems/find-the-duplicate-number/description/) | [Find the Duplicate Number](/src/Q287FindtheDuplicateNumber.java) | Array、双指针 | :star: :star: :star: [300](https://leetcode.com/problems/longest-increasing-subsequence/) | [Longest Increasing Subsequence](/src/Q300LongestIncreasingSubsequence.java) | DP、Binary Search | :star: :star: :star: [309](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) | [Best Time to Buy and Sell Stock with Cooldown](/src/Q309BestTimetoBuyandSellStockwithCooldown.java) | DP、状态机 | :star: :star: :star: +[322](https://leetcode.com/problems/coin-change/) | [Coin Change](/src/Q322CoinChange.java) | DP | :star: :star: :star: :star: [334](https://leetcode.com/problems/increasing-triplet-subsequence/) | [Increasing Triplet Subsequence](/src/Q334IncreasingTripletSubsequence.java) | | :star: :star: [337](https://leetcode.com/problems/house-robber-iii/) | [House Robber III](/src/Q337HouseRobberIII.java) | HashMap、DP | :star: :star: :star: [347](https://leetcode.com/problems/top-k-frequent-elements/) | [Top K Frequent Elements](/src/Q347TopKFrequentElements.java) | HashMap | :star: :star: :star: diff --git a/src/Q322CoinChange.java b/src/Q322CoinChange.java new file mode 100644 index 0000000..f404ffb --- /dev/null +++ b/src/Q322CoinChange.java @@ -0,0 +1,112 @@ +/** + * @author ahscuml + * @date 2019/3/20 + * @time 17:58 + */ +public class Q322CoinChange { + public static void main(String[] args) { + int[] coins = {1, 2, 5}; + int amount = 11; + System.out.println(coinChange(coins, amount)); + int[] coins1 = {2}; + int amount1 = 3; + System.out.println(coinChange(coins1, amount1)); + int[] coins2 = {2, 5, 10, 1}; + int amount2 = 27; + System.out.println(coinChange(coins2, amount2)); + } + + /** + * 自己写的方法 + * 带最字的都是动态规划的问题,所以可以从动态规划的角度考虑 + * 首先动态规划是划分成子问题,首先找出子问题 + * dp[i][j] 用 coins[0...j]的硬币,完成价格J的最少个数 + */ + public static int coinChange(int[] coins, int target) { + if (coins == null || coins.length < 1 || target < 1) { + return 0; + } + + int[][] dp = new int[coins.length][target + 1]; + for (int i = 0; i < coins.length; i++) { + dp[i][0] = 0; + } + + for (int i = 1; i < target + 1; i++) { + if (i % coins[0] == 0) { + dp[0][i] = i / coins[0]; + } else { + dp[0][i] = Integer.MAX_VALUE; + } + } + + for (int i = 1; i < coins.length; i++) { + for (int j = 1; j < target + 1; j++) { + // 还要处理j - coins[i] < 0的问题 + if (j - coins[i] < 0) { + dp[i][j] = dp[i - 1][j]; + } else { + // 还要处理Integer.MAX_VALUE的问题 + dp[i][j] = dp[i][j - coins[i]] == Integer.MAX_VALUE + ? dp[i - 1][j] : Math.min(dp[i - 1][j], dp[i][j - coins[i]] + 1); + } + } + } + return dp[coins.length - 1][target] == Integer.MAX_VALUE ? -1 : dp[coins.length - 1][target]; + } + + /** + * 循环的方式 + */ + public int coinChange1(int[] coins, int amount) { + if (amount < 1) return 0; + return helper(coins, amount, new int[amount]); + } + + /** + * 递归的方法,自上而下 + * + * @param coins coins we have + * @param rem remainint to change + * @param count the number of coins + */ + private int helper(int[] coins, int rem, int[] count) { + if (rem < 0) return -1; // not valid + if (rem == 0) return 0; // completed + // already computed, so reuse + if (count[rem - 1] != 0) return count[rem - 1]; + int min = Integer.MAX_VALUE; + for (int coin : coins) { + int res = helper(coins, rem - coin, count); + if (res >= 0 && res < min) + min = res + 1; + } + count[rem - 1] = (min == Integer.MAX_VALUE) ? -1 : min; + return count[rem - 1]; + } + + /** + * 循环的方法,就是我的方法的改版,不过用了空间压缩的方法,只用一个一维数组就搞定了 + * 当前金额sum的最小值是金额为sum - coin的最小值加1 + */ + public int coinChange2(int[] coins, int amount) { + if (amount < 1) return 0; + // 当前amount所需的最少的coin次数,长度是amount + 1 + int[] dp = new int[amount + 1]; + // 当前金额 + int sum = 0; + + while (++sum <= amount) { + // 最少的次数,对于一个数值,遍历完一遍coins才知道min + int min = -1; + for (int coin : coins) { + if (sum >= coin && dp[sum - coin] != -1) { + int temp = dp[sum - coin] + 1; + min = min < 0 ? temp : (temp < min ? temp : min); + } + } + dp[sum] = min; + } + return dp[amount]; + } +} From ce0280988207ee21e67a76ec98d2fd2161668dbe Mon Sep 17 00:00:00 2001 From: ahscuml Date: Wed, 20 Mar 2019 20:45:27 +0800 Subject: [PATCH 02/33] =?UTF-8?q?416=E4=B8=80=E4=B8=AA=E6=95=B0=E7=BB=84?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E4=B8=80=E5=8D=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/junitgenerator-prj-settings.xml | 6 ++ README.md | 5 +- src/Q416PartitionEqualSubsetSum.java | 87 +++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 .idea/junitgenerator-prj-settings.xml create mode 100644 src/Q416PartitionEqualSubsetSum.java diff --git a/.idea/junitgenerator-prj-settings.xml b/.idea/junitgenerator-prj-settings.xml new file mode 100644 index 0000000..d73e792 --- /dev/null +++ b/.idea/junitgenerator-prj-settings.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 4d99998..8b44feb 100644 --- a/README.md +++ b/README.md @@ -109,9 +109,10 @@ Medium [309](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) | [Best Time to Buy and Sell Stock with Cooldown](/src/Q309BestTimetoBuyandSellStockwithCooldown.java) | DP、状态机 | :star: :star: :star: [322](https://leetcode.com/problems/coin-change/) | [Coin Change](/src/Q322CoinChange.java) | DP | :star: :star: :star: :star: [334](https://leetcode.com/problems/increasing-triplet-subsequence/) | [Increasing Triplet Subsequence](/src/Q334IncreasingTripletSubsequence.java) | | :star: :star: -[337](https://leetcode.com/problems/house-robber-iii/) | [House Robber III](/src/Q337HouseRobberIII.java) | HashMap、DP | :star: :star: :star: +[337](https://leetcode.com/problems/house-robber-iii/) | [House Robber III](/src/Q337HouseRobberIII.java) | HashMap、DP | :star: :star: :star: [347](https://leetcode.com/problems/top-k-frequent-elements/) | [Top K Frequent Elements](/src/Q347TopKFrequentElements.java) | HashMap | :star: :star: :star: -[357](https://leetcode.com/problems/count-numbers-with-unique-digits/description/) | [Count Numbers with Unique Digits](/src/Q357CountNumberswithUniqueDigits.java) | DP、回溯 | :star: :star: :star: +[357](https://leetcode.com/problems/count-numbers-with-unique-digits/description/) | [Count Numbers with Unique Digits](/src/Q357CountNumberswithUniqueDigits.java) | DP、回溯 | :star: :star: :star: +[416](https://leetcode.com/problems/partition-equal-subset-sum/) | [Partition Equal Subset Sum](/src/Q416PartitionEqualSubsetSum.java) | DP | :star: :star: :star: :star: [438](https://leetcode.com/problems/find-all-anagrams-in-a-string/) | [Find All Anagrams in a String](/src/Q438FindAllAnagramsinaString.java) | HashTable、滑动窗口 | :star: :star: :star: [442](https://leetcode.com/problems/find-all-duplicates-in-an-array/description/) | [Find All Duplicates in an Array](/src/Q442FindAllDuplicatesinanArray.java) | Array | :star: :star: :star: [526](https://leetcode.com/problems/beautiful-arrangement/description/) | [BeautifulArrangement](/src/Q526BeautifulArrangement.java) | 回溯 | :star: :star: :star: diff --git a/src/Q416PartitionEqualSubsetSum.java b/src/Q416PartitionEqualSubsetSum.java new file mode 100644 index 0000000..a9ccef6 --- /dev/null +++ b/src/Q416PartitionEqualSubsetSum.java @@ -0,0 +1,87 @@ +import java.util.Arrays; + +/** + * Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets + * such that the sum of elements in both subsets is equal. + * + * @author ahscuml + * @date 2019/3/20 + * @time 20:02 + */ +public class Q416PartitionEqualSubsetSum { + public static void main(String[] args) { + int[] nums = {1, 5, 11, 5}; + System.out.println(canPartition(nums)); + System.out.println(canPartition1(nums)); + } + + /** + * 0-1背包问题的变形 类似于coins问题??? + * dp[i][j] means whether the specific sum j can be gotten from the first i numbers. + */ + public static boolean canPartition(int[] nums) { + int sum = 0; + for (int num : nums) { + sum += num; + } + // sum的末位不能是奇数,因为奇数不可能分成两个相等的内容 + if ((sum & 1) == 1) { + return false; + } + sum /= 2; + int n = nums.length; + boolean[][] dp = new boolean[n + 1][sum + 1]; + /** + * ii的地方全填成false? + * */ + for (int i = 0; i < dp.length; i++) { + Arrays.fill(dp[i], false); + } + dp[0][0] = true; + // 和为0的 + for (int i = 1; i < n + 1; i++) { + dp[i][0] = true; + } + // 不使用元素的 + for (int j = 1; j < sum + 1; j++) { + dp[0][j] = false; + } + for (int i = 1; i < n + 1; i++) { + for (int j = 1; j < sum + 1; j++) { + // 不用当前这个元素 + dp[i][j] = dp[i - 1][j]; + // j是sum, + if (j >= nums[i - 1]) { + dp[i][j] = (dp[i][j] || dp[i - 1][j - nums[i - 1]]); + } + } + } + return dp[n][sum]; + } + + /** + * 上面方法的优化,使用一维数组 + * */ + public static boolean canPartition1(int[] nums) { + int sum = 0; + for (int num : nums) { + sum += num; + } + if ((sum & 1) == 1) { + return false; + } + sum /= 2; + boolean[] dp = new boolean[sum + 1]; + // 数组的初始化 + Arrays.fill(dp, false); + dp[0] = true; + for (int num : nums) { + for (int i = sum; i > 0; i--) { + if (i >= num) { + dp[i] = dp[i] || dp[i - num]; + } + } + } + return dp[sum]; + } +} From e687d000de0039cceb62f2d7c512aa6fd7b7ebfb Mon Sep 17 00:00:00 2001 From: ahscuml Date: Thu, 21 Mar 2019 09:19:16 +0800 Subject: [PATCH 03/33] =?UTF-8?q?=E5=A2=9E=E5=8A=A0gitignore=E9=A1=B9?= =?UTF-8?q?=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java.gitignore | 2 ++ src/Q97InterleavingString.java | 37 ++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 java.gitignore create mode 100644 src/Q97InterleavingString.java diff --git a/java.gitignore b/java.gitignore new file mode 100644 index 0000000..f419182 --- /dev/null +++ b/java.gitignore @@ -0,0 +1,2 @@ +*.idea/workspace.xml +*.out/ \ No newline at end of file diff --git a/src/Q97InterleavingString.java b/src/Q97InterleavingString.java new file mode 100644 index 0000000..f957861 --- /dev/null +++ b/src/Q97InterleavingString.java @@ -0,0 +1,37 @@ +/** + * @author ahscuml + * @date 2019/3/16 + * @time 9:00 + */ +public class Q97InterleavingString { + + /** + * DP的方法 + * 首先要明白子问题是什么 + * 空间换时间,空间的意义是什么 + */ + public boolean isInterleave(String s1, String s2, String s3) { + if ((s1.length() + s2.length()) != s3.length()) { + return false; + } + // 需要存储的空间 + boolean[][] matrix = new boolean[s2.length() + 1][s1.length() + 1]; + matrix[0][0] = true; + // 初始化第一行 + for (int i = 1; i < matrix[0].length; i++) { + matrix[0][i] = matrix[0][i - 1] && (s1.charAt(i - 1) == s3.charAt(i - 1)); + } + // 初始化第一列 + for (int i = 1; i < matrix.length; i++) { + matrix[i][0] = matrix[i - 1][0] && (s2.charAt(i - 1) == s3.charAt(i - 1)); + } + // 利用之前的计算填充二维数组 + for (int i = 1; i < matrix.length; i++) { + for (int j = 1; j < matrix[0].length; j++) { + matrix[i][j] = (matrix[i - 1][j] && (s2.charAt(i - 1) == s3.charAt(i + j - 1))) + || (matrix[i][j - 1] && (s1.charAt(j - 1) == s3.charAt(i + j - 1))); + } + } + return matrix[s2.length()][s1.length()]; + } +} From 4262c610efdbec99f7fe5aee00f5c358fa2703ae Mon Sep 17 00:00:00 2001 From: ahscuml Date: Thu, 21 Mar 2019 09:24:08 +0800 Subject: [PATCH 04/33] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BF=BD=E7=95=A5?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java.gitignore | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/java.gitignore b/java.gitignore index f419182..4eecc56 100644 --- a/java.gitignore +++ b/java.gitignore @@ -1,2 +1,26 @@ *.idea/workspace.xml -*.out/ \ No newline at end of file +*.out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* \ No newline at end of file From 6c6ed50e16bc24fab318ddb9701bf8d573130bfc Mon Sep 17 00:00:00 2001 From: ahscuml Date: Thu, 21 Mar 2019 09:39:16 +0800 Subject: [PATCH 05/33] =?UTF-8?q?=E5=A2=9E=E5=8A=A0gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4eecc56 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +*.idea/workspace.xml +*.out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* \ No newline at end of file From 8298dbacf9759936b580c054673ea3681cb26032 Mon Sep 17 00:00:00 2001 From: ahscuml_linux Date: Thu, 21 Mar 2019 12:35:27 +0800 Subject: [PATCH 06/33] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=9B=AE=E5=BD=95?= =?UTF-8?q?=E7=BB=93=E6=9E=84=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../KnapsackProblem => DynamicProgrammin}/Fibonacci.java | 2 +- .../KnapsackProblem => DynamicProgrammin}/Knapsack01.java | 2 +- .../KnapsackProblem => DynamicProgrammin}/MaxPathSum.java | 2 +- .../KnapsackProblem => DynamicProgrammin}/MinCoin.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename src/{DynamicProgramming/KnapsackProblem => DynamicProgrammin}/Fibonacci.java (97%) rename src/{DynamicProgramming/KnapsackProblem => DynamicProgrammin}/Knapsack01.java (81%) rename src/{DynamicProgramming/KnapsackProblem => DynamicProgrammin}/MaxPathSum.java (98%) rename src/{DynamicProgramming/KnapsackProblem => DynamicProgrammin}/MinCoin.java (95%) diff --git a/src/DynamicProgramming/KnapsackProblem/Fibonacci.java b/src/DynamicProgrammin/Fibonacci.java similarity index 97% rename from src/DynamicProgramming/KnapsackProblem/Fibonacci.java rename to src/DynamicProgrammin/Fibonacci.java index 2fa826a..a26480e 100644 --- a/src/DynamicProgramming/KnapsackProblem/Fibonacci.java +++ b/src/DynamicProgrammin/Fibonacci.java @@ -1,4 +1,4 @@ -package DynamicProgramming.KnapsackProblem; +package DynamicProgrammin; /** * 斐波那契问题是经典的动态规划问题,可以从这里面学到动态规划的思想 diff --git a/src/DynamicProgramming/KnapsackProblem/Knapsack01.java b/src/DynamicProgrammin/Knapsack01.java similarity index 81% rename from src/DynamicProgramming/KnapsackProblem/Knapsack01.java rename to src/DynamicProgrammin/Knapsack01.java index 4c3bcc3..7fa50ce 100644 --- a/src/DynamicProgramming/KnapsackProblem/Knapsack01.java +++ b/src/DynamicProgrammin/Knapsack01.java @@ -1,4 +1,4 @@ -package DynamicProgramming.KnapsackProblem; +package DynamicProgrammin; import java.util.concurrent.atomic.AtomicIntegerArray; diff --git a/src/DynamicProgramming/KnapsackProblem/MaxPathSum.java b/src/DynamicProgrammin/MaxPathSum.java similarity index 98% rename from src/DynamicProgramming/KnapsackProblem/MaxPathSum.java rename to src/DynamicProgrammin/MaxPathSum.java index 2b582de..9bb95d3 100644 --- a/src/DynamicProgramming/KnapsackProblem/MaxPathSum.java +++ b/src/DynamicProgrammin/MaxPathSum.java @@ -1,4 +1,4 @@ -package DynamicProgramming.KnapsackProblem; +package DynamicProgrammin; /** * 矩阵的最小路径和(左上角走到右下角,只能向右和向下走) diff --git a/src/DynamicProgramming/KnapsackProblem/MinCoin.java b/src/DynamicProgrammin/MinCoin.java similarity index 95% rename from src/DynamicProgramming/KnapsackProblem/MinCoin.java rename to src/DynamicProgrammin/MinCoin.java index 9bfd070..59e72c6 100644 --- a/src/DynamicProgramming/KnapsackProblem/MinCoin.java +++ b/src/DynamicProgrammin/MinCoin.java @@ -1,4 +1,4 @@ -package DynamicProgramming.KnapsackProblem; +package DynamicProgrammin; /** * @author ahscuml From ca7f3d66526d4831c19dfca6a61ceef095dbc4b6 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Mon, 1 Apr 2019 00:23:24 +0800 Subject: [PATCH 07/33] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E5=85=AC?= =?UTF-8?q?=E5=8F=B8=E6=A0=87=E7=AD=BE=EF=BC=8C83=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 13 +++--- src/Q83RemoveDuplicatesfromSortedList.java | 53 ++++++++++++++++++++++ src/TEST/PostOrder.java | 6 +-- src/util/ListNode.java | 15 ++++++ 4 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 src/Q83RemoveDuplicatesfromSortedList.java create mode 100644 src/util/ListNode.java diff --git a/README.md b/README.md index 8b44feb..b6366ce 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,15 @@ Easy --- -题号|题目|Tags|star| ---- |--- |--- |--- | +题号|题目|Tags|Star|Company| +--- |--- |--- |--- |---| [1](https://leetcode.com/problems/two-sum/description/) | [Two Sum](/src/Q1TwoSum.java) | HashMap | :star: :star: :star: [7](https://leetcode.com/problems/reverse-integer/) | [Reverse Integer](/src/Q7ReverseInteger.java) | Integer | :star: :star: [14](https://leetcode.com/problems/longest-common-prefix/description/) | [Longest Common Prefix](/src/Q14LongestCommonPrefix.java) | String | :star: [20](https://leetcode.com/problems/valid-parentheses/description/) | [Valid Parentheses](/src/Q20ValidParentheses.java) | String、Stack | :star: :star: :star: [21](https://leetcode.com/problems/merge-two-sorted-lists/description/) | [Merge Two Sorted Lists](/src/Q21MergeTwoSortedLists.java) | LinkedList | :star: :star: :star: [53](https://leetcode.com/problems/maximum-subarray/description/) | [Maximum Subarray](/src/Q53MaximumSubarray.java) | Array、DP | :star: :star: :star: :star: +[83](https://leetcode.com/problems/remove-duplicates-from-sorted-list/) | [Remove Duplicates from Sorted List](src/Q83RemoveDuplicatesfromSortedList.java) | ListNode | :star: :star: :star: | ByteDance [88](https://leetcode.com/problems/merge-sorted-array/description/) | [Merge Sorted Array](/src/Q88MergeSortedArray.java) | Array、双指针 [100](https://leetcode.com/problems/same-tree/) | [Same Tree](/src/Q100SameTree.java) | Tree | :star: :star: :star: [101](https://leetcode.com/problems/symmetric-tree/) | [Symmetric Tree](/src/Q101SymmetricTree.java) | Tree | :star: :star: :star: @@ -52,8 +53,8 @@ Easy Medium --- -题号|题目|Tags|star| ----|---|--- |--- | +题号|题目|Tags|Star|Company| +---|---|--- |--- | --- | [2](https://leetcode.com/problems/add-two-numbers/description/) | [Add Two Numbers](/src/Q2AddTwoNumbers.java) | LinkedList | :star: :star: :star: [3](https://leetcode.com/problems/longest-substring-without-repeating-characters/description/) | [Longest Substring Without Repeating Characters](/src/Q3LongestSubstringWithoutRepeatingCharacters.java) | 双指针 | :star: :star: :star: [5](https://leetcode.com/problems/longest-palindromic-substring/) | [Longest Palindromic Substring](/src/Q5LongestPalindromicSubstring.java) | String、动态规划 | :star: :star: :star: @@ -124,8 +125,8 @@ Medium Hard --- -题号|题目|Tags|star| ----|---|--- |--- | +题号|题目|Tags|Star|Company| +---|---|--- |--- | ---| [4](https://leetcode.com/problems/median-of-two-sorted-arrays/) | [Median of Two Sorted Arrays](/src/Q4MedianofTwoSortedArrays.java) | 分治思想、二分查找 | :star: :star: :star: [123](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/) | [Best Time to Buy and Sell Stock III](/src/Q123BestTimetoBuyandSellStockIII.java) | DP、状态机 | :star: :star: :star: [188](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/) | [Best Time to Buy and Sell Stock IV](/src/Q188BestTimetoBuyandSellStockIV.java) | DP | :star: :star: :star: \ No newline at end of file diff --git a/src/Q83RemoveDuplicatesfromSortedList.java b/src/Q83RemoveDuplicatesfromSortedList.java new file mode 100644 index 0000000..6508961 --- /dev/null +++ b/src/Q83RemoveDuplicatesfromSortedList.java @@ -0,0 +1,53 @@ +import util.ListNode; + +/** + * @author ahscuml + * @date 2019/4/1 + * @time 0:09 + */ +public class Q83RemoveDuplicatesfromSortedList { + /** + * 测试函数 + */ + public static void main(String[] args) { + ListNode l1 = new ListNode(1); + ListNode l2 = new ListNode(1); + ListNode l3 = new ListNode(2); + ListNode l4 = new ListNode(3); + ListNode l5 = new ListNode(3); + l1.next = l2; + l2.next = l3; + l3.next = l4; + l4.next = l5; + ListNode cur = deleteDuplicatesII(l1); + while (cur != null) { + System.out.print(cur.val + " "); + cur = cur.next; + } + + } + + /** + * 递归的方法,非常不建议使用,因为会产生栈的溢出 + */ + public static ListNode deleteDuplicates(ListNode head) { + if (head == null || head.next == null) return head; + head.next = deleteDuplicates(head.next); + return head.val == head.next.val ? head.next : head; + } + + /** + * 常规的解法,时间复杂度O(n),空间复杂度O(1) + */ + public static ListNode deleteDuplicatesII(ListNode head) { + ListNode cur = head; + while (cur != null && cur.next != null) { + if (cur.val == cur.next.val) { + cur.next = cur.next.next; + } else { + cur = cur.next; + } + } + return head; + } +} diff --git a/src/TEST/PostOrder.java b/src/TEST/PostOrder.java index 69b86ff..7d5f9ed 100644 --- a/src/TEST/PostOrder.java +++ b/src/TEST/PostOrder.java @@ -42,7 +42,7 @@ private static void postOrderRec(TreeNode root) { /*if (root == null) { return; }*/ - if(root!=null){ + if (root != null) { postOrderRec(root.left); postOrderRec(root.right); System.out.print(root.val); @@ -63,9 +63,9 @@ private static void postOrderIte(TreeNode root) { Stack output = new Stack<>(); TreeNode cur = root; - while (cur != null || !stack.isEmpty()) { + while (cur != null || !stack.isEmpty()) { if (cur != null) { - output.push(cur); + output.push(cur); stack.push(cur); // 先进后出,所以先是右边 cur = cur.right; diff --git a/src/util/ListNode.java b/src/util/ListNode.java new file mode 100644 index 0000000..d529e10 --- /dev/null +++ b/src/util/ListNode.java @@ -0,0 +1,15 @@ +package util; + +/** + * @author ahscuml + * @date 2019/4/1 + * @time 0:10 + */ +public class ListNode { + public int val; + public ListNode next; + + public ListNode(int x) { + val = x; + } +} From 2021c09e5a2e7fb27a201f64750ac1c1489ef67f Mon Sep 17 00:00:00 2001 From: ahscuml Date: Mon, 1 Apr 2019 12:20:45 +0800 Subject: [PATCH 08/33] 124 --- README.md | 3 +- src/Q114FlattenBinaryTreetoLinkedList.java | 4 +- src/Q124BinaryTreeMaximumPathSum.java | 48 ++++++++++++++++++++++ 3 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 src/Q124BinaryTreeMaximumPathSum.java diff --git a/README.md b/README.md index b6366ce..e4db24b 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Medium [102](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/) | [Binary Tree Level Order Traversal](/src/Q102BinaryTreeLevelOrderTraversal.java) | Tree | :star: :star: :star: [103](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/) | [Binary Tree Zigzag Level Order Traversal](/src/Q103BinaryTreeZigzagLevelOrderTraversal.java) | Tree | :star: :star: :star: [113](https://leetcode.com/problems/path-sum-ii/) | [Path Sum II](/src/Q113PathSumII.java) | Tree | :star: :star: -[114](https://leetcode.com/problems/flatten-binary-tree-to-linked-list/) | [Flatten Binary Tree to Linked List](/src/Q114FlattenBinaryTreetoLinkedList.java) | Tree | :star: :star: :star: +[114](https://leetcode.com/problems/flatten-binary-tree-to-linked-list/) | [Flatten Binary Tree to Linked List](/src/Q114FlattenBinaryTreetoLinkedList.java) | Tree、递归 | :star: :star: :star: :star | ByteDance [120](https://leetcode.com/problems/triangle/) | [Triangle](/src/Q120Triangle.java) | DP | :star: :star: :star: [139](https://leetcode.com/problems/word-break/) | [Word Break](/src/Q139WordBreak.java) | DP | :star: :star: :star: [142](https://leetcode.com/problems/linked-list-cycle-ii/description/) | [Linked List Cycle II](/src/Q142LinkedListCycleII.java) | LinkedList、双指针 | :star: :star: :star: @@ -129,4 +129,5 @@ Hard ---|---|--- |--- | ---| [4](https://leetcode.com/problems/median-of-two-sorted-arrays/) | [Median of Two Sorted Arrays](/src/Q4MedianofTwoSortedArrays.java) | 分治思想、二分查找 | :star: :star: :star: [123](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/) | [Best Time to Buy and Sell Stock III](/src/Q123BestTimetoBuyandSellStockIII.java) | DP、状态机 | :star: :star: :star: +[124](https://leetcode.com/problems/binary-tree-maximum-path-sum/) | [Binary Tree Maximum Path Sum](/src/Q124BinaryTreeMaximumPathSum.java) | Tree,递归 | :star: :star: :star: [188](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/) | [Best Time to Buy and Sell Stock IV](/src/Q188BestTimetoBuyandSellStockIV.java) | DP | :star: :star: :star: \ No newline at end of file diff --git a/src/Q114FlattenBinaryTreetoLinkedList.java b/src/Q114FlattenBinaryTreetoLinkedList.java index e973153..d48f1a7 100644 --- a/src/Q114FlattenBinaryTreetoLinkedList.java +++ b/src/Q114FlattenBinaryTreetoLinkedList.java @@ -24,6 +24,7 @@ public void flatten(TreeNode root) { if (root == null) { return; } + // 这样递归调用保证是从后面往前面进行后面的操作的 flatten(root.right); flatten(root.left); // 如果左面空,那么不用处理,直接返回 @@ -59,7 +60,7 @@ public void flattenEasy(TreeNode root) { } /** - * 迭代方法 + * 迭代方法,先存右节点,再存左节点。 */ public void flattenIte(TreeNode root) { if (root == null) { @@ -79,7 +80,6 @@ public void flattenIte(TreeNode root) { cur.right = stack.peek(); } cur.left = null; - } } diff --git a/src/Q124BinaryTreeMaximumPathSum.java b/src/Q124BinaryTreeMaximumPathSum.java new file mode 100644 index 0000000..e67e48b --- /dev/null +++ b/src/Q124BinaryTreeMaximumPathSum.java @@ -0,0 +1,48 @@ +import util.TreeNode; + +/** + * @author ahscuml + * @date 2019/4/1 + * @time 12:09 + */ +public class Q124BinaryTreeMaximumPathSum { + /** + * 还是利用了递归的思想,以当前节点为中心,找到左右两边最大的子树,然后加起来 + */ + public static int max = Integer.MIN_VALUE; + + /** + * 测试函数 + */ + public static void main(String[] args) { + TreeNode t1 = new TreeNode(1); + TreeNode t2 = new TreeNode(2); + TreeNode t3 = new TreeNode(3); + t1.left = t2; + t1.right = t3; + System.out.println(maxPathSum(t1)); + } + + /** + * 返回这个最大值 + * */ + public static int maxPathSum(TreeNode root) { + helper(root); + return max; + } + + /** + * 返回以当前节点为中心的最大的左节点或者右节点 + */ + private static int helper(TreeNode node) { + if (node == null) { + return 0; + } + int left = Math.max(0, helper(node.left)); + int right = Math.max(0, helper(node.right)); + // 最大值的判断 + max = Math.max(max, left + right + node.val); + // 这是要返回的内容,最大的左或右,别忘了加上val + return Math.max(left, right) + node.val; + } +} From 99f466583cd449cdb3fa5569ae03e81a38c9fc04 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Mon, 1 Apr 2019 15:37:23 +0800 Subject: [PATCH 09/33] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=8621=E9=A2=98?= =?UTF-8?q?=E5=92=8C86=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + src/Q21MergeTwoSortedLists.java | 43 +++++++++++++++++++++++++++------ src/Q86PartitionList.java | 39 ++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e4db24b..0f49151 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ Medium [15](https://leetcode.com/problems/3sum/description/) | [3Sum](/src/Q153Sum.java) | Array、双指针 | :star: :star: :star: [17](https://leetcode.com/problems/letter-combinations-of-a-phone-number/description/) | [Letter Combinations of a Phone Number](/src/Q17LetterCombinationsofaPhoneNumber.java) | 递归 | :star: :star: :star: [19](https://leetcode.com/problems/remove-nth-node-from-end-of-list/description/) | [Remove Nth Node From End of List](/src/Q19RemoveNthNodeFromEndofList.java) | 双指针 | :star: :star: :star: +[21](https://leetcode.com/problems/merge-two-sorted-lists/) | [Merge Two Sorted Lists](/src/Q21MergeTwoSortedLists.java) | List,递归 | :star: :star: :star: :star: [22](https://leetcode.com/problems/generate-parentheses/) | [Generate Parentheses](/src/Q22GenerateParentheses.java) | String、回溯法 | :star: :star: :star: [24](https://leetcode.com/problems/swap-nodes-in-pairs/description/) | [Swap Nodes in Pairs](/src/Q24SwapNodesinPairs.java) | LinkedList | :star: :star: :star: [34](https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/description/) | [Find First and Last Position of Element in Sorted Array](/src/Q34FindFirstandLastPositionofElementinSortedArray.java) | Array、BinarySearch | :star: :star: :star: diff --git a/src/Q21MergeTwoSortedLists.java b/src/Q21MergeTwoSortedLists.java index 1a7645a..2a7e25c 100644 --- a/src/Q21MergeTwoSortedLists.java +++ b/src/Q21MergeTwoSortedLists.java @@ -1,5 +1,6 @@ /** * 21. Merge Two Sorted Lists + * * @author ahscuml * @date 2018/9/29 * @time 15:16 @@ -7,7 +8,7 @@ public class Q21MergeTwoSortedLists { /** * 测试函数 - * */ + */ public static void main(String[] args) { ListNode listNode1 = new ListNode(1); ListNode listNode2 = new ListNode(2); @@ -26,24 +27,52 @@ public static void main(String[] args) { result = result.next; } } + /** * 递归,相当优秀 - * */ - public static ListNode mergeTwoLists(ListNode l1, ListNode l2){ - if(l1 == null) { + */ + public static ListNode mergeTwoLists(ListNode l1, ListNode l2) { + if (l1 == null) { return l2; } - if(l2 == null) { + if (l2 == null) { return l1; } - if(l1.val < l2.val){ + if (l1.val < l2.val) { l1.next = mergeTwoLists(l1.next, l2); return l1; - } else{ + } else { l2.next = mergeTwoLists(l1, l2.next); return l2; } } + + /** + * 循环的方法,同样也很优秀,只不过长了一点 + * 创建一个dummyHead节点,这是惯用的方法 + */ + public ListNode mergeTwoListsII(ListNode l1, ListNode l2) { + ListNode dummyHead = new ListNode(-1); + ListNode cur = dummyHead; + while (l1 != null && l2 != null) { + if (l1.val < l2.val) { + cur.next = l1; + l1 = l1.next; + } else { + cur.next = l2; + l2 = l2.next; + } + cur = cur.next; + } + if (l1 != null) { + cur.next = l1; + } + if (l2 != null) { + cur.next = l2; + } + return dummyHead.next; + } + /** * 链表的定义 */ diff --git a/src/Q86PartitionList.java b/src/Q86PartitionList.java index 2ad888f..6381319 100644 --- a/src/Q86PartitionList.java +++ b/src/Q86PartitionList.java @@ -50,6 +50,45 @@ public static ListNode partition(ListNode head, int x) { return smallHead.next; } + /** + * 空间复杂度O(1),时间复杂度O(n) + * 在链表内部调整,找到一个小的,就把这个小的放到前面。 + * */ + public ListNode partitionII(ListNode head, int x) { + // 循环的方法 + // 存3个节点,一个是pre,一个cur,还有一个小数字的尾节点 + if(head == null) { + return head; + } + ListNode dummyHead = new ListNode(-1); + dummyHead.next = head; + ListNode cur = head; + ListNode pre = dummyHead; + ListNode tail = dummyHead; + while(cur != null) { + if(cur.val < x) { + if(tail == pre) { + cur = cur.next; + pre = pre.next; + tail = tail.next; + } else { + // 摘链 + pre.next = cur.next; + // 插入 + cur.next = tail.next; + tail.next = cur; + tail = cur; + cur = pre.next; + } + + } else { + cur = cur.next; + pre = pre.next; + } + } + return dummyHead.next; + } + public static class ListNode { int val; ListNode next; From b57f610241bac91cf50ab0dacf7265984228215d Mon Sep 17 00:00:00 2001 From: ahscuml Date: Mon, 1 Apr 2019 16:21:31 +0800 Subject: [PATCH 10/33] =?UTF-8?q?160=E9=A2=98=E8=BF=98=E6=98=AF=E5=BE=88?= =?UTF-8?q?=E5=85=B3=E9=94=AE=E7=9A=84=EF=BC=8C=E5=A2=9E=E5=8A=A0=E4=BA=86?= =?UTF-8?q?=E5=BE=AA=E7=8E=AF=E5=A4=84=E7=90=86=E7=9A=84=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/Q160IntersectionofTwoLinkedLists.java | 36 ++++++++++++++++++++++- src/Q617MergeTwoBinaryTrees.java | 16 ++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0f49151..2bfe5fb 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Easy [136](https://leetcode.com/problems/single-number/description/) | [Single Number](/src/Q136SingleNumber.java) | Array、二进制 | :star: :star: :star: [141](https://leetcode.com/problems/linked-list-cycle/description/) | [Linked List Cycle](/src/Q141LinkedListCycle.java) | LinkedList、双指针 | :star: :star: :star: [148](https://leetcode.com/problems/sort-list/) | [Sort List](/src/Q148SortList.java) | LinkedList、MergeSort | :star: :star: :star: -[160](https://leetcode.com/problems/intersection-of-two-linked-lists/description/) | [Intersection of Two Linked Lists](/src/Q160IntersectionofTwoLinkedLists.java) | LinkedList、双指针 | :star: :star: :star: +[160](https://leetcode.com/problems/intersection-of-two-linked-lists/description/) | [Intersection of Two Linked Lists](/src/Q160IntersectionofTwoLinkedLists.java) | LinkedList、双指针 | :star: :star: :star: :star: | ByteDance [169](https://leetcode.com/problems/majority-element/description/) | [Majority Element](/src/Q169MajorityElement.java) | Array | :star: :star: [198](https://leetcode.com/problems/house-robber/description/) | [House Robber](/src/Q198HouseRobber.java) | Array、DP | :star: :star: :star: [200](https://leetcode.com/problems/number-of-islands/) | [Number of Islands](/src/Q200NumberofIslands.java) | DFS、BFS | :star: :star: :star: diff --git a/src/Q160IntersectionofTwoLinkedLists.java b/src/Q160IntersectionofTwoLinkedLists.java index de76548..2579847 100644 --- a/src/Q160IntersectionofTwoLinkedLists.java +++ b/src/Q160IntersectionofTwoLinkedLists.java @@ -14,6 +14,7 @@ public static void main(String[] args) { listNode2.next = listNode3; listNode3.next = listNode4; System.out.println(getIntersectionNode(listNode1, listNode2).val); + System.out.println(getIntersectionNodeII(listNode1, listNode2).val); } /** @@ -35,10 +36,43 @@ public static ListNode getIntersectionNode(ListNode headA, ListNode headB) { a = a == null ? headB : a.next; b = b == null ? headA : b.next; } - return a; } + /** + * 另外一种循环的方法就是首先求出两个链表的长度,然后调整到一样长的地方在走,直到找到相同的那个节点 + */ + public static ListNode getIntersectionNodeII(ListNode headA, ListNode headB) { + if (headA == null || headB == null) { + return null; + } + int alen = len(headA); + int blen = len(headB); + while (alen > blen) { + headA = headA.next; + alen--; + } + while (blen > alen) { + headB = headB.next; + blen--; + } + + while (headA != headB) { + headA = headA.next; + headB = headB.next; + } + return headA; + } + + public static int len(ListNode node) { + int count = 0; + while (node != null) { + count++; + node = node.next; + } + return count; + } + static class ListNode { int val; ListNode next; diff --git a/src/Q617MergeTwoBinaryTrees.java b/src/Q617MergeTwoBinaryTrees.java index cde7740..d5c1911 100644 --- a/src/Q617MergeTwoBinaryTrees.java +++ b/src/Q617MergeTwoBinaryTrees.java @@ -1,4 +1,5 @@ /** + * TODO 循环的方法 * @author ahscuml * @date 2018/11/26 * @time 15:09 @@ -49,6 +50,21 @@ public static TreeNode mergeTrees(TreeNode t1, TreeNode t2) { return newNode; } + /** + * 自己写的递归方法,时间复杂度O(n) + * */ + public TreeNode mergeTreesII(TreeNode t1, TreeNode t2) { + if(t1 == null) { + return t2; + } + if(t2 == null) { + return t1; + } + t1.val = t1.val + t2.val; + t1.left = mergeTrees(t1.left, t2.left); + t1.right = mergeTrees(t1.right, t2.right); + return t1; + } /** * 中序遍历, 递归 打印这个树 From f3e6ea2daacb1942db0c392005318873d2fcf8e7 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Mon, 1 Apr 2019 17:14:33 +0800 Subject: [PATCH 11/33] 199 --- README.md | 1 + src/Q199BinaryTreeRightSideView.java | 71 ++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 src/Q199BinaryTreeRightSideView.java diff --git a/README.md b/README.md index 2bfe5fb..01149c0 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ Medium [142](https://leetcode.com/problems/linked-list-cycle-ii/description/) | [Linked List Cycle II](/src/Q142LinkedListCycleII.java) | LinkedList、双指针 | :star: :star: :star: [143](https://leetcode.com/problems/reorder-list/) | [Reorder List](/src/Q143ReorderList.java) | LinkedList | :star: :star: :star: [152](https://leetcode.com/problems/maximum-product-subarray/description/) | [Maximum Product Subarray](/src/Q152MaximumProductSubarray.java) | Array、 DP | :star: :star: :star: +[199](https://leetcode.com/problems/binary-tree-right-side-view/) | [Binary Tree Right Side View](/src/Q199BinaryTreeRightSideView.java) | Tree,递归 | :star: :star: :star: :star: | ByteDance [209](https://leetcode.com/problems/minimum-size-subarray-sum/description/) | [Minimum Size Subarray Sum](/src/Q209MinimumSizeSubarraySum.java) | Array、滑动窗口 [213](https://leetcode.com/problems/house-robber-ii/) | [House Robber II](/src/Q213HouseRobberII.java) | 动态规划 | :star: :star: [215](https://leetcode.com/problems/kth-largest-element-in-an-array/description/) | [Kth Largest Element in an Array](/src/Q215KthLargestElementinanArray.java) | Array、快速选择算法 | :star: :star: :star: :star: diff --git a/src/Q199BinaryTreeRightSideView.java b/src/Q199BinaryTreeRightSideView.java new file mode 100644 index 0000000..b16e0c4 --- /dev/null +++ b/src/Q199BinaryTreeRightSideView.java @@ -0,0 +1,71 @@ +import util.TreeNode; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * @author ahscuml + * @date 2019/4/1 + * @time 17:00 + */ +public class Q199BinaryTreeRightSideView { + /** + * 测试函数 + * */ + public static void main(String[] args) { + //TODO + } + + /** + * 循环的方式,相当于层序遍历 + * */ + public List rightSideView(TreeNode root) { + // 从右往左看就是将层序遍历的最后一个元素放入这个list中 + Queue queue = new LinkedList(); + List list = new ArrayList(); + if(root == null) { + return list; + } + queue.offer(root); + while(queue.size() != 0) { + int n = queue.size(); + for(int i = 0; i < n; i++) { + TreeNode cur = queue.poll(); + if(i == 0) { + list.add(cur.val); + } + if(cur.right != null) { + queue.offer(cur.right); + } + if(cur.left != null) { + queue.offer(cur.left); + } + } + } + return list; + } + + /** + * 递归的方法 + * */ + public List rightSideViewII(TreeNode root) { + List result = new ArrayList(); + rightView(root, result, 0); + return result; + } + + public void rightView(TreeNode curr, List result, int currDepth){ + if(curr == null){ + return; + } + if(currDepth == result.size()){ + result.add(curr.val); + } + + rightView(curr.right, result, currDepth + 1); + rightView(curr.left, result, currDepth + 1); + + } +} From c814a9acd95694318f44f2cadc458fb23bef32b6 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Mon, 1 Apr 2019 22:05:41 +0800 Subject: [PATCH 12/33] =?UTF-8?q?23=E9=A2=98=E7=9A=84=E4=B8=89=E7=A7=8D?= =?UTF-8?q?=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 ++- src/Q148SortList.java | 22 +++---- src/Q23MergekSortedLists.java | 111 ++++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+), 14 deletions(-) create mode 100644 src/Q23MergekSortedLists.java diff --git a/README.md b/README.md index 01149c0..705bafd 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ Easy [7](https://leetcode.com/problems/reverse-integer/) | [Reverse Integer](/src/Q7ReverseInteger.java) | Integer | :star: :star: [14](https://leetcode.com/problems/longest-common-prefix/description/) | [Longest Common Prefix](/src/Q14LongestCommonPrefix.java) | String | :star: [20](https://leetcode.com/problems/valid-parentheses/description/) | [Valid Parentheses](/src/Q20ValidParentheses.java) | String、Stack | :star: :star: :star: -[21](https://leetcode.com/problems/merge-two-sorted-lists/description/) | [Merge Two Sorted Lists](/src/Q21MergeTwoSortedLists.java) | LinkedList | :star: :star: :star: -[53](https://leetcode.com/problems/maximum-subarray/description/) | [Maximum Subarray](/src/Q53MaximumSubarray.java) | Array、DP | :star: :star: :star: :star: +[21](https://leetcode.com/problems/merge-two-sorted-lists/description/) | [Merge Two Sorted Lists](/src/Q21MergeTwoSortedLists.java) | LinkedList | :star: :star: :star: :star: +[53](https://leetcode.com/problems/maximum-subarray/description/) | [Maximum Subarray](/src/Q53MaximumSubarray.java) | Array、DP | :star: :star: :star: [83](https://leetcode.com/problems/remove-duplicates-from-sorted-list/) | [Remove Duplicates from Sorted List](src/Q83RemoveDuplicatesfromSortedList.java) | ListNode | :star: :star: :star: | ByteDance [88](https://leetcode.com/problems/merge-sorted-array/description/) | [Merge Sorted Array](/src/Q88MergeSortedArray.java) | Array、双指针 [100](https://leetcode.com/problems/same-tree/) | [Same Tree](/src/Q100SameTree.java) | Tree | :star: :star: :star: @@ -28,7 +28,7 @@ Easy [122](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/) | [Best Time to Buy and Sell Stock II](/src/Q122BestTimetoBuyandSellStockII.java) | DP | :star: [136](https://leetcode.com/problems/single-number/description/) | [Single Number](/src/Q136SingleNumber.java) | Array、二进制 | :star: :star: :star: [141](https://leetcode.com/problems/linked-list-cycle/description/) | [Linked List Cycle](/src/Q141LinkedListCycle.java) | LinkedList、双指针 | :star: :star: :star: -[148](https://leetcode.com/problems/sort-list/) | [Sort List](/src/Q148SortList.java) | LinkedList、MergeSort | :star: :star: :star: +[148](https://leetcode.com/problems/sort-list/) | [Sort List](/src/Q148SortList.java) | LinkedList、MergeSort | :star: :star: :star: :star: |ByteDance [160](https://leetcode.com/problems/intersection-of-two-linked-lists/description/) | [Intersection of Two Linked Lists](/src/Q160IntersectionofTwoLinkedLists.java) | LinkedList、双指针 | :star: :star: :star: :star: | ByteDance [169](https://leetcode.com/problems/majority-element/description/) | [Majority Element](/src/Q169MajorityElement.java) | Array | :star: :star: [198](https://leetcode.com/problems/house-robber/description/) | [House Robber](/src/Q198HouseRobber.java) | Array、DP | :star: :star: :star: @@ -130,6 +130,7 @@ Hard 题号|题目|Tags|Star|Company| ---|---|--- |--- | ---| [4](https://leetcode.com/problems/median-of-two-sorted-arrays/) | [Median of Two Sorted Arrays](/src/Q4MedianofTwoSortedArrays.java) | 分治思想、二分查找 | :star: :star: :star: +[23](https://leetcode.com/problems/merge-k-sorted-lists/) | [Merge k Sorted Lists](/src/Q23MergekSortedLists.java) | ListNode,归并排序,优先队列 | :star: :star: :star: :star: [123](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/) | [Best Time to Buy and Sell Stock III](/src/Q123BestTimetoBuyandSellStockIII.java) | DP、状态机 | :star: :star: :star: [124](https://leetcode.com/problems/binary-tree-maximum-path-sum/) | [Binary Tree Maximum Path Sum](/src/Q124BinaryTreeMaximumPathSum.java) | Tree,递归 | :star: :star: :star: [188](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/) | [Best Time to Buy and Sell Stock IV](/src/Q188BestTimetoBuyandSellStockIV.java) | DP | :star: :star: :star: \ No newline at end of file diff --git a/src/Q148SortList.java b/src/Q148SortList.java index 9607ed4..5a2c4aa 100644 --- a/src/Q148SortList.java +++ b/src/Q148SortList.java @@ -79,19 +79,19 @@ public static ListNode sortList(ListNode head) { * 递归调用,两个节点,一个快,一个慢,快的到达末尾,慢的就到达中间 */ public static ListNode sortListRec(ListNode head) { - if (head == null || head.next == null) + if(head == null || head.next == null) { return head; - ListNode f = head.next.next; - ListNode p = head; - while (f != null && f.next != null) { - p = p.next; - f = f.next.next; } - // 递归调用 p在链表的中部 - ListNode h2 = sortListRec(p.next); - // 将一个链表从中间分为两部分 一个是head,一个是h2 - p.next = null; - return merge(sortListRec(head), h2); + ListNode slow = head,fast = head,pre = null; + while(fast != null && fast.next != null) { + pre = slow; + slow = slow.next; + fast = fast.next.next; + } + pre.next = null; + ListNode l1 = sortList(head); + ListNode l2 = sortList(slow); + return merge(l1, l2); } /** diff --git a/src/Q23MergekSortedLists.java b/src/Q23MergekSortedLists.java new file mode 100644 index 0000000..5911b52 --- /dev/null +++ b/src/Q23MergekSortedLists.java @@ -0,0 +1,111 @@ +import util.ListNode; + +import java.util.*; + +/** + * @author ahscuml + * @date 2019/4/1 + * @time 18:19 + */ +public class Q23MergekSortedLists { + /** + * 测试函数 + */ + public static void main(String[] args) { + //TODO + } + + /** + * 看到了merge最先想到的就应该是mergesort,针对链表进行mergesort + */ + public ListNode mergeKLists(ListNode[] lists) { + if (lists.length == 0) { + return null; + } + return sort(lists, 0, lists.length - 1); + } + + public ListNode sort(ListNode[] lists, int start, int end) { + if (start == end) { + return lists[start]; + } + int mid = start + (end - start) / 2; + ListNode l1 = sort(lists, start, mid); + ListNode l2 = sort(lists, mid + 1, end); + return merge(l1, l2); + } + + public ListNode merge(ListNode a, ListNode b) { + if (a == null) { + return b; + } + if (b == null) { + return a; + } + if (a.val < b.val) { + a.next = merge(a.next, b); + return a; + } else { + b.next = merge(b.next, a); + return b; + } + } + + /** + * 对于很对元素排序的题还可以应用优先队列,应用优先队列的特性,让优先队列去排序 + * */ + public ListNode mergeKLists(List lists) { + if (lists == null || lists.size() == 0) { + return null; + } + // 优先队列的构造函数,确定大小和初始化构造器,通过构造器来完成排序的工作 + PriorityQueue queue = new PriorityQueue(lists.size(), new Comparator() { + @Override + public int compare(ListNode o1, ListNode o2) { + return o1.val - o2.val; + } + }); + + ListNode dummy = new ListNode(0); + ListNode tail = dummy; + for (ListNode node : lists) { + if (node != null) { + queue.add(node); + } + while (!queue.isEmpty()) { + tail.next = queue.poll(); + tail = tail.next; + // lists里面的ListNode只是一个节点,如果当前节点后面还有节点,那么在放入队列的时候将这个节点之后的节点添加进queue + if (tail.next != null) { + queue.add(tail.next); + } + } + } + return dummy.next; + } + + /** + * 还有一种方法,可以把所有的ListNode的值读出来,读到一个list里,然后进行排序,最后从头到尾进行建立ListNode的操作 + * 这种方法竟然打败了 + * */ + public ListNode mergeKListsIII(ListNode[] lists) { + ArrayList list = new ArrayList(); + for(int i = 0; i < lists.length; i++) { + ListNode cur = lists[i]; + while(cur != null) { + list.add(cur.val); + cur = cur.next; + } + } + Collections.sort(list); + ListNode dummyHead = new ListNode(0); + ListNode cur = dummyHead; + for(int i = 0; i < list.size(); i++) { + + cur.next = new ListNode(list.get(i)); + cur = cur.next; + //cur = null; + } + return dummyHead.next; + } +} From fea7d00c199175fdd94373f7f2ce0665fce0899e Mon Sep 17 00:00:00 2001 From: ahscuml Date: Thu, 4 Apr 2019 00:35:40 +0800 Subject: [PATCH 13/33] =?UTF-8?q?23=E9=A2=98=E7=9A=84=E4=B8=89=E7=A7=8D?= =?UTF-8?q?=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +- src/DynamicProgrammin/Fibonacci.java | 74 ------------------------- src/DynamicProgrammin/Knapsack01.java | 14 ----- src/DynamicProgrammin/MaxPathSum.java | 67 ---------------------- src/DynamicProgrammin/MinCoin.java | 36 ------------ src/Q215KthLargestElementinanArray.java | 26 ++++----- src/Q50Pow.java | 28 ++++++++++ 7 files changed, 43 insertions(+), 207 deletions(-) delete mode 100644 src/DynamicProgrammin/Fibonacci.java delete mode 100644 src/DynamicProgrammin/Knapsack01.java delete mode 100644 src/DynamicProgrammin/MaxPathSum.java delete mode 100644 src/DynamicProgrammin/MinCoin.java create mode 100644 src/Q50Pow.java diff --git a/README.md b/README.md index 705bafd..3e10177 100644 --- a/README.md +++ b/README.md @@ -88,8 +88,9 @@ Medium [92](https://leetcode.com/problems/reverse-linked-list-ii/) | [Reverse Linked List II](/src/Q92ReverseLinkedListII.java) | LinkedList | :star: :star: :star: [94](https://leetcode.com/problems/binary-tree-inorder-traversal/description/) | [Binary Tree Inorder Traversal](/src/Q94BinaryTreeInorderTraversal.java) | Tree | :star: :star: :star: [96](https://leetcode.com/problems/unique-binary-search-trees/) | [Unique Binary Search Trees](/src/Q96UniqueBinarySearchTrees.java) | BST, 递归 | :star: :star: :star: +[98](https://leetcode.com/problems/validate-binary-search-tree/) | [Validate Binary Search Tree](/src/Q98ValidateBinarySearchTree.java) | 递归 | :star: :star: :star: | ByteDance [102](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/) | [Binary Tree Level Order Traversal](/src/Q102BinaryTreeLevelOrderTraversal.java) | Tree | :star: :star: :star: -[103](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/) | [Binary Tree Zigzag Level Order Traversal](/src/Q103BinaryTreeZigzagLevelOrderTraversal.java) | Tree | :star: :star: :star: +[103](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/) | [Binary Tree Zigzag Level Order Traversal](/src/Q103BinaryTreeZigzagLevelOrderTraversal.java) | Tree | :star: :star: :star: | ByteDance [113](https://leetcode.com/problems/path-sum-ii/) | [Path Sum II](/src/Q113PathSumII.java) | Tree | :star: :star: [114](https://leetcode.com/problems/flatten-binary-tree-to-linked-list/) | [Flatten Binary Tree to Linked List](/src/Q114FlattenBinaryTreetoLinkedList.java) | Tree、递归 | :star: :star: :star: :star | ByteDance [120](https://leetcode.com/problems/triangle/) | [Triangle](/src/Q120Triangle.java) | DP | :star: :star: :star: @@ -100,7 +101,7 @@ Medium [199](https://leetcode.com/problems/binary-tree-right-side-view/) | [Binary Tree Right Side View](/src/Q199BinaryTreeRightSideView.java) | Tree,递归 | :star: :star: :star: :star: | ByteDance [209](https://leetcode.com/problems/minimum-size-subarray-sum/description/) | [Minimum Size Subarray Sum](/src/Q209MinimumSizeSubarraySum.java) | Array、滑动窗口 [213](https://leetcode.com/problems/house-robber-ii/) | [House Robber II](/src/Q213HouseRobberII.java) | 动态规划 | :star: :star: -[215](https://leetcode.com/problems/kth-largest-element-in-an-array/description/) | [Kth Largest Element in an Array](/src/Q215KthLargestElementinanArray.java) | Array、快速选择算法 | :star: :star: :star: :star: +[215](https://leetcode.com/problems/kth-largest-element-in-an-array/description/) | [Kth Largest Element in an Array](/src/Q215KthLargestElementinanArray.java) | Array、快速选择算法 | :star: :star: :star: :star: | ihandy,ByteDance [216](https://leetcode.com/problems/combination-sum-iii/description/) | [CombinationSumIII](/src/Q216CombinationSumIII.java) | Array、回溯法 | :star: :star: :star: [221](https://leetcode.com/problems/maximal-square/) | [Maximal Square](/src/Q221MaximalSquare.java) | DP | :star: :star: :star: [238](https://leetcode.com/problems/product-of-array-except-self/description/) | [Product of Array Except Self](/src/Q238ProductofArrayExceptSelf.java) | Array diff --git a/src/DynamicProgrammin/Fibonacci.java b/src/DynamicProgrammin/Fibonacci.java deleted file mode 100644 index a26480e..0000000 --- a/src/DynamicProgrammin/Fibonacci.java +++ /dev/null @@ -1,74 +0,0 @@ -package DynamicProgrammin; - -/** - * 斐波那契问题是经典的动态规划问题,可以从这里面学到动态规划的思想 - * - * 补充1:走台阶,每次可以走1步,或者两步,问有多少种可能 - * - * 补充2:母牛生产问题,成熟母牛每年生一个小牛小牛三年之后成熟又可以生小牛。第一年有一头牛, - * 第二年开始生小牛,给定整数N,求N年后牛的数量 - * @author ahscuml - * @date 19-3-20 - * @time 下午3:14 - */ -public class Fibonacci { - public static void main(String[] args) { - System.out.println(fib1(8)); - System.out.println(fib2(8)); - System.out.println(cow(5)); - } - - /** - * 递归的方法来做这个提,从上往下 - * */ - private static int fib1(int n) { - if(n < 1) { - return 0; - } else if(n == 1 || n == 2) { - return 1; - } - return fib1(n - 1) + fib1( n - 2); - } - - /** - * 动态规划的方法,O(N)的时间复杂度 - * */ - private static int fib2(int n) { - if (n < 1) { - return 0; - } else if (n == 1 || n == 2) { - return 1; - } - int res = 1, pre = 1; - for (int i = 3; i <= n; i++) { - res += pre; - pre = res - pre; - } - return res; - } - - /** - * 小牛问题 - * 重点是找到递推的关系式 - * */ - private static int cow(int n) { - if(n < 1) { - return 0; - } else if(n == 1 || n == 2 || n == 3) { - return n; - } - // 前1年 - int n_1 = 3; - // 前2年 - int n_2 = 2; - // 前3年 - int n_3 = 1; - for(int i = 4; i <= n; i++) { - n_1 = n_1 + n_3; - int temp = n_2; - n_2 = n_1 - n_3; - n_3 = temp; - } - return n_1; - } -} diff --git a/src/DynamicProgrammin/Knapsack01.java b/src/DynamicProgrammin/Knapsack01.java deleted file mode 100644 index 7fa50ce..0000000 --- a/src/DynamicProgrammin/Knapsack01.java +++ /dev/null @@ -1,14 +0,0 @@ -package DynamicProgrammin; - -import java.util.concurrent.atomic.AtomicIntegerArray; - -/** - * @author ahscuml - * @date 2018/11/28 - * @time 20:13 - */ -public class Knapsack01 { - public static void main(String[] args) { - - } -} diff --git a/src/DynamicProgrammin/MaxPathSum.java b/src/DynamicProgrammin/MaxPathSum.java deleted file mode 100644 index 9bb95d3..0000000 --- a/src/DynamicProgrammin/MaxPathSum.java +++ /dev/null @@ -1,67 +0,0 @@ -package DynamicProgrammin; - -/** - * 矩阵的最小路径和(左上角走到右下角,只能向右和向下走) - * - * @author ahscuml - * @date 19-3-20 - * @time 下午3:53 - */ -public class MaxPathSum { - public static void main(String[] args) { - int[][] matrix = {{1,3,5,9},{8,1,3,4},{5,0,6,1},{8,8,4,0}}; - System.out.println(maxPathSum1(matrix)); - System.out.println(maxPathSum1(matrix)); - } - - /** - * 创建一个二维数组来存储内容,dp[i][j]代表到达当前节点的最小路径值 - * 时间复杂度O(M * N),空间复杂度O(M * N) - * */ - public static int maxPathSum1(int[][] matrix) { - if (matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0) { - return 0; - } - int[][] dp = new int[matrix.length][matrix[0].length]; - dp[0][0] = matrix[0][0]; - for (int i = 1; i < matrix.length; i++) { - dp[i][0] = dp[i - 1][0] + matrix[i][0]; - } - for (int j = 1; j < matrix[0].length; j++) { - dp[0][j] = dp[0][j - 1] + matrix[0][j]; - } - for (int i = 1; i < matrix.length; i++) { - for (int j = 1; j < matrix[0].length; j++) { - dp[i][j] = Math.min(dp[i - 1][j],dp[i][j - 1]) + matrix[i][j]; - } - } - return dp[matrix.length - 1][matrix[0].length - 1]; - } - - /** - * 对于上面的方法的优化,时间复杂度不变,但是空间复杂度变为O(mni(M,N)) - * */ - public static int maxPathSum2(int[][] matrix) { - if (matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0) { - return 0; - } - int col = matrix.length; - int row = matrix[0].length; - int more = Math.max(col, row); - int less = Math.min(col, row); - // 判断是行更多一些,还是列更多一些 - boolean rowmore = more == col; - int[] dp = new int[less]; - dp[0] = matrix[0][0]; - for (int i = 1; i < less; i++) { - dp[i] = dp[i - 1] + (rowmore ? matrix[0][i] : matrix[i][0]); - } - for (int i = 1; i < more; i++) { - dp[0] = dp[0] + (rowmore ? matrix[i][0] : matrix[0][i]); - for (int j = 1; j < less; j++) { - dp[j] = Math.min(dp[j - 1], dp[j]) + (rowmore ? matrix[i][j] : matrix[j][i]); - } - } - return dp[less - 1]; - } -} diff --git a/src/DynamicProgrammin/MinCoin.java b/src/DynamicProgrammin/MinCoin.java deleted file mode 100644 index 59e72c6..0000000 --- a/src/DynamicProgrammin/MinCoin.java +++ /dev/null @@ -1,36 +0,0 @@ -package DynamicProgrammin; - -/** - * @author ahscuml - * @date 19-3-20 - * @time 下午4:33 - */ -public class MinCoin { - public static void main(String[] args) { - int[] coins = {1,2,5}; - int target = 11; - System.out.println(minCoin1(coins, target)); - } - - /** - * 首先要找到递推的关系式 - * dp[j]就是凑成j最少有多少种方法 - * */ - public static int minCoin1(int[] num, int target) { - int[] dp = new int[target + 1]; - dp[0] = 0; - for (int i = 1; i <= target; i++) { - int min = -1; - for (int coin : num) { - if (i >= coin) { - int temp = dp[i - coin]; - if (temp != -1) { - min = min == -1 ? temp + 1 : (min > temp + 1 ? temp + 1 : min); - } - } - } - dp[i] = min; - } - return dp[target]; - } -} diff --git a/src/Q215KthLargestElementinanArray.java b/src/Q215KthLargestElementinanArray.java index 07f55c0..da7a2de 100644 --- a/src/Q215KthLargestElementinanArray.java +++ b/src/Q215KthLargestElementinanArray.java @@ -122,32 +122,32 @@ public static int quickSelect(int[] nums, int k, int left, int right) { /** * 同样的快速选择算法 但是在paartition操作中使用了双指针技术,所以会更快一点 - * */ + */ public static int findKthLargestV(int[] nums, int k) { - return quickSelectII(nums, nums.length-k, 0, nums.length-1); + return quickSelectII(nums, nums.length - k, 0, nums.length - 1); } - private static int quickSelectII(int[] nums, int k, int left, int right){ + private static int quickSelectII(int[] nums, int k, int left, int right) { // 递归的终止条件,同样也是 - if(left>=right){ + if (left >= right) { return nums[left]; } // 随机化 - int index = (left+right)/2; + int index = (left + right) / 2; int pivot = nums[index]; int low = left, high = right; // partition 操作 - while(low<=high){ + while (low <= high) { // 如果左边比pivot小,左边不断增加,直到大于pivot - while(low<=high && nums[low]pivot){ + while (low <= high && nums[high] > pivot) { high--; } // 交换high与low - if(low<=high){ + if (low <= high) { int tmp = nums[low]; nums[low] = nums[high]; nums[high] = tmp; @@ -156,13 +156,11 @@ private static int quickSelectII(int[] nums, int k, int left, int right){ } } // 针对K进行递归,由于K是对nums的下标来说的,所以K不用变 - if(k>=low && k<=right){ + if (k >= low && k <= right) { return quickSelectII(nums, k, low, right); - } - else if(k>=left && k<=high){ + } else if (k >= left && k <= high) { return quickSelectII(nums, k, left, high); - } - else{ + } else { return nums[k]; } } diff --git a/src/Q50Pow.java b/src/Q50Pow.java new file mode 100644 index 0000000..0681035 --- /dev/null +++ b/src/Q50Pow.java @@ -0,0 +1,28 @@ +/** + * @author ahscuml + * @date 2019/4/1 + * @time 22:12 + */ +public class Q50Pow { + /** + * 测试函数 + */ + public static void main(String[] args) { + + } + + /** + * 非常奇葩的一道题,还要考虑到n是最小值的问题 + */ + public double myPow(double x, int n) { + if (n == 0) return 1; + if (n == Integer.MIN_VALUE) { + return myPow(1 / (x * x), -(n / 2)); + } + if (n < 0) { + n = -n; + x = 1 / x; + } + return n % 2 == 0 ? myPow(x * x, n / 2) : x * myPow(x * x, n / 2); + } +} From 624b7e44c05e8560c4726fa8f0f41e7bcae7e251 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Fri, 5 Apr 2019 16:35:40 +0800 Subject: [PATCH 14/33] =?UTF-8?q?=E4=BF=AE=E6=94=B9TreeNode=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E8=A1=A8=E7=A4=BA=E5=BD=A2=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Q100SameTree.java | 28 +++++--------- src/Q101SymmetricTree.java | 12 +----- src/Q102BinaryTreeLevelOrderTraversal.java | 15 +------- ...03BinaryTreeZigzagLevelOrderTraversal.java | 15 +------- src/Q104MaximumDepthofBinaryTree.java | 12 +----- ...ryTreefromPreorderandInorderTraversal.java | 19 ++-------- ...8ConvertSortedArraytoBinarySearchTree.java | 25 ++++-------- src/Q112PathSum.java | 15 +------- src/Q113PathSumII.java | 15 +------- src/Q114FlattenBinaryTreetoLinkedList.java | 24 ++++-------- src/Q226InvertBinaryTree.java | 12 +----- src/Q437PathSumIII.java | 12 +----- src/Q538ConvertBSTtoGreaterTree.java | 15 +------- src/Q543DiameterofBinaryTree.java | 15 +------- src/Q572SubtreeofAnotherTree.java | 15 +------- src/Q617MergeTwoBinaryTrees.java | 38 +++++++------------ src/Q94BinaryTreeInorderTraversal.java | 12 +----- src/Q98ValidateBinarySearchTree.java | 16 ++------ src/TEST/InOrder.java | 15 +------- src/TEST/LevelOrder.java | 16 +------- src/TEST/PostOrder.java | 15 +------- src/TEST/PreOrder.java | 15 +------- 22 files changed, 76 insertions(+), 300 deletions(-) diff --git a/src/Q100SameTree.java b/src/Q100SameTree.java index f431c58..8ba2f7d 100644 --- a/src/Q100SameTree.java +++ b/src/Q100SameTree.java @@ -1,3 +1,5 @@ +import util.TreeNode; + import java.util.LinkedList; import java.util.Queue; @@ -9,7 +11,7 @@ public class Q100SameTree { /** * 测试函数 - * */ + */ public static void main(String[] args) { TreeNode p1 = new TreeNode(1); TreeNode p2 = new TreeNode(2); @@ -23,13 +25,13 @@ public static void main(String[] args) { q1.left = q2; q1.right = q3; - System.out.println(isSameTreeRec(p1,q1)); - System.out.println(isSameTreeIte(p1,q1)); + System.out.println(isSameTreeRec(p1, q1)); + System.out.println(isSameTreeIte(p1, q1)); } /** * 递归的方法遍历这两个树 - * */ + */ public static boolean isSameTreeRec(TreeNode p, TreeNode q) { if (p == null && q == null) return true; if (p == null && q != null || p != null && q == null) return false; @@ -39,17 +41,17 @@ public static boolean isSameTreeRec(TreeNode p, TreeNode q) { /** * 循环的方法来遍历树,同时只使用一个queue非常简洁,但是对于null的判断会增加时间复杂度。 - * */ + */ public static boolean isSameTreeIte(TreeNode p, TreeNode q) { Queue queue = new LinkedList<>(); queue.add(p); queue.add(q); - while(!queue.isEmpty()){ + while (!queue.isEmpty()) { TreeNode f = queue.poll(); TreeNode s = queue.poll(); - if(f == null && s == null){ + if (f == null && s == null) { continue; - }else if(f == null || s == null || f.val != s.val){ + } else if (f == null || s == null || f.val != s.val) { return false; } queue.add(f.left); @@ -59,14 +61,4 @@ public static boolean isSameTreeIte(TreeNode p, TreeNode q) { } return true; } - - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } } diff --git a/src/Q101SymmetricTree.java b/src/Q101SymmetricTree.java index ec98303..34447f4 100644 --- a/src/Q101SymmetricTree.java +++ b/src/Q101SymmetricTree.java @@ -1,3 +1,5 @@ +import util.TreeNode; + import java.util.Stack; /** @@ -114,14 +116,4 @@ private static boolean isSymmetricIte(TreeNode root) { } return true; } - - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } } diff --git a/src/Q102BinaryTreeLevelOrderTraversal.java b/src/Q102BinaryTreeLevelOrderTraversal.java index 052ad23..a922d25 100644 --- a/src/Q102BinaryTreeLevelOrderTraversal.java +++ b/src/Q102BinaryTreeLevelOrderTraversal.java @@ -1,3 +1,5 @@ +import util.TreeNode; + import java.util.ArrayList; import java.util.LinkedList; import java.util.Queue; @@ -95,17 +97,4 @@ private static void depth(TreeNode root, int depth, ArrayList depth(root.left, depth + 1, list); depth(root.right, depth + 1, list); } - - /** - * 树结构的定义 - */ - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } } diff --git a/src/Q103BinaryTreeZigzagLevelOrderTraversal.java b/src/Q103BinaryTreeZigzagLevelOrderTraversal.java index 73fe2f6..b938a07 100644 --- a/src/Q103BinaryTreeZigzagLevelOrderTraversal.java +++ b/src/Q103BinaryTreeZigzagLevelOrderTraversal.java @@ -1,3 +1,5 @@ +import util.TreeNode; + import java.util.*; /** @@ -140,17 +142,4 @@ private static List> Helper(TreeNode root) { } return res; } - - /** - * 树结构的定义 - */ - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } } diff --git a/src/Q104MaximumDepthofBinaryTree.java b/src/Q104MaximumDepthofBinaryTree.java index 39a780f..f6c5818 100644 --- a/src/Q104MaximumDepthofBinaryTree.java +++ b/src/Q104MaximumDepthofBinaryTree.java @@ -1,3 +1,5 @@ +import util.TreeNode; + import java.util.LinkedList; import java.util.Queue; @@ -86,14 +88,4 @@ private static int maxDepthIte(TreeNode root) { } return level; } - - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } } diff --git a/src/Q105ConstructBinaryTreefromPreorderandInorderTraversal.java b/src/Q105ConstructBinaryTreefromPreorderandInorderTraversal.java index c3c59f4..8fdf60b 100644 --- a/src/Q105ConstructBinaryTreefromPreorderandInorderTraversal.java +++ b/src/Q105ConstructBinaryTreefromPreorderandInorderTraversal.java @@ -1,4 +1,4 @@ -import TEST.InOrder; +import util.TreeNode; import java.util.HashMap; import java.util.Map; @@ -16,7 +16,7 @@ public static void main(String[] args) { int[] preorder = {3, 9, 20, 15, 7}; int[] inorder = {9, 3, 15, 20, 7}; - preorderRec(buildTree(preorder,inorder)); + preorderRec(buildTree(preorder, inorder)); } /** @@ -37,7 +37,7 @@ public static TreeNode buildTree(int[] preorder, int[] inorder) { public static TreeNode buildTree(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd, - Map inMap) { + Map inMap) { if (preStart > preEnd || inStart > inEnd) { return null; } @@ -63,17 +63,4 @@ public static void preorderRec(TreeNode root) { preorderRec(root.right); } } - - /** - * 树结构的定义 - */ - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } } diff --git a/src/Q108ConvertSortedArraytoBinarySearchTree.java b/src/Q108ConvertSortedArraytoBinarySearchTree.java index f7ac3d7..98a68c7 100644 --- a/src/Q108ConvertSortedArraytoBinarySearchTree.java +++ b/src/Q108ConvertSortedArraytoBinarySearchTree.java @@ -1,3 +1,5 @@ +import util.TreeNode; + /** * @author ahscuml * @date 2019/1/4 @@ -6,16 +8,16 @@ public class Q108ConvertSortedArraytoBinarySearchTree { /** * 测试函数 - * */ + */ public static void main(String[] args) { } /** * 利用递归的方法来说实现 - * */ + */ public TreeNode sortedArrayToBST(int[] nums) { - if(nums == null || nums.length == 0) { + if (nums == null || nums.length == 0) { return null; } // 节点个数可能是奇数或者偶数,需要进行判断 @@ -23,8 +25,8 @@ public TreeNode sortedArrayToBST(int[] nums) { return helper(nums, 0, n - 1); } - public TreeNode helper(int[] nums, int left ,int right) { - if(right < left) { + public TreeNode helper(int[] nums, int left, int right) { + if (right < left) { return null; } int mid = (right + left) / 2; @@ -33,17 +35,4 @@ public TreeNode helper(int[] nums, int left ,int right) { root.right = helper(nums, mid + 1, right); return root; } - - /** - * 树结构的定义 - * */ - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } } diff --git a/src/Q112PathSum.java b/src/Q112PathSum.java index 86194d0..b998a55 100644 --- a/src/Q112PathSum.java +++ b/src/Q112PathSum.java @@ -1,3 +1,5 @@ +import util.TreeNode; + import java.util.Stack; /** @@ -68,17 +70,4 @@ public static boolean hasPathSumIte(TreeNode root, int sum) { } return false; } - - /** - * 树结构的定义 - */ - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } } diff --git a/src/Q113PathSumII.java b/src/Q113PathSumII.java index 18e70fe..10e190a 100644 --- a/src/Q113PathSumII.java +++ b/src/Q113PathSumII.java @@ -1,3 +1,5 @@ +import util.TreeNode; + import java.util.ArrayList; import java.util.List; import java.util.Stack; @@ -99,17 +101,4 @@ public static List> pathSumIte(TreeNode root, int sum) { return res; } - - /** - * 树结构的定义 - */ - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } } diff --git a/src/Q114FlattenBinaryTreetoLinkedList.java b/src/Q114FlattenBinaryTreetoLinkedList.java index d48f1a7..d34051e 100644 --- a/src/Q114FlattenBinaryTreetoLinkedList.java +++ b/src/Q114FlattenBinaryTreetoLinkedList.java @@ -1,3 +1,5 @@ +import util.TreeNode; + import java.util.Stack; /** @@ -8,6 +10,11 @@ * @time 9:40 */ public class Q114FlattenBinaryTreetoLinkedList { + /** + * 和我的思路一样,但是非常简单的写法 + */ + private TreeNode prev = null; + // TODO 增加测试用例; public static void main(String[] args) { @@ -45,10 +52,6 @@ public void flatten(TreeNode root) { } } - /** - * 和我的思路一样,但是非常简单的写法 - */ - private TreeNode prev = null; public void flattenEasy(TreeNode root) { if (root == null) return; @@ -82,17 +85,4 @@ public void flattenIte(TreeNode root) { cur.left = null; } } - - /** - * 树结构的定义 - */ - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } } diff --git a/src/Q226InvertBinaryTree.java b/src/Q226InvertBinaryTree.java index a3d4c6e..15c7de1 100644 --- a/src/Q226InvertBinaryTree.java +++ b/src/Q226InvertBinaryTree.java @@ -1,3 +1,5 @@ +import util.TreeNode; + import java.util.LinkedList; import java.util.Queue; @@ -91,14 +93,4 @@ private static TreeNode invertTreeIte(TreeNode root) { } return root; } - - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } } diff --git a/src/Q437PathSumIII.java b/src/Q437PathSumIII.java index e2719f5..49e5b3c 100644 --- a/src/Q437PathSumIII.java +++ b/src/Q437PathSumIII.java @@ -1,3 +1,5 @@ +import util.TreeNode; + import java.util.HashMap; /** @@ -45,14 +47,4 @@ public static int helper(TreeNode root, int currSum, int target, HashMap inorderTraversal2(TreeNode root) { } return res; } - - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } } diff --git a/src/Q98ValidateBinarySearchTree.java b/src/Q98ValidateBinarySearchTree.java index 6685824..c78e278 100644 --- a/src/Q98ValidateBinarySearchTree.java +++ b/src/Q98ValidateBinarySearchTree.java @@ -1,7 +1,10 @@ +import util.TreeNode; + import java.util.Stack; /** * 二叉搜索树是不是合理的 + * * @author ahscuml * @date 2018/12/28 * @time 16:34 @@ -54,17 +57,4 @@ public boolean isValidBSTIte(TreeNode root) { } return true; } - - /** - * 树结构的定义 - */ - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } } diff --git a/src/TEST/InOrder.java b/src/TEST/InOrder.java index f5c0651..76ef4f6 100644 --- a/src/TEST/InOrder.java +++ b/src/TEST/InOrder.java @@ -1,5 +1,7 @@ package TEST; +import util.TreeNode; + import java.util.Stack; /** @@ -71,17 +73,4 @@ private static void inOrderIte(TreeNode root) { } } } - - /** - * 树结构的定义 - */ - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } } diff --git a/src/TEST/LevelOrder.java b/src/TEST/LevelOrder.java index 03bee31..70957d1 100644 --- a/src/TEST/LevelOrder.java +++ b/src/TEST/LevelOrder.java @@ -1,5 +1,7 @@ package TEST; +import util.TreeNode; + import java.util.LinkedList; import java.util.Queue; @@ -153,18 +155,4 @@ public static void levelOrderIte(TreeNode root) { } } } - - - /** - * 树结构的定义 - */ - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } } diff --git a/src/TEST/PostOrder.java b/src/TEST/PostOrder.java index 7d5f9ed..b40595c 100644 --- a/src/TEST/PostOrder.java +++ b/src/TEST/PostOrder.java @@ -1,5 +1,7 @@ package TEST; +import util.TreeNode; + import java.util.Stack; /** @@ -80,17 +82,4 @@ private static void postOrderIte(TreeNode root) { System.out.print(output.pop().val); } } - - /** - * 树结构的定义 - */ - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } } diff --git a/src/TEST/PreOrder.java b/src/TEST/PreOrder.java index 15604d1..1d2ed9d 100644 --- a/src/TEST/PreOrder.java +++ b/src/TEST/PreOrder.java @@ -1,5 +1,7 @@ package TEST; +import util.TreeNode; + import java.util.Stack; /** @@ -73,17 +75,4 @@ public static void preorderIte(TreeNode root) { } } } - - /** - * 树结构的定义 - */ - public static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int x) { - val = x; - } - } } From 96a956a51b35d1ff7af19fee89ee7a7d8522629c Mon Sep 17 00:00:00 2001 From: ahscuml Date: Sun, 7 Apr 2019 19:10:03 +0800 Subject: [PATCH 15/33] =?UTF-8?q?=E6=96=B0=E5=A2=9E95=E5=92=8C10=E9=A2=98?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E4=BA=8664=E9=A2=98=E7=9A=84?= =?UTF-8?q?=E6=99=AE=E9=80=9A=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +- src/Q10RegularExpressionMatching.java | 46 +++++++++++++ src/Q64MinimumPathSum.java | 33 ++++++++-- src/Q95UniqueBinarySearchTreesII.java | 95 +++++++++++++++++++++++++++ 4 files changed, 172 insertions(+), 5 deletions(-) create mode 100644 src/Q10RegularExpressionMatching.java create mode 100644 src/Q95UniqueBinarySearchTreesII.java diff --git a/README.md b/README.md index 3e10177..bf882eb 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ Medium [61](https://leetcode.com/problems/rotate-list/description/) | [Rotate List](/src/Q61RotateList.java) | LinkedList、双指针 | :star: [62](https://leetcode.com/problems/unique-paths/description/) | [Unique Paths](/src/Q62UniquePaths.java) | 二维数组、动态规划 | :star: :star: :star: [63](https://leetcode.com/problems/unique-paths-ii/description/) | [Unique Paths II](/src/Q63UniquePathsII.java) | 二维数组、动态规划 | :star: :star: :star: -[64](https://leetcode.com/problems/minimum-path-sum/description/) | [Minimum Path Sum](/src/Q64MinimumPathSum.java) | 二维数组、动态规划 | :star: :star: :star: +[64](https://leetcode.com/problems/minimum-path-sum/description/) | [Minimum Path Sum](/src/Q64MinimumPathSum.java) | 二维数组、动态规划 | :star: :star: :star: :star: [74](https://leetcode.com/problems/search-a-2d-matrix/) | [Search a 2D Matrix](/src/Q74Searcha2DMatrix.java) | 二分查找 | :star: :star: [77](https://leetcode.com/problems/combinations/description/) | [Combinations](/src/Q77Combinations.java) | 回溯法 | :star: :star: :star: [78](https://leetcode.com/problems/subsets/description/) | [Subsets](/src/Q78Subsets.java) | Array、回溯法 | :star: :star: :star: @@ -131,6 +131,7 @@ Hard 题号|题目|Tags|Star|Company| ---|---|--- |--- | ---| [4](https://leetcode.com/problems/median-of-two-sorted-arrays/) | [Median of Two Sorted Arrays](/src/Q4MedianofTwoSortedArrays.java) | 分治思想、二分查找 | :star: :star: :star: +[10](https://leetcode.com/problems/regular-expression-matching/) | [Regular Expression Matching](/src/Q10RegularExpressionMatching.java) | DP | :star: :star: :star: [23](https://leetcode.com/problems/merge-k-sorted-lists/) | [Merge k Sorted Lists](/src/Q23MergekSortedLists.java) | ListNode,归并排序,优先队列 | :star: :star: :star: :star: [123](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/) | [Best Time to Buy and Sell Stock III](/src/Q123BestTimetoBuyandSellStockIII.java) | DP、状态机 | :star: :star: :star: [124](https://leetcode.com/problems/binary-tree-maximum-path-sum/) | [Binary Tree Maximum Path Sum](/src/Q124BinaryTreeMaximumPathSum.java) | Tree,递归 | :star: :star: :star: diff --git a/src/Q10RegularExpressionMatching.java b/src/Q10RegularExpressionMatching.java new file mode 100644 index 0000000..dd43a09 --- /dev/null +++ b/src/Q10RegularExpressionMatching.java @@ -0,0 +1,46 @@ +/** + * @author ahscuml + * @date 2019/4/7 + * @time 0:04 + */ +public class Q10RegularExpressionMatching { + public static void main(String[] args) { + // TODO 测试用例 + } + + public static boolean isMatch(String s, String p) { + boolean[][] dp = new boolean[s.length() + 1][p.length() + 1]; + // 初始化,当模式串为0的时候,除了0,0为true,其余都为false + dp[0][0] = true; + // 当s为0的时候,如果模式串带有*还可能为空,保证前面一个不是* + for(int j = 2; j <= p.length(); j++) { + if(p.charAt(j - 1) == '*' && j > 1 && p.charAt(j - 2) != '*') { + dp[0][j] = dp[0][j - 2]; + } + } + + for(int i = 1; i <= s.length(); i++) { + for(int j = 1; j <= p.length(); j++) { + // 首先确定如果相等的情况 + if(s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '.') { + // 匹配的情况 + dp[i][j] = dp[i - 1][j - 1]; + } + // 不匹配的情况,1. 真的不匹配,不用管,因为默认是false + // 2. 出现'*' + if(p.charAt(j - 1) == '*') { + if(s.charAt(i - 1) != p.charAt(j - 2) && p.charAt(j - 2) != '.') { + // 不匹配任何内容,那么x*只能为空 + dp[i][j] = dp[i][j - 2]; + } else { + // 2.1 x*不匹配任何内容,直接跳过 + // 2.2 x*匹配一个内容 + // 2.3 x*匹配很多个内容 + dp[i][j] = dp[i][j - 2] || dp[i][j - 1] || dp[i - 1][j]; + } + } + } + } + return dp[s.length()][p.length()]; + } +} diff --git a/src/Q64MinimumPathSum.java b/src/Q64MinimumPathSum.java index a84c9b3..70743ee 100644 --- a/src/Q64MinimumPathSum.java +++ b/src/Q64MinimumPathSum.java @@ -9,20 +9,21 @@ public static void main(String[] args) { {1, 5, 1}, {4, 2, 1}}; System.out.println(minPathSum(nums)); + System.out.println(minPathSumII(nums)); } /** * 依旧使用动态规划,和62,63一样的想法。 * 可以不使用额外的存储空间,直接将内容存储到matrix中,可以试试这个想法。 - * */ + */ public static int minPathSum(int[][] matrix) { int n = matrix[0].length; int[] aux = new int[n]; - for(int i = 0; i < matrix.length; i++) { - for(int j = 0; j < n; j++) { + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < n; j++) { if (j == 0) { aux[j] = aux[j] + matrix[i][j]; - } else if(i == 0){ + } else if (i == 0) { aux[j] = aux[j - 1] + matrix[i][j]; } else { aux[j] = matrix[i][j] + Math.min(aux[j - 1], aux[j]); @@ -31,4 +32,28 @@ public static int minPathSum(int[][] matrix) { } return aux[n - 1]; } + + /** + * 动态规划的方法,只不过采用的是二维的数组,最基本的想法 + * 注意创建辅助数组的时候的长度以及创建完成以后首先对00赋值 + */ + public static int minPathSumII(int[][] grid) { + if (grid.length == 0 || grid[0].length == 0) { + return 0; + } + int[][] dp = new int[grid.length][grid[0].length]; + dp[0][0] = grid[0][0]; + for (int i = 1; i < grid.length; i++) { + dp[i][0] = grid[i][0] + dp[i - 1][0]; + } + for (int i = 1; i < grid[0].length; i++) { + dp[0][i] = grid[0][i] + dp[0][i - 1]; + } + for (int i = 1; i < grid.length; i++) { + for (int j = 1; j < grid[0].length; j++) { + dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]; + } + } + return dp[grid.length - 1][grid[0].length - 1]; + } } diff --git a/src/Q95UniqueBinarySearchTreesII.java b/src/Q95UniqueBinarySearchTreesII.java new file mode 100644 index 0000000..593398b --- /dev/null +++ b/src/Q95UniqueBinarySearchTreesII.java @@ -0,0 +1,95 @@ +import util.TreeNode; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author ahscuml + * @date 2019/4/5 + * @time 15:46 + */ +public class Q95UniqueBinarySearchTreesII { + public static void main(String[] args) { + //TODO 测试用例 + } + + /** + * 优化后的方法,也就是利用动态规划的特性,用空间换时间,将之前的内容存储起来 + * 同时应用了一个小trick,左子树可以直接从之前的子树移动过来。 + */ + public static List generateTreesII(int n) { + List[] res = new List[n + 1]; + res[0] = new ArrayList<>(); + if (n == 0) { + return res[0]; + } + // 赋值空 + res[0].add(null); + // 1-i产生的结果 + for (int i = 1; i <= n; i++) { + res[i] = new ArrayList(); + // j是左子树的元素个数 + for (int j = 0; j < i; j++) { + for (TreeNode left : res[j]) { + for (TreeNode right : res[i - j - 1]) { + // 根节点的值 + TreeNode root = new TreeNode(j + 1); + root.left = left; + root.right = clone(right, j + 1); + res[i].add(root); + } + } + } + } + return res[n]; + } + + /** + * 节省空间,将从1开始的子树通过加上offset拷贝过来。因为右子树是从 offset + 1 开始的 + */ + public static TreeNode clone(TreeNode n, int offset) { + if (n == null) { + return null; + } + TreeNode node = new TreeNode(n.val + offset); + node.left = clone(n.left, offset); + node.right = clone(n.right, offset); + return node; + } + + /** + * 暴力解法:通过辅助函数来完成(依然打败了63%) + * 缺点是没有利用之前存储的内容来进行计算 + */ + public List generateTrees(int n) { + List res = new ArrayList<>(); + if (n == 0) { + return res; + } + return generateHelper(1, n); + } + + /** + * 辅助函数的主要思路是分别得出左右子树的可能性,然后将这些子树拼接到一起,加入结果集 + */ + public List generateHelper(int s, int e) { + List res = new ArrayList<>(); + if (s > e) { + res.add(null); + return res; + } + for (int i = s; i <= e; i++) { + List left = generateHelper(s, i - 1); + List right = generateHelper(i + 1, e); + for (TreeNode l : left) { + for (TreeNode r : right) { + TreeNode root = new TreeNode(i); + root.left = l; + root.right = r; + res.add(root); + } + } + } + return res; + } +} From c275bc054ade78bf0c27a0ec539c2aa789990e50 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Mon, 8 Apr 2019 21:29:30 +0800 Subject: [PATCH 16/33] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E4=B8=89?= =?UTF-8?q?=E4=B8=AA=E4=BA=8C=E5=8F=89=E6=A0=91=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + ...03BinaryTreeZigzagLevelOrderTraversal.java | 37 +++++++++- src/Q144BinaryTreePreorderTraversal.java | 17 +++++ ...westCommonAncestorofaBinarySearchTree.java | 48 +++++++++++++ ...Q236LowestCommonAncestorofaBinaryTree.java | 67 +++++++++++++++++++ 5 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 src/Q144BinaryTreePreorderTraversal.java create mode 100644 src/Q235LowestCommonAncestorofaBinarySearchTree.java create mode 100644 src/Q236LowestCommonAncestorofaBinaryTree.java diff --git a/README.md b/README.md index bf882eb..dbc5f32 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ Easy [217](https://leetcode.com/problems/contains-duplicate/description/) | [Contains Duplicate](/src/Q217ContainsDuplicate.java) | Array、HashTable | :star: [226](https://leetcode.com/problems/invert-binary-tree/) | [Invert Binary Tree](/src/Q226InvertBinaryTree.java) | Tree | :star: :star: :star: [234](https://leetcode.com/problems/palindrome-linked-list/description/) | [Palindrome Linked List](/src/Q234PalindromeLinkedList.java) | LinkedList、双指针 | :star: :star: :star: +[235](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) | [Lowest Common Ancestor of a Binary Search Tree](/src/Q235LowestCommonAncestorofaBinarySearchTree.java) | 递归 | :star: :star: :star: [338](https://leetcode.com/problems/counting-bits/) | [Counting Bits](/src/Q338CountingBits.java) | bits | :star: :star: :star: [401](https://leetcode.com/problems/binary-watch/description/) | [Binary Watch](/src/Q401BinaryWatch.java) | 递归 | :star: [437](https://leetcode.com/problems/path-sum-iii/) | [Path Sum III](/src/Q437PathSumIII.java) | HashMap,Tree | :star: :star: :star: @@ -104,6 +105,7 @@ Medium [215](https://leetcode.com/problems/kth-largest-element-in-an-array/description/) | [Kth Largest Element in an Array](/src/Q215KthLargestElementinanArray.java) | Array、快速选择算法 | :star: :star: :star: :star: | ihandy,ByteDance [216](https://leetcode.com/problems/combination-sum-iii/description/) | [CombinationSumIII](/src/Q216CombinationSumIII.java) | Array、回溯法 | :star: :star: :star: [221](https://leetcode.com/problems/maximal-square/) | [Maximal Square](/src/Q221MaximalSquare.java) | DP | :star: :star: :star: +[236](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) | [Lowest Common Ancestor of a Binary Tree](/src/Q236LowestCommonAncestorofaBinaryTree.java) | 递归 | :star: :star: :star: :star: | ByteDance [238](https://leetcode.com/problems/product-of-array-except-self/description/) | [Product of Array Except Self](/src/Q238ProductofArrayExceptSelf.java) | Array [240](https://leetcode.com/problems/search-a-2d-matrix-ii/) | [Search a 2D Matrix II](/src/Q240Searcha2DMatrixII.java) | | :star: :star: :star: [264](https://leetcode.com/problems/ugly-number-ii/) | [Ugly NumberII](/src/Q264UglyNumberII.java) | DP | :star: :star: diff --git a/src/Q103BinaryTreeZigzagLevelOrderTraversal.java b/src/Q103BinaryTreeZigzagLevelOrderTraversal.java index b938a07..86cb24f 100644 --- a/src/Q103BinaryTreeZigzagLevelOrderTraversal.java +++ b/src/Q103BinaryTreeZigzagLevelOrderTraversal.java @@ -74,7 +74,6 @@ public static List> zigzagLevelOrderIte(TreeNode root) { return res; } - /** * 递归的算法 */ @@ -142,4 +141,40 @@ private static List> Helper(TreeNode root) { } return res; } + + /** + * 利用Collection.reverse函数来实现 + */ + public static List> zigzagLevelOrder(TreeNode root) { + List> res = new ArrayList<>(); + if (root == null) { + return res; + } + List curList = new ArrayList(); + Queue queue = new LinkedList(); + queue.offer(root); + TreeNode cur = null; + boolean iszigzag = false; + while (!queue.isEmpty()) { + int size = queue.size(); + ArrayList list = new ArrayList(); + while (size != 0) { + cur = queue.poll(); + list.add(cur.val); + if (cur.left != null) { + queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + size--; + } + if (iszigzag) { + Collections.reverse(list); + } + res.add(list); + iszigzag = !iszigzag; + } + return res; + } } diff --git a/src/Q144BinaryTreePreorderTraversal.java b/src/Q144BinaryTreePreorderTraversal.java new file mode 100644 index 0000000..a6080e6 --- /dev/null +++ b/src/Q144BinaryTreePreorderTraversal.java @@ -0,0 +1,17 @@ +/** + * @author ahscuml + * @date 2019/4/8 + * @time 18:38 + */ +public class Q144BinaryTreePreorderTraversal { + /** + *测试函数 + * */ + public static void main(String[] args) { + // TODO + } + + /** + * 树的前序遍历,没那么复杂 + * */ +} diff --git a/src/Q235LowestCommonAncestorofaBinarySearchTree.java b/src/Q235LowestCommonAncestorofaBinarySearchTree.java new file mode 100644 index 0000000..df4a6fa --- /dev/null +++ b/src/Q235LowestCommonAncestorofaBinarySearchTree.java @@ -0,0 +1,48 @@ +import util.TreeNode; + +/** + * 二叉搜索树的公共祖先 + * + * @author ahscuml + * @date 2019/4/8 + * @time 20:19 + */ +public class Q235LowestCommonAncestorofaBinarySearchTree { + /** + * 测试函数 + */ + public static void main(String[] args) { + // TODO + } + + /** + * 利用BST的特点 + * 利用树递归的性质 + */ + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root == null) { + return null; + } + if (p.val < root.val && q.val < root.val) { + return lowestCommonAncestor(root.left, p, q); + } else if (p.val > root.val && q.val > root.val) { + return lowestCommonAncestor(root.right, p, q); + } else { + return root; + } + } + + /** + * 利用循环的方法 + */ + public TreeNode lowestCommonAncestorIte(TreeNode root, TreeNode p, TreeNode q) { + while (true) { + if (root == null || (root.val - p.val) * (root.val - q.val) <= 0) return root; + if (p.val < root.val) { + root = root.left; + } else { + root = root.right; + } + } + } +} diff --git a/src/Q236LowestCommonAncestorofaBinaryTree.java b/src/Q236LowestCommonAncestorofaBinaryTree.java new file mode 100644 index 0000000..2268a94 --- /dev/null +++ b/src/Q236LowestCommonAncestorofaBinaryTree.java @@ -0,0 +1,67 @@ +import util.TreeNode; + +import java.util.*; + +/** + * 二叉树最近公共祖先 + * + * @author ahscuml + * @date 2019/4/8 + * @time 19:44 + */ +public class Q236LowestCommonAncestorofaBinaryTree { + /** + * 测试函数 + */ + public static void main(String[] args) { + // TODO + } + + /** + * 循环的方法,记录祖先 + */ + public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + Map parent = new HashMap<>(); + Deque stack = new ArrayDeque<>(); + parent.put(root, null); + stack.push(root); + + while (!parent.containsKey(p) || !parent.containsKey(q)) { + TreeNode node = stack.pop(); + if (node.left != null) { + parent.put(node.left, node); + stack.push(node.left); + } + if (node.right != null) { + parent.put(node.right, node); + stack.push(node.right); + } + } + Set ancestors = new HashSet<>(); + while (p != null) { + ancestors.add(p); + p = parent.get(p); + } + while (!ancestors.contains(q)) + q = parent.get(q); + return q; + } + + /** + * 递归的方法 + */ + public TreeNode lowestCommonAncestorRec(TreeNode root, TreeNode p, TreeNode q) { + if (root == null || root == p || root == q) { + return root; + } + TreeNode left = lowestCommonAncestorRec(root.left, p, q); + TreeNode right = lowestCommonAncestorRec(root.right, p, q); + if (left == null) { + return right; + } + if (right == null) { + return left; + } + return root; + } +} From 4b15137098615359f4eb57c61dc0e836a414b967 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Tue, 9 Apr 2019 00:06:40 +0800 Subject: [PATCH 17/33] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86LRU=E7=9A=84?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + src/Q146LRUCache.java | 107 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 src/Q146LRUCache.java diff --git a/README.md b/README.md index dbc5f32..3b2f931 100644 --- a/README.md +++ b/README.md @@ -137,4 +137,5 @@ Hard [23](https://leetcode.com/problems/merge-k-sorted-lists/) | [Merge k Sorted Lists](/src/Q23MergekSortedLists.java) | ListNode,归并排序,优先队列 | :star: :star: :star: :star: [123](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/) | [Best Time to Buy and Sell Stock III](/src/Q123BestTimetoBuyandSellStockIII.java) | DP、状态机 | :star: :star: :star: [124](https://leetcode.com/problems/binary-tree-maximum-path-sum/) | [Binary Tree Maximum Path Sum](/src/Q124BinaryTreeMaximumPathSum.java) | Tree,递归 | :star: :star: :star: +[146](https://leetcode.com/problems/lru-cache/) | [LRU Cache](/src/Q146LRUCache.java) | LRU,HashMap,LinkedHashMap | :star: :star: :star: | ByteDance [188](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/) | [Best Time to Buy and Sell Stock IV](/src/Q188BestTimetoBuyandSellStockIV.java) | DP | :star: :star: :star: \ No newline at end of file diff --git a/src/Q146LRUCache.java b/src/Q146LRUCache.java new file mode 100644 index 0000000..d7feb6f --- /dev/null +++ b/src/Q146LRUCache.java @@ -0,0 +1,107 @@ +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author ahscuml + * @date 2019/4/8 + * @time 23:58 + */ +class LRUCache { + // 定义LRUCache的一些常量参数 + final Node head = new Node(0, 0); + final Node tail = new Node(0, 0); + final HashMap map; + final int capacity; + + // 对于LRU初始化 + public LRUCache(int capacity) { + this.capacity = capacity; + map = new HashMap(capacity); + head.next = tail; + tail.pre = head; + } + + // 插入一个元素到队列的头结点 + private void insertToHead(Node node) { + node.next = head.next; + node.next.pre = node; + head.next = node; + node.pre = head; + } + + // 从队列里删除一个节点 + private void remove(Node node) { + node.pre.next = node.next; + node.next.pre = node.pre; + } + + public int get(int key) { + if (map.containsKey(key)) { + Node node = map.get(key); + remove(node); + insertToHead(node); + return node.val; + } else { + return -1; + } + } + + public void put(int key, int value) { + if (map.containsKey(key)) { + Node node = map.get(key); + remove(node); + node.val = value; + insertToHead(node); + } else { + if (map.size() == capacity) { + map.remove(tail.pre.key); + // 只有到达容量的时候才移动 + remove(tail.pre); + } + Node node = new Node(key, value); + map.put(key, node); + insertToHead(node); + } + } + + // 创建一个node对象,方便进行插入删除 + // 这一一个双端队列 + class Node { + Node pre, next; + int key, val; + + Node(int key, int val) { + this.key = key; + this.val = val; + } + } +} + + + + +/** + * 采用LinkedHashMap的方式,非常简单。 + * */ +class LRUCacheII { + private final int CAPACITY; + private LinkedHashMap map; + + public LRUCacheII(int capacity) { + CAPACITY = capacity; + map = new LinkedHashMap(capacity, 0.75f, true) { + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > CAPACITY; + } + }; + } + + public int get(int key) { + return map.getOrDefault(key, -1); + } + + public void put(int key, int value) { + map.put(key, value); + } +} \ No newline at end of file From 873e8154c805072bf0491dab1d311e7b696e5b34 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Tue, 9 Apr 2019 00:33:53 +0800 Subject: [PATCH 18/33] 343 --- README.md | 1 + src/Q343IntegerBreak.java | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/Q343IntegerBreak.java diff --git a/README.md b/README.md index 3b2f931..b072f59 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,7 @@ Medium [322](https://leetcode.com/problems/coin-change/) | [Coin Change](/src/Q322CoinChange.java) | DP | :star: :star: :star: :star: [334](https://leetcode.com/problems/increasing-triplet-subsequence/) | [Increasing Triplet Subsequence](/src/Q334IncreasingTripletSubsequence.java) | | :star: :star: [337](https://leetcode.com/problems/house-robber-iii/) | [House Robber III](/src/Q337HouseRobberIII.java) | HashMap、DP | :star: :star: :star: +[343](https://leetcode.com/problems/integer-break/) | [Integer Break](/src/Q343IntegerBreak.java) | DP | :star: :star: [347](https://leetcode.com/problems/top-k-frequent-elements/) | [Top K Frequent Elements](/src/Q347TopKFrequentElements.java) | HashMap | :star: :star: :star: [357](https://leetcode.com/problems/count-numbers-with-unique-digits/description/) | [Count Numbers with Unique Digits](/src/Q357CountNumberswithUniqueDigits.java) | DP、回溯 | :star: :star: :star: [416](https://leetcode.com/problems/partition-equal-subset-sum/) | [Partition Equal Subset Sum](/src/Q416PartitionEqualSubsetSum.java) | DP | :star: :star: :star: :star: diff --git a/src/Q343IntegerBreak.java b/src/Q343IntegerBreak.java new file mode 100644 index 0000000..661f8bc --- /dev/null +++ b/src/Q343IntegerBreak.java @@ -0,0 +1,28 @@ +/** + * @author ahscuml + * @date 2019/4/9 + * @time 0:27 + */ +public class Q343IntegerBreak { + public static void main(String[] args) { + integerBreak(10); + } + + /** + * 需要特殊考虑2和3 + * */ + public static int integerBreak(int n) { + // 这个一看就是动态规划的问题 + // 行就是数字n,列就是最大的乘积 + int[] dp = new int[n + 1]; + dp[0] = 1; + dp[1] = 1; + for (int i = 2; i <= n; i++) { + for (int j = 1; j <= i / 2; j++) { + dp[i] = Math.max(Math.max(dp[i], dp[j] * dp[i - j]), i); + } + System.out.print(dp[i] + " "); + } + return dp[n]; + } +} From 403e464f2a3582f2052892d5cbcbe8769e86e773 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Tue, 9 Apr 2019 00:45:57 +0800 Subject: [PATCH 19/33] =?UTF-8?q?=E8=A1=A5=E5=85=85=E4=BA=86=E4=B8=A4?= =?UTF-8?q?=E9=81=93=E5=81=9A=E8=BF=87=E7=9A=84DP=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/Q279PerfectSquares.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b072f59..9be011f 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ Medium [103](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/) | [Binary Tree Zigzag Level Order Traversal](/src/Q103BinaryTreeZigzagLevelOrderTraversal.java) | Tree | :star: :star: :star: | ByteDance [113](https://leetcode.com/problems/path-sum-ii/) | [Path Sum II](/src/Q113PathSumII.java) | Tree | :star: :star: [114](https://leetcode.com/problems/flatten-binary-tree-to-linked-list/) | [Flatten Binary Tree to Linked List](/src/Q114FlattenBinaryTreetoLinkedList.java) | Tree、递归 | :star: :star: :star: :star | ByteDance -[120](https://leetcode.com/problems/triangle/) | [Triangle](/src/Q120Triangle.java) | DP | :star: :star: :star: +[120](https://leetcode.com/problems/triangle/) | [Triangle](/src/Q120Triangle.java) | DP | :star: :star: :star: :star: [139](https://leetcode.com/problems/word-break/) | [Word Break](/src/Q139WordBreak.java) | DP | :star: :star: :star: [142](https://leetcode.com/problems/linked-list-cycle-ii/description/) | [Linked List Cycle II](/src/Q142LinkedListCycleII.java) | LinkedList、双指针 | :star: :star: :star: [143](https://leetcode.com/problems/reorder-list/) | [Reorder List](/src/Q143ReorderList.java) | LinkedList | :star: :star: :star: diff --git a/src/Q279PerfectSquares.java b/src/Q279PerfectSquares.java index aa4425d..20f0a41 100644 --- a/src/Q279PerfectSquares.java +++ b/src/Q279PerfectSquares.java @@ -18,14 +18,14 @@ public static void main(String[] args) { * 动态规划方法 * */ public static int numSquares(int n) { - int count[] = new int[n + 1]; - Arrays.fill(count, Integer.MAX_VALUE); - count[0] = 0; + int dp[] = new int[n + 1]; + Arrays.fill(dp, Integer.MAX_VALUE); + dp[0] = 0; for(int i = 1; i <= n; i++) { for(int j = 1; j * j <=i; j++) { - count[i] = Math.min(count[i],count[i - j * j] + 1); + dp[i] = Math.min(dp[i],dp[i - j * j] + 1); } } - return count[n]; + return dp[n]; } } From a79e16ebe1102d509dec50a5d803fa5e9d7df432 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Tue, 9 Apr 2019 00:58:24 +0800 Subject: [PATCH 20/33] =?UTF-8?q?718=20=E4=B8=80=E9=81=93=E7=AE=80?= =?UTF-8?q?=E5=8D=95=E7=9A=84=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92=E9=A2=98?= =?UTF-8?q?=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + src/Q718MaximumLengthofRepeatedSubarray.java | 34 ++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 src/Q718MaximumLengthofRepeatedSubarray.java diff --git a/README.md b/README.md index 9be011f..b4a0766 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ Medium [673](https://leetcode.com/problems/number-of-longest-increasing-subsequence/) | [Number of Longest Increasing Subsequence](/src/Q673NumberofLongestIncreasingSubsequence.java) | DP | :star: :star: [713](https://leetcode.com/problems/subarray-product-less-than-k/description/) | [Subarray Product Less Than K](/src/Q713SubarrayProductLessThanK.java) | 双指针、滑动窗口 | :star: :star: [714](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) | [Best Time to Buy and Sell Stock with Transaction Fee](/src/Q714BestTimetoBuyandSellStockwithTransactionFee.java) | 动态规划、状态机 | :star: :star: :star: +[718](https://leetcode.com/problems/maximum-length-of-repeated-subarray/) | [Maximum Length of Repeated Subarray](/src/Q718MaximumLengthofRepeatedSubarray.java) | DP | | :star: :star: :star: Hard --- diff --git a/src/Q718MaximumLengthofRepeatedSubarray.java b/src/Q718MaximumLengthofRepeatedSubarray.java new file mode 100644 index 0000000..472ebfe --- /dev/null +++ b/src/Q718MaximumLengthofRepeatedSubarray.java @@ -0,0 +1,34 @@ +/** + * @author ahscuml + * @date 2019/4/9 + * @time 0:54 + */ +public class Q718MaximumLengthofRepeatedSubarray { + /** + * 测试函数 + */ + public static void main(String[] args) { + int[] A = {1, 2, 3, 2, 1}; + int[] B = {3, 2, 1, 4, 7}; + System.out.println(findLength(A, B)); + } + + /** + * 动态规划 + * 找到规律,也就是递推关系式很好处理 + */ + public static int findLength(int[] A, int[] B) { + int res = 0; + // DP问题 + int[][] dp = new int[A.length + 1][B.length + 1]; + for (int i = 1; i < dp.length; i++) { + for (int j = 1; j < dp[0].length; j++) { + if (A[i - 1] == B[j - 1]) { + dp[i][j] = dp[i - 1][j - 1] + 1; + res = Math.max(res, dp[i][j]); + } + } + } + return res; + } +} From 2f559bde5f188d4313c6b14b473299fe0ab43bbb Mon Sep 17 00:00:00 2001 From: ahscuml Date: Sat, 13 Apr 2019 11:18:37 +0800 Subject: [PATCH 21/33] =?UTF-8?q?328=E7=AE=80=E5=8D=95=E7=9A=84=E9=93=BE?= =?UTF-8?q?=E8=A1=A8=E9=A2=98=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +- src/Q328OddEvenLinkedList.java | 66 ++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/Q328OddEvenLinkedList.java diff --git a/README.md b/README.md index b4a0766..af5d0bc 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ Medium [300](https://leetcode.com/problems/longest-increasing-subsequence/) | [Longest Increasing Subsequence](/src/Q300LongestIncreasingSubsequence.java) | DP、Binary Search | :star: :star: :star: [309](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) | [Best Time to Buy and Sell Stock with Cooldown](/src/Q309BestTimetoBuyandSellStockwithCooldown.java) | DP、状态机 | :star: :star: :star: [322](https://leetcode.com/problems/coin-change/) | [Coin Change](/src/Q322CoinChange.java) | DP | :star: :star: :star: :star: +[328](https://leetcode.com/problems/odd-even-linked-list/) | [Odd Even Linked List](/src/Q328OddEvenLinkedList.java) | ListNode | :star: :star: [334](https://leetcode.com/problems/increasing-triplet-subsequence/) | [Increasing Triplet Subsequence](/src/Q334IncreasingTripletSubsequence.java) | | :star: :star: [337](https://leetcode.com/problems/house-robber-iii/) | [House Robber III](/src/Q337HouseRobberIII.java) | HashMap、DP | :star: :star: :star: [343](https://leetcode.com/problems/integer-break/) | [Integer Break](/src/Q343IntegerBreak.java) | DP | :star: :star: @@ -128,7 +129,7 @@ Medium [673](https://leetcode.com/problems/number-of-longest-increasing-subsequence/) | [Number of Longest Increasing Subsequence](/src/Q673NumberofLongestIncreasingSubsequence.java) | DP | :star: :star: [713](https://leetcode.com/problems/subarray-product-less-than-k/description/) | [Subarray Product Less Than K](/src/Q713SubarrayProductLessThanK.java) | 双指针、滑动窗口 | :star: :star: [714](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) | [Best Time to Buy and Sell Stock with Transaction Fee](/src/Q714BestTimetoBuyandSellStockwithTransactionFee.java) | 动态规划、状态机 | :star: :star: :star: -[718](https://leetcode.com/problems/maximum-length-of-repeated-subarray/) | [Maximum Length of Repeated Subarray](/src/Q718MaximumLengthofRepeatedSubarray.java) | DP | | :star: :star: :star: +[718](https://leetcode.com/problems/maximum-length-of-repeated-subarray/) | [Maximum Length of Repeated Subarray](/src/Q718MaximumLengthofRepeatedSubarray.java) | DP | :star: :star: :star: Hard --- diff --git a/src/Q328OddEvenLinkedList.java b/src/Q328OddEvenLinkedList.java new file mode 100644 index 0000000..f681dde --- /dev/null +++ b/src/Q328OddEvenLinkedList.java @@ -0,0 +1,66 @@ +import util.ListNode; + +/** + * @author ahscuml + * @date 2019/4/13 + * @time 10:49 + */ +public class Q328OddEvenLinkedList { + /** + * 测试函数 + */ + public static void main(String[] args) { + // TODO + } + + /** + * 重点是循环条件的判断 + * */ + public static ListNode oddEvenListII(ListNode head) { + // 先找到odd和even的开头?? + if(head == null || head.next == null) { + return head; + } + ListNode even = head.next, curOdd = head, curEven = head.next; + while(curEven != null && curEven.next != null) { + curOdd.next = curEven.next; + curOdd = curOdd.next; + curEven.next = curOdd.next; + curEven = curEven.next; + } + curOdd.next = even; + return head; + } + + + /** + * 这个不是这道题的答案,这个是这个题的变种,关注的是listnode中的值 + */ + public ListNode oddEvenList(ListNode head) { + if (head == null || head.next == null) { + return head; + } + boolean isSwaped = false; + ListNode dummyHead = new ListNode(-1); + dummyHead.next = head; + ListNode cur = dummyHead; + do { + isSwaped = false; + cur = dummyHead; + while (cur.next.next != null) { + if (cur.next.val % 2 == 0 && cur.next.next.val % 2 == 1) { + swapNode(cur, cur.next, cur.next.next); + isSwaped = true; + } + cur = cur.next; + } + } while (isSwaped); + return dummyHead.next; + } + + private void swapNode(ListNode pre, ListNode left, ListNode right) { + left.next = right.next; + right.next = left; + pre.next = right; + } +} From 80dacaaae9ac4e737e2145f902f530aded7fefcb Mon Sep 17 00:00:00 2001 From: ahscuml Date: Sat, 13 Apr 2019 17:15:25 +0800 Subject: [PATCH 22/33] =?UTF-8?q?110=EF=BC=8C=E5=88=A4=E6=96=AD=E8=BF=99?= =?UTF-8?q?=E4=B8=AA=E6=A0=91=E6=98=AF=E5=90=A6=E6=BB=A1=E8=B6=B3BST?= =?UTF-8?q?=E7=9A=84=E6=B7=B1=E5=BA=A6=E8=A6=81=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 ++- src/Q110BalancedBinaryTree.java | 68 +++++++++++++++++++++++++++++++++ src/Q206ReverseLinkedList.java | 18 ++++----- 3 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 src/Q110BalancedBinaryTree.java diff --git a/README.md b/README.md index af5d0bc..d846d20 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ Easy [104](https://leetcode.com/problems/maximum-depth-of-binary-tree/description/) | [Maximum Depth of Binary Tree](/src/Q104MaximumDepthofBinaryTree.java) | Tree | :star: :star: :star: [105](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) | [Construct Binary Tree from Preorder and Inorder Traversal](/src/Q105ConstructBinaryTreefromPreorderandInorderTraversal.java) | Tree | :star: :star: :star: [108](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/) | [Convert Sorted Array to Binary Search Tree](/src/Q108ConvertSortedArraytoBinarySearchTree.java) | Tree | :star: :star: :star: +[110](https://leetcode.com/problems/balanced-binary-tree/) | [Balanced Binary Tree](/src/Q110BalancedBinaryTree.java) | Tree,DFS | :star: :star: :star: :star: [111](https://leetcode.com/problems/minimum-depth-of-binary-tree/) | [Minimum Depth of Binary Tree](/src/Q111MinimumDepthofBinaryTree.java) | Tree、递归 | :star: :star: :star: [112](https://leetcode.com/problems/path-sum/) | [Path Sum](/src/Q112PathSum.java) | Tree | :star: :star: [115](https://leetcode.com/problems/min-stack/) | [Min Stack](/src/Q155MinStack.java) | Stack | :star: :star: :star: @@ -33,7 +34,7 @@ Easy [169](https://leetcode.com/problems/majority-element/description/) | [Majority Element](/src/Q169MajorityElement.java) | Array | :star: :star: [198](https://leetcode.com/problems/house-robber/description/) | [House Robber](/src/Q198HouseRobber.java) | Array、DP | :star: :star: :star: [200](https://leetcode.com/problems/number-of-islands/) | [Number of Islands](/src/Q200NumberofIslands.java) | DFS、BFS | :star: :star: :star: -[206](https://leetcode.com/problems/reverse-linked-list/description/) | [Reverse Linked List](/src/Q206ReverseLinkedList.java) | ListNode | :star: :star: :star: +[206](https://leetcode.com/problems/reverse-linked-list/description/) | [Reverse Linked List](/src/Q206ReverseLinkedList.java) | ListNode | :star: :star: :star: :star: [207](https://leetcode.com/problems/course-schedule/) | [Course Schedule](/src/Q207CourseSchedule.java) | DFS、BFS | :star: :star: :star: [217](https://leetcode.com/problems/contains-duplicate/description/) | [Contains Duplicate](/src/Q217ContainsDuplicate.java) | Array、HashTable | :star: [226](https://leetcode.com/problems/invert-binary-tree/) | [Invert Binary Tree](/src/Q226InvertBinaryTree.java) | Tree | :star: :star: :star: @@ -46,7 +47,7 @@ Easy [461](https://leetcode.com/problems/hamming-distance/) | [Hamming Distance](/src/Q461HammingDistance.java) | bits | :star: :star: :star: [538](https://leetcode.com/problems/convert-bst-to-greater-tree/) | [Convert BST to Greater Tree](/src/Q538ConvertBSTtoGreaterTree.java) | 二叉搜索树 | :star: :star: :star: [543](https://leetcode.com/problems/diameter-of-binary-tree/) | [ Diameter of Binary Tree](/src/Q543DiameterofBinaryTree.java) | Tree、递归 | :star: :star: :star: -[572](https://leetcode.com/problems/subtree-of-another-tree/) | [Subtree of Another Tree](/src/Q572SubtreeofAnotherTree.java) | Tree | :star: :star: :star: +[572](https://leetcode.com/problems/subtree-of-another-tree/) | [Subtree of Another Tree](/src/Q572SubtreeofAnotherTree.java) | Tree | :star: :star: :star: :star: [581](https://leetcode.com/problems/shortest-unsorted-continuous-subarray/description/) | [Shortest Unsorted Continuous Subarray](/src/Q581ShortestUnsortedContinuousSubarray.java) | Array | :star: :star: :star: [617](https://leetcode.com/problems/merge-two-binary-trees/) | [Merge Two Binary Trees](/src/Q617MergeTwoBinaryTrees.java) | Tree | :star: :star: :star: [628](https://leetcode.com/problems/maximum-product-of-three-numbers/description/) | [Maximum Product of Three Numbers](/src/Q628MaximumProductofThreeNumbers.java) | Array | :star: diff --git a/src/Q110BalancedBinaryTree.java b/src/Q110BalancedBinaryTree.java new file mode 100644 index 0000000..6e2addf --- /dev/null +++ b/src/Q110BalancedBinaryTree.java @@ -0,0 +1,68 @@ +import util.TreeNode; + +/** + * @author ahscuml + * @date 2019/4/13 + * @time 17:07 + */ +public class Q110BalancedBinaryTree { + /** + * 测试函数 + */ + public static void main(String[] args) { + // TODO + } + + /** + * 自底向上的方法,计算深度,然后返回。 + * 时间复杂度O(nlogn) + */ + public boolean isBalanced(TreeNode root) { + if (root == null) { + return true; + } + int left = depth(root.left); + int right = depth(root.right); + // 针对每一个深度都得符合要求 + if (Math.abs(left - right) <= 1) { + return isBalanced(root.left) && isBalanced(root.right); + } + return false; + } + + public int depth(TreeNode root) { + if (root == null) { + return 0; + } + return Math.max(depth(root.left), depth(root.right)) + 1; + } + + /** + * 自顶向下的方法 + * 时间复杂度O(n) + */ + public boolean isBalancedII(TreeNode root) { + return height(root) != -1; + } + + public int height(TreeNode node) { + if (node == null) { + return 0; + } + // 递归调用,计算深度 + int lH = height(node.left); + if (lH == -1) { + return -1; + } + // 右边递归调用,计算深度 + int rH = height(node.right); + if (rH == -1) { + return -1; + } + // 判断当前行是否满足要求,不满足要求直接返回-1 + if (lH - rH < -1 || lH - rH > 1) { + return -1; + } + return Math.max(lH, rH) + 1; + } +} diff --git a/src/Q206ReverseLinkedList.java b/src/Q206ReverseLinkedList.java index fa0c12f..4d3240d 100644 --- a/src/Q206ReverseLinkedList.java +++ b/src/Q206ReverseLinkedList.java @@ -52,23 +52,23 @@ public static ListNode ReverseList(ListNode head) { return null; } HashMap map = new HashMap(); - ListNode pointer = new ListNode(0); - pointer.next = head; + ListNode dummyHead = new ListNode(0); + dummyHead.next = head; int n = 0; - while(pointer.next != null) { - pointer = pointer.next; - map.put(n,pointer); + while(dummyHead.next != null) { + dummyHead = dummyHead.next; + map.put(n,dummyHead); n++; } n--; head = map.get(n); - pointer = head; + dummyHead = head; while(n > 0) { n--; - pointer.next = map.get(n); - pointer = pointer.next; + dummyHead.next = map.get(n); + dummyHead = dummyHead.next; } - pointer.next = null; + dummyHead.next = null; return head; } From d9d03fc1fa2c1ef59e3eb3d4e8af7374562d69aa Mon Sep 17 00:00:00 2001 From: ahscuml Date: Sat, 13 Apr 2019 18:09:30 +0800 Subject: [PATCH 23/33] =?UTF-8?q?=E5=9B=9E=E6=97=8B=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E4=BA=8C=E7=BB=B4=E6=95=B0=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + src/Q54SpiralMatrix.java | 95 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 src/Q54SpiralMatrix.java diff --git a/README.md b/README.md index d846d20..4de6bd3 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ Medium [47](https://leetcode.com/problems/permutations-ii/description/) | [PermutationsII](/src/Q47PermutationsII.java) | 回溯法 | :star: :star: :star: [48](https://leetcode.com/problems/rotate-image/description/) | [Rotate Image](/src/Q48RotateImage.java) | 二维数组 | :star: :star: [49](https://leetcode.com/problems/group-anagrams/description/) | [Group Anagrams](/src/Q49GroupAnagrams.java) | ArrayList, HashMap | :star: :star: :star: +[54](https://leetcode.com/problems/spiral-matrix/) | [Spiral Matrix](/src/Q54SpiralMatrix.java) | 细节问题 | :star: :star: [56](https://leetcode.com/problems/merge-intervals/description/) | [Merge Intervals](/src/Q56MergeIntervals.java) | 迭代器,自写比较函数 | :star: :star: :star: [60](https://leetcode.com/problems/permutation-sequence/description/) | [Permutation Sequence](/src/Q60PermutationSequence.java) | Array、感觉像是递归 [61](https://leetcode.com/problems/rotate-list/description/) | [Rotate List](/src/Q61RotateList.java) | LinkedList、双指针 | :star: diff --git a/src/Q54SpiralMatrix.java b/src/Q54SpiralMatrix.java new file mode 100644 index 0000000..9db003d --- /dev/null +++ b/src/Q54SpiralMatrix.java @@ -0,0 +1,95 @@ +import java.util.ArrayList; +import java.util.List; + +/** + * @author ahscuml + * @date 2019/4/13 + * @time 18:03 + */ +public class Q54SpiralMatrix { + /** + * 测试函数 + */ + public static void main(String[] args) { + int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; + System.out.println(spiralOrder(matrix)); + System.out.println(spiralOrderII(matrix)); + } + + /** + * 重点是一个循环的终止条件 + * 和四个打印的判断条件 + */ + public static List spiralOrder(int[][] matrix) { + List res = new ArrayList(); + if (matrix.length == 0) { + return res; + } + int rowBegin = 0, rowEnd = matrix.length - 1, colBegin = 0, colEnd = matrix[0].length - 1; + while (rowBegin <= rowEnd && colBegin <= colEnd) { + // 打印rowBegin行,从colBegin到colEnd + for (int i = colBegin; i <= colEnd; i++) { + res.add(matrix[rowBegin][i]); + } + rowBegin++; + // 打印colEnd列 + // 这里值变换了rowBegin而且后面还是比较row,所以不用判断 + for (int i = rowBegin; i <= rowEnd; i++) { + res.add(matrix[i][colEnd]); + } + colEnd--; + + // 打印 rowEnd行 + // 这里要比较row + if (rowBegin <= rowEnd) { + for (int i = colEnd; i >= colBegin; i--) { + res.add(matrix[rowEnd][i]); + } + } + rowEnd--; + + // 打印colBegin列 + // 这里要比较col,因为前面改过col + if (colBegin <= colEnd) { + for (int i = rowEnd; i >= rowBegin; i--) { + res.add(matrix[i][colBegin]); + } + } + colBegin++; + } + return res; + } + + /** + * 第二种方法,可能更加方便记忆 + */ + public static List spiralOrderII(int[][] matrix) { + List res = new ArrayList(); + if (matrix.length == 0 || matrix[0].length == 0) return res; + + int top = 0; + int bottom = matrix.length - 1; + int left = 0; + int right = matrix[0].length - 1; + + while (true) { + for (int i = left; i <= right; i++) res.add(matrix[top][i]); + top++; + if (left > right || top > bottom) break; + + for (int i = top; i <= bottom; i++) res.add(matrix[i][right]); + right--; + if (left > right || top > bottom) break; + + for (int i = right; i >= left; i--) res.add(matrix[bottom][i]); + bottom--; + if (left > right || top > bottom) break; + + for (int i = bottom; i >= top; i--) res.add(matrix[i][left]); + left++; + if (left > right || top > bottom) break; + } + + return res; + } +} From e936f26ba3f8d71b46b917595b3a7a1e8139a641 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Sat, 13 Apr 2019 18:57:57 +0800 Subject: [PATCH 24/33] =?UTF-8?q?=E6=9C=89=E6=95=88=E7=9A=84Stack=E9=A1=BA?= =?UTF-8?q?=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- src/Q946ValidateStackSequences.java | 36 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 src/Q946ValidateStackSequences.java diff --git a/README.md b/README.md index 4de6bd3..58200fe 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,8 @@ Medium [713](https://leetcode.com/problems/subarray-product-less-than-k/description/) | [Subarray Product Less Than K](/src/Q713SubarrayProductLessThanK.java) | 双指针、滑动窗口 | :star: :star: [714](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) | [Best Time to Buy and Sell Stock with Transaction Fee](/src/Q714BestTimetoBuyandSellStockwithTransactionFee.java) | 动态规划、状态机 | :star: :star: :star: [718](https://leetcode.com/problems/maximum-length-of-repeated-subarray/) | [Maximum Length of Repeated Subarray](/src/Q718MaximumLengthofRepeatedSubarray.java) | DP | :star: :star: :star: - +[946](https://leetcode.com/problems/validate-stack-sequences/) | [Validate Stack Sequences](/src/Q946ValidateStackSequences.java) | Stack | :star: :star: + Hard --- 题号|题目|Tags|Star|Company| diff --git a/src/Q946ValidateStackSequences.java b/src/Q946ValidateStackSequences.java new file mode 100644 index 0000000..0663f19 --- /dev/null +++ b/src/Q946ValidateStackSequences.java @@ -0,0 +1,36 @@ +import java.util.Stack; + +/** + * @author ahscuml + * @date 2019/4/13 + * @time 18:52 + */ +public class Q946ValidateStackSequences { + /** + * + * */ + public static void main(String[] args) { + int[] pushed = {1, 2, 3, 4, 5}; + int[] popped = {4, 5, 3, 2, 1}; + System.out.println(validateStackSequences(pushed, popped)); + } + + /** + * 很简单的思想,不过记得stack要先push + * */ + public static boolean validateStackSequences(int[] pushA, int[] popA) { + Stack stack = new Stack(); + int j = 0; + for (int i = 0; i < pushA.length; i++) { + stack.push(pushA[i]); + while (!stack.isEmpty() && stack.peek() == popA[j]) { + j++; + stack.pop(); + } + } + if (stack.isEmpty()) { + return true; + } + return false; + } +} From 79b809b7379385e5fb7f561f0eb3849c839f9e09 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Sun, 14 Apr 2019 01:47:19 +0800 Subject: [PATCH 25/33] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/Q215KthLargestElementinanArray.java | 18 +++++++- src/Q347TopKFrequentElements.java | 59 +++++++++++++++++++++++-- 3 files changed, 73 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 58200fe..7896718 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,7 @@ Medium [334](https://leetcode.com/problems/increasing-triplet-subsequence/) | [Increasing Triplet Subsequence](/src/Q334IncreasingTripletSubsequence.java) | | :star: :star: [337](https://leetcode.com/problems/house-robber-iii/) | [House Robber III](/src/Q337HouseRobberIII.java) | HashMap、DP | :star: :star: :star: [343](https://leetcode.com/problems/integer-break/) | [Integer Break](/src/Q343IntegerBreak.java) | DP | :star: :star: -[347](https://leetcode.com/problems/top-k-frequent-elements/) | [Top K Frequent Elements](/src/Q347TopKFrequentElements.java) | HashMap | :star: :star: :star: +[347](https://leetcode.com/problems/top-k-frequent-elements/) | [Top K Frequent Elements](/src/Q347TopKFrequentElements.java) | HashMap | :star: :star: :star: :star: [357](https://leetcode.com/problems/count-numbers-with-unique-digits/description/) | [Count Numbers with Unique Digits](/src/Q357CountNumberswithUniqueDigits.java) | DP、回溯 | :star: :star: :star: [416](https://leetcode.com/problems/partition-equal-subset-sum/) | [Partition Equal Subset Sum](/src/Q416PartitionEqualSubsetSum.java) | DP | :star: :star: :star: :star: [438](https://leetcode.com/problems/find-all-anagrams-in-a-string/) | [Find All Anagrams in a String](/src/Q438FindAllAnagramsinaString.java) | HashTable、滑动窗口 | :star: :star: :star: diff --git a/src/Q215KthLargestElementinanArray.java b/src/Q215KthLargestElementinanArray.java index da7a2de..c33ac42 100644 --- a/src/Q215KthLargestElementinanArray.java +++ b/src/Q215KthLargestElementinanArray.java @@ -1,6 +1,8 @@ import java.util.Arrays; +import java.util.PriorityQueue; /** + * 非常重点的题,主要考察Quick Select方法(https://www.jianshu.com/p/52f90fe2b141) * @author ahscuml * @date 2018/10/8 * @time 19:56 @@ -20,6 +22,7 @@ public static void main(String[] args) { System.out.println(findKthLargestIII(nums5, 1)); System.out.println(findKthLargestIV(nums3, 4)); System.out.println(findKthLargestV(nums3, 4)); + System.out.println(findKthLargestVI(nums3, 4)); } /** @@ -132,7 +135,7 @@ private static int quickSelectII(int[] nums, int k, int left, int right) { if (left >= right) { return nums[left]; } - // 随机化 + // 随机化, 取中点的值,其实也不是最好的,应该是三点法 int index = (left + right) / 2; int pivot = nums[index]; int low = left, high = right; @@ -165,6 +168,19 @@ private static int quickSelectII(int[] nums, int k, int left, int right) { } } + /** + * 这个问题非常适合利用堆来完成,使用一个小顶堆,在Java中就是priority queue + * */ + public static int findKthLargestVI(int[] nums, int k) { + PriorityQueue priorityQueue = new PriorityQueue<>(k); + for(int el : nums) { + priorityQueue.add(el); + if (priorityQueue.size() > k) { + priorityQueue.poll(); + } + } + return priorityQueue.peek(); + } private static void swap(int[] nums, int i, int j) { int temp = nums[i]; diff --git a/src/Q347TopKFrequentElements.java b/src/Q347TopKFrequentElements.java index 4180f43..e9e2924 100644 --- a/src/Q347TopKFrequentElements.java +++ b/src/Q347TopKFrequentElements.java @@ -1,7 +1,4 @@ -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; +import java.util.*; /** * @author ahscuml @@ -19,6 +16,7 @@ public static void main(String[] args) { } /** + * 使用桶排序来做这件事情 * 利用HashMap统计频次 * 利用List的数组存储结果 */ @@ -31,6 +29,7 @@ public static List topKFrequent(int[] nums, int k) { } // 遍历存有频率的HashMap,利用存有list的数组bucket 按照频率将元素存储到bucket里 + // 如何遍历HashMap也是一个重点 List[] bucket = new List[nums.length + 1]; for (int i : map.keySet()) { int fre = map.get(i); @@ -49,4 +48,56 @@ public static List topKFrequent(int[] nums, int k) { } return res; } + + /** + * 使用堆来完成任务,也就是PriorityQueue + * */ + public static List topKFrequentII(int[] nums, int k) { + // 利用HahsMap来存储频次 + Map map = new HashMap<>(); + for(int n: nums){ + map.put(n, map.getOrDefault(n,0)+1); + } + + // 优先队列的使用 + PriorityQueue> maxHeap = + new PriorityQueue<>((a,b)->(b.getValue()-a.getValue())); + for(Map.Entry entry: map.entrySet()){ + maxHeap.add(entry); + } + + List res = new ArrayList<>(); + while(res.size() entry = maxHeap.poll(); + res.add(entry.getKey()); + } + return res; + } + + /** + * 使用TreeMap来完成这个任务 + * */ + public static List topKFrequentIII(int[] nums, int k) { + Map map = new HashMap<>(); + for(int n: nums){ + map.put(n, map.getOrDefault(n,0)+1); + } + + TreeMap> freqMap = new TreeMap<>(); + for(int num : map.keySet()){ + int freq = map.get(num); + if(!freqMap.containsKey(freq)){ + freqMap.put(freq, new LinkedList<>()); + } + freqMap.get(freq).add(num); + } + + // 对于TreeMap的使用 + List res = new ArrayList<>(); + while(res.size()> entry = freqMap.pollLastEntry(); + res.addAll(entry.getValue()); + } + return res; + } } From 0a3308630bb32b425b0e56fb4729060dd0a60199 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Wed, 17 Apr 2019 19:42:37 +0800 Subject: [PATCH 26/33] =?UTF-8?q?=E4=BF=AE=E6=94=B9103zigzag=E6=89=93?= =?UTF-8?q?=E5=8D=B0=E4=BA=8C=E5=8F=89=E6=A0=91=E7=9A=84=E9=94=99=E8=AF=AF?= =?UTF-8?q?=EF=BC=8C=E4=BB=A5=E5=8F=8A102=E5=B1=82=E5=BA=8F=E6=89=93?= =?UTF-8?q?=E5=8D=B0=E7=9A=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Q102BinaryTreeLevelOrderTraversal.java | 2 +- ...03BinaryTreeZigzagLevelOrderTraversal.java | 63 +++---------------- 2 files changed, 10 insertions(+), 55 deletions(-) diff --git a/src/Q102BinaryTreeLevelOrderTraversal.java b/src/Q102BinaryTreeLevelOrderTraversal.java index a922d25..08efe95 100644 --- a/src/Q102BinaryTreeLevelOrderTraversal.java +++ b/src/Q102BinaryTreeLevelOrderTraversal.java @@ -91,7 +91,7 @@ private static void depth(TreeNode root, int depth, ArrayList if (depth > list.size()) { list.add(new ArrayList<>()); } - // 获取之前添加的ArrayList然后添加数据; + // 获取之前添加的ArrayList然后添加数据;主要depth要减一 list.get(depth - 1).add(root.val); depth(root.left, depth + 1, list); diff --git a/src/Q103BinaryTreeZigzagLevelOrderTraversal.java b/src/Q103BinaryTreeZigzagLevelOrderTraversal.java index 86cb24f..5bdad64 100644 --- a/src/Q103BinaryTreeZigzagLevelOrderTraversal.java +++ b/src/Q103BinaryTreeZigzagLevelOrderTraversal.java @@ -29,51 +29,6 @@ public static void main(String[] args) { System.out.println(Helper(treeNode1)); } - /** - * 通过翻转来实现,循环算法 - */ - public static List> zigzagLevelOrderIte(TreeNode root) { - List> res = new ArrayList(); - List curRes = new ArrayList(); - if (root == null) { - return res; - } - Queue queue = new LinkedList(); - queue.offer(root); - TreeNode cur; - int level = 1; - // 当前层的元素数量 - int A = 1; - // 下一层的元素数量 - int next = 0; - while (!queue.isEmpty()) { - - cur = queue.poll(); - // 当前行减1; - A--; - curRes.add(cur.val); - if (cur.left != null) { - queue.offer(cur.left); - next++; - } - if (cur.right != null) { - queue.offer(cur.right); - next++; - } - if (A == 0) { - if (level % 2 == 0) { - Collections.reverse(curRes); - } - res.add(curRes); - curRes = new ArrayList(); - A = next; - next = 0; - level++; - } - } - return res; - } - /** * 递归的算法 */ @@ -100,7 +55,7 @@ private static void travel(TreeNode curr, List> sol, int level) { } /** - * 使用一个栈与一个队列来实现,因为栈弹出的过程就是翻转的过程 + * 使用两个栈来实现,因为栈弹出的过程就是翻转的过程 */ private static List> Helper(TreeNode root) { TreeNode cur; @@ -109,12 +64,12 @@ private static List> Helper(TreeNode root) { return res; } Stack stack = new Stack<>(); - Queue queue = new LinkedList<>(); - queue.offer(root); + Stack queue = new Stack<>(); + queue.push(root); while (!queue.isEmpty() || !stack.isEmpty()) { List temp = new ArrayList<>(); while (!queue.isEmpty()) { - cur = queue.poll(); + cur = queue.pop(); temp.add(cur.val); if (cur.left != null) { stack.push(cur.left); @@ -128,11 +83,11 @@ private static List> Helper(TreeNode root) { while (!stack.isEmpty()) { cur = stack.pop(); temp.add(cur.val); - if (cur.left != null) { - queue.offer(cur.left); - } if (cur.right != null) { - queue.offer(cur.right); + queue.push(cur.right); + } + if (cur.left != null) { + queue.push(cur.left); } } if (!temp.isEmpty()) { @@ -145,7 +100,7 @@ private static List> Helper(TreeNode root) { /** * 利用Collection.reverse函数来实现 */ - public static List> zigzagLevelOrder(TreeNode root) { + public static List> zigzagLevelOrderIte(TreeNode root) { List> res = new ArrayList<>(); if (root == null) { return res; From 317eecfccf8de51c11db22dc4b4f0b78782c2e49 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Wed, 17 Apr 2019 21:57:39 +0800 Subject: [PATCH 27/33] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E5=B0=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Q103BinaryTreeZigzagLevelOrderTraversal.java | 1 + src/Q112PathSum.java | 2 +- src/Q113PathSumII.java | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Q103BinaryTreeZigzagLevelOrderTraversal.java b/src/Q103BinaryTreeZigzagLevelOrderTraversal.java index 5bdad64..f4ad8c3 100644 --- a/src/Q103BinaryTreeZigzagLevelOrderTraversal.java +++ b/src/Q103BinaryTreeZigzagLevelOrderTraversal.java @@ -48,6 +48,7 @@ private static void travel(TreeNode curr, List> sol, int level) { List collection = sol.get(level); if (level % 2 == 0) collection.add(curr.val); + // 不一样的地方,利用ArrayList 的特点,从头添加的时候会把后面的往后移动 else collection.add(0, curr.val); travel(curr.left, sol, level + 1); diff --git a/src/Q112PathSum.java b/src/Q112PathSum.java index b998a55..59e6d0c 100644 --- a/src/Q112PathSum.java +++ b/src/Q112PathSum.java @@ -40,12 +40,12 @@ public static boolean hasPathSumRec(TreeNode root, int sum) { /** * 采用循环的方法,可以避免堆栈的溢出,但是代码量很大,而且需要一个栈存储当前节点的和 + * 其实就是前序遍历,只不过存储的是值而已,通过一个判断来完成题目要求。 */ public static boolean hasPathSumIte(TreeNode root, int sum) { if (root == null) { return false; } - Stack stack = new Stack<>(); Stack SumForNode = new Stack<>(); int curSum = 0; diff --git a/src/Q113PathSumII.java b/src/Q113PathSumII.java index 10e190a..ce6789b 100644 --- a/src/Q113PathSumII.java +++ b/src/Q113PathSumII.java @@ -98,7 +98,6 @@ public static List> pathSumIte(TreeNode root, int sum) { curSum -= cur.val; cur = null; } - return res; } } From 5398efd05ac261b4e8413c3324d4dcfaa8e908cf Mon Sep 17 00:00:00 2001 From: ahscuml Date: Wed, 17 Apr 2019 21:58:04 +0800 Subject: [PATCH 28/33] =?UTF-8?q?138=E9=A2=98=EF=BC=8C=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E9=93=BE=E8=A1=A8=E5=A4=8D=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + src/Q138CopyListwithRandomPointer.java | 51 ++++++++++++++++++++++++++ src/util/RandomNode.java | 20 ++++++++++ 3 files changed, 72 insertions(+) create mode 100644 src/Q138CopyListwithRandomPointer.java create mode 100644 src/util/RandomNode.java diff --git a/README.md b/README.md index 7896718..0141a21 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ Medium [113](https://leetcode.com/problems/path-sum-ii/) | [Path Sum II](/src/Q113PathSumII.java) | Tree | :star: :star: [114](https://leetcode.com/problems/flatten-binary-tree-to-linked-list/) | [Flatten Binary Tree to Linked List](/src/Q114FlattenBinaryTreetoLinkedList.java) | Tree、递归 | :star: :star: :star: :star | ByteDance [120](https://leetcode.com/problems/triangle/) | [Triangle](/src/Q120Triangle.java) | DP | :star: :star: :star: :star: +[138](https://leetcode.com/problems/copy-list-with-random-pointer/) | [Copy List with Random Pointer](/src/Q138CopyListwithRandomPointer.java) | List | :star: :star: :star: [139](https://leetcode.com/problems/word-break/) | [Word Break](/src/Q139WordBreak.java) | DP | :star: :star: :star: [142](https://leetcode.com/problems/linked-list-cycle-ii/description/) | [Linked List Cycle II](/src/Q142LinkedListCycleII.java) | LinkedList、双指针 | :star: :star: :star: [143](https://leetcode.com/problems/reorder-list/) | [Reorder List](/src/Q143ReorderList.java) | LinkedList | :star: :star: :star: diff --git a/src/Q138CopyListwithRandomPointer.java b/src/Q138CopyListwithRandomPointer.java new file mode 100644 index 0000000..e9a8423 --- /dev/null +++ b/src/Q138CopyListwithRandomPointer.java @@ -0,0 +1,51 @@ +import util.RandomNode; + +/** + * @author ahscuml + * @date 2019/4/17 + * @time 21:37 + */ +public class Q138CopyListwithRandomPointer { + /** + * 测试函数 + * */ + public static void main(String[] args) { + // TODO + } + + /** + * + * */ + public RandomNode copyRandomList(RandomNode head) { + if(head == null) { + return null; + } + RandomNode cur = head; + // 创建新的链表 + while(cur != null) { + RandomNode newNode = new RandomNode(); + newNode.val = cur.val; + newNode.next = cur.next; + cur.next = newNode; + cur = cur.next.next; + } + + cur = head; + // 复制random节点 + while(cur != null) { + cur.next.random = cur.random == null ? null : cur.random.next; + cur = cur.next.next; + } + cur = head; + RandomNode dummyHead = cur.next; + // 按照奇偶拆分成两个链表 + while(cur != null) { + RandomNode newNode = cur.next; + cur.next = newNode.next; + newNode.next = cur.next == null ? null : newNode.next.next; + cur = cur.next; + } + return dummyHead; + + } +} diff --git a/src/util/RandomNode.java b/src/util/RandomNode.java new file mode 100644 index 0000000..ab84fd6 --- /dev/null +++ b/src/util/RandomNode.java @@ -0,0 +1,20 @@ +package util; + +/** + * @author ahscuml + * @date 2019/4/17 + * @time 21:40 + */ +public class RandomNode { + public int val; + public RandomNode next; + public RandomNode random; + + public RandomNode() {} + + public RandomNode(int _val,RandomNode _next,RandomNode _random) { + val = _val; + next = _next; + random = _random; + } +} From 7007030b75c1684fa3d6185f277ff6d8a5e591f9 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Mon, 29 Apr 2019 12:17:21 +0800 Subject: [PATCH 29/33] =?UTF-8?q?107=E4=BA=8C=E5=8F=89=E6=A0=91=E5=80=92?= =?UTF-8?q?=E5=BA=8F=E5=90=8E=E5=BA=8F=E9=81=8D=E5=8E=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + src/Q107BinaryTreeLevelOrderTraversalII.java | 75 ++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 src/Q107BinaryTreeLevelOrderTraversalII.java diff --git a/README.md b/README.md index 0141a21..bc3abc3 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Easy [101](https://leetcode.com/problems/symmetric-tree/) | [Symmetric Tree](/src/Q101SymmetricTree.java) | Tree | :star: :star: :star: [104](https://leetcode.com/problems/maximum-depth-of-binary-tree/description/) | [Maximum Depth of Binary Tree](/src/Q104MaximumDepthofBinaryTree.java) | Tree | :star: :star: :star: [105](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) | [Construct Binary Tree from Preorder and Inorder Traversal](/src/Q105ConstructBinaryTreefromPreorderandInorderTraversal.java) | Tree | :star: :star: :star: +[107](https://leetcode.com/problems/binary-tree-level-order-traversal-ii/submissions/) | [Binary Tree Level Order Traversal II](/src/Q107BinaryTreeLevelOrderTraversalII.java) | Tree | :star: :star: [108](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/) | [Convert Sorted Array to Binary Search Tree](/src/Q108ConvertSortedArraytoBinarySearchTree.java) | Tree | :star: :star: :star: [110](https://leetcode.com/problems/balanced-binary-tree/) | [Balanced Binary Tree](/src/Q110BalancedBinaryTree.java) | Tree,DFS | :star: :star: :star: :star: [111](https://leetcode.com/problems/minimum-depth-of-binary-tree/) | [Minimum Depth of Binary Tree](/src/Q111MinimumDepthofBinaryTree.java) | Tree、递归 | :star: :star: :star: diff --git a/src/Q107BinaryTreeLevelOrderTraversalII.java b/src/Q107BinaryTreeLevelOrderTraversalII.java new file mode 100644 index 0000000..4da0a5e --- /dev/null +++ b/src/Q107BinaryTreeLevelOrderTraversalII.java @@ -0,0 +1,75 @@ +import util.TreeNode; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * 倒着层序遍历二叉树 + * + * @author ahscuml + * @date 2019/4/29 + * @time 12:09 + */ +public class Q107BinaryTreeLevelOrderTraversalII { + /** + * 测试函数 + */ + public static void main(String[] args) { + // TODO + } + + /** + * 后序遍历的递归实现,记录层数,确定添加元素的位置 + */ + public static List> levelOrderBottomII(TreeNode root) { + List> wrapList = new LinkedList>(); + levelMaker(wrapList, root, 0); + return wrapList; + } + + public static void levelMaker(List> list, TreeNode root, int level) { + if (root == null) return; + if (level >= list.size()) { + list.add(0, new LinkedList()); + } + levelMaker(list, root.left, level + 1); + levelMaker(list, root.right, level + 1); + list.get(list.size() - level - 1).add(root.val); + } + + /** + * 层序遍历循环方法 + * 最后将结果逆序有两种方法,一种是规定好插入的位置,在第一个,另外一种是使用Collections.reverse()函数 + */ + public List> levelOrderBottom(TreeNode root) { + List> list = new ArrayList(); + if (root == null) { + return list; + } + Queue queue = new LinkedList<>(); + TreeNode cur = null; + queue.offer(root); + while (!queue.isEmpty()) { + List templist = new ArrayList(); + int count = queue.size(); + while (count > 0) { + cur = queue.poll(); + templist.add(cur.val); + if (cur.left != null) { + queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + count--; + } + if (templist != null) + list.add(0, templist); + } + return list; + } +} + + From 0a664f42bead39aa67716236166e57cb1c09882b Mon Sep 17 00:00:00 2001 From: ahscuml Date: Mon, 29 Apr 2019 13:08:14 +0800 Subject: [PATCH 30/33] 257, 637 --- README.md | 2 + src/Q257BinaryTreePaths.java | 47 ++++++++++++++++++++++ src/Q637AverageofLevelsinBinaryTree.java | 50 ++++++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 src/Q257BinaryTreePaths.java create mode 100644 src/Q637AverageofLevelsinBinaryTree.java diff --git a/README.md b/README.md index bc3abc3..861bcc0 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ Easy [226](https://leetcode.com/problems/invert-binary-tree/) | [Invert Binary Tree](/src/Q226InvertBinaryTree.java) | Tree | :star: :star: :star: [234](https://leetcode.com/problems/palindrome-linked-list/description/) | [Palindrome Linked List](/src/Q234PalindromeLinkedList.java) | LinkedList、双指针 | :star: :star: :star: [235](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) | [Lowest Common Ancestor of a Binary Search Tree](/src/Q235LowestCommonAncestorofaBinarySearchTree.java) | 递归 | :star: :star: :star: +[257](https://leetcode.com/problems/binary-tree-paths/) | [Binary Tree Paths](/src/Q257BinaryTreePaths.java) | Tree, String | :star: :star: :star: :star: [338](https://leetcode.com/problems/counting-bits/) | [Counting Bits](/src/Q338CountingBits.java) | bits | :star: :star: :star: [401](https://leetcode.com/problems/binary-watch/description/) | [Binary Watch](/src/Q401BinaryWatch.java) | 递归 | :star: [437](https://leetcode.com/problems/path-sum-iii/) | [Path Sum III](/src/Q437PathSumIII.java) | HashMap,Tree | :star: :star: :star: @@ -52,6 +53,7 @@ Easy [581](https://leetcode.com/problems/shortest-unsorted-continuous-subarray/description/) | [Shortest Unsorted Continuous Subarray](/src/Q581ShortestUnsortedContinuousSubarray.java) | Array | :star: :star: :star: [617](https://leetcode.com/problems/merge-two-binary-trees/) | [Merge Two Binary Trees](/src/Q617MergeTwoBinaryTrees.java) | Tree | :star: :star: :star: [628](https://leetcode.com/problems/maximum-product-of-three-numbers/description/) | [Maximum Product of Three Numbers](/src/Q628MaximumProductofThreeNumbers.java) | Array | :star: +[637](https://leetcode.com/problems/average-of-levels-in-binary-tree/) | [Average of Levels in Binary Tree](/src/Q637AverageofLevelsinBinaryTree.java) | Tree | :star: :star: [771](https://leetcode.com/problems/jewels-and-stones/) | [Jewels and Stones](/src/Q771JewelsandStones.java) | String | :star: Medium diff --git a/src/Q257BinaryTreePaths.java b/src/Q257BinaryTreePaths.java new file mode 100644 index 0000000..afaf10e --- /dev/null +++ b/src/Q257BinaryTreePaths.java @@ -0,0 +1,47 @@ +import util.TreeNode; + +import java.util.ArrayList; +import java.util.List; + +/** + * 二叉树从头到尾的路径 + * @author ahscuml + * @date 2019/4/29 + * @time 13:00 + */ +public class Q257BinaryTreePaths { + /** + * 测试函数 + */ + public static void main(String[] args) { + + } + + /** + * 将StringBuilder作为传递资源完成内容。 + * setLength函数设置长度 + * 最后一个不用加上->,所以需要判断当前节点的左右子节点是否是null + * */ + public List binaryTreePaths(TreeNode root) { + List res = new ArrayList<>(); + StringBuilder sb = new StringBuilder(); + helper(res, root, sb); + return res; + } + + private void helper(List res, TreeNode root, StringBuilder sb) { + if (root == null) { + return; + } + int len = sb.length(); + sb.append(root.val); + if (root.left == null && root.right == null) { + res.add(sb.toString()); + } else { + sb.append("->"); + helper(res, root.left, sb); + helper(res, root.right, sb); + } + sb.setLength(len); + } +} diff --git a/src/Q637AverageofLevelsinBinaryTree.java b/src/Q637AverageofLevelsinBinaryTree.java new file mode 100644 index 0000000..a4f0dd6 --- /dev/null +++ b/src/Q637AverageofLevelsinBinaryTree.java @@ -0,0 +1,50 @@ +import util.TreeNode; + +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * @author ahscuml + * @date 2019/4/29 + * @time 12:22 + */ +public class Q637AverageofLevelsinBinaryTree { + /** + * 测试函数 + */ + public static void main(String[] args) { + + } + + /** + * 层序遍历,统计这一层的值,除就可以了 + */ + public List averageOfLevels(TreeNode root) { + List list = new LinkedList(); + if (root == null) { + return list; + } + Queue queue = new LinkedList<>(); + TreeNode cur = null; + queue.offer(root); + while (!queue.isEmpty()) { + int count = queue.size(); + int n = count; + double sum = 0; + while (count > 0) { + cur = queue.poll(); + sum += cur.val; + if (cur.left != null) { + queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + count--; + } + list.add(sum / n); + } + return list; + } +} From ad701fab9ec7b8daea9a46a9f30c059401ef240c Mon Sep 17 00:00:00 2001 From: ahscuml Date: Mon, 13 May 2019 23:43:30 +0800 Subject: [PATCH 31/33] =?UTF-8?q?297=20=E5=BA=8F=E5=88=97=E5=8C=96?= =?UTF-8?q?=E5=92=8C=E5=8F=8D=E5=BA=8F=E5=88=97=E5=8C=96=E4=BA=8C=E5=8F=89?= =?UTF-8?q?=E6=A0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +- ...Q297SerializeandDeserializeBinaryTree.java | 57 +++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 src/Q297SerializeandDeserializeBinaryTree.java diff --git a/README.md b/README.md index 861bcc0..e4a5242 100644 --- a/README.md +++ b/README.md @@ -148,4 +148,5 @@ Hard [123](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/) | [Best Time to Buy and Sell Stock III](/src/Q123BestTimetoBuyandSellStockIII.java) | DP、状态机 | :star: :star: :star: [124](https://leetcode.com/problems/binary-tree-maximum-path-sum/) | [Binary Tree Maximum Path Sum](/src/Q124BinaryTreeMaximumPathSum.java) | Tree,递归 | :star: :star: :star: [146](https://leetcode.com/problems/lru-cache/) | [LRU Cache](/src/Q146LRUCache.java) | LRU,HashMap,LinkedHashMap | :star: :star: :star: | ByteDance -[188](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/) | [Best Time to Buy and Sell Stock IV](/src/Q188BestTimetoBuyandSellStockIV.java) | DP | :star: :star: :star: \ No newline at end of file +[188](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/) | [Best Time to Buy and Sell Stock IV](/src/Q188BestTimetoBuyandSellStockIV.java) | DP | :star: :star: :star: +[297](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/) | [Serialize and Deserialize Binary Tree](/src/Q297SerializeandDeserializeBinaryTree.java) | Tree | :star: :star: :star: \ No newline at end of file diff --git a/src/Q297SerializeandDeserializeBinaryTree.java b/src/Q297SerializeandDeserializeBinaryTree.java new file mode 100644 index 0000000..5177f90 --- /dev/null +++ b/src/Q297SerializeandDeserializeBinaryTree.java @@ -0,0 +1,57 @@ +/** + * @author ahscuml + * @date 2019/5/13 + * @time 23:32 + */ + +import util.TreeNode; + +public class Q297SerializeandDeserializeBinaryTree { + int index = -1; + + /** + * 测试函数 + */ + public static void main(String[] args) { + + } + + /** + * 序列化和反序列化,这是一个运行时间相对优秀的答案 + * 主要利用前序遍历,将一棵树组装成一个String + * 反序列化同理,同样要注意反序列化的顺序 + * */ + private void serializeNode(TreeNode node, StringBuilder sb) { + if (node == null) { + sb.append('#').append(","); + return; + } + sb.append(node.val).append(','); + serializeNode(node.left, sb); + serializeNode(node.right, sb); + } + + // Encodes a tree to a single string. + public String serialize(TreeNode root) { + StringBuilder sb = new StringBuilder(); + serializeNode(root, sb); + return sb.substring(0, sb.length() - 1); + } + + // Decodes your encoded data to tree. + public TreeNode deserialize(String data) { + String[] val = data.split(","); + return buildTree(val); + } + + private TreeNode buildTree(String[] val) { + index++; + TreeNode cur = null; + if (!val[index].equals("#")) { + cur = new TreeNode(Integer.valueOf(val[index])); + cur.left = buildTree(val); + cur.right = buildTree(val); + } + return cur; + } +} From 1d6034049732cc2481a71b64933494ad9df949a3 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Sat, 18 May 2019 00:40:43 +0800 Subject: [PATCH 32/33] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86173=E4=B8=8E23?= =?UTF-8?q?0=E4=B8=A4=E4=B8=AA=E9=A2=98=E7=9B=AE=EF=BC=8C=E5=AF=B996?= =?UTF-8?q?=E5=81=9A=E4=BA=86=E4=B8=80=E7=82=B9=E6=9B=B4=E6=94=B9=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86readme=E4=B8=AD=E7=9A=84=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 ++-- src/Q173BinarySearchTreeIterator.java | 95 +++++++++++++++++++++++++++ src/Q230KthSmallestElementinaBST.java | 79 ++++++++++++++++++++++ src/Q96UniqueBinarySearchTrees.java | 1 + 4 files changed, 182 insertions(+), 4 deletions(-) create mode 100644 src/Q173BinarySearchTreeIterator.java create mode 100644 src/Q230KthSmallestElementinaBST.java diff --git a/README.md b/README.md index e4a5242..652f39f 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Easy [104](https://leetcode.com/problems/maximum-depth-of-binary-tree/description/) | [Maximum Depth of Binary Tree](/src/Q104MaximumDepthofBinaryTree.java) | Tree | :star: :star: :star: [105](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) | [Construct Binary Tree from Preorder and Inorder Traversal](/src/Q105ConstructBinaryTreefromPreorderandInorderTraversal.java) | Tree | :star: :star: :star: [107](https://leetcode.com/problems/binary-tree-level-order-traversal-ii/submissions/) | [Binary Tree Level Order Traversal II](/src/Q107BinaryTreeLevelOrderTraversalII.java) | Tree | :star: :star: -[108](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/) | [Convert Sorted Array to Binary Search Tree](/src/Q108ConvertSortedArraytoBinarySearchTree.java) | Tree | :star: :star: :star: +[108](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/) | [Convert Sorted Array to Binary Search Tree](/src/Q108ConvertSortedArraytoBinarySearchTree.java) | BST | :star: :star: :star: [110](https://leetcode.com/problems/balanced-binary-tree/) | [Balanced Binary Tree](/src/Q110BalancedBinaryTree.java) | Tree,DFS | :star: :star: :star: :star: [111](https://leetcode.com/problems/minimum-depth-of-binary-tree/) | [Minimum Depth of Binary Tree](/src/Q111MinimumDepthofBinaryTree.java) | Tree、递归 | :star: :star: :star: [112](https://leetcode.com/problems/path-sum/) | [Path Sum](/src/Q112PathSum.java) | Tree | :star: :star: @@ -93,8 +93,9 @@ Medium [90](https://leetcode.com/problems/subsets-ii/description/) | [SubsetsII](/src/Q90SubsetsII.java) | Array、回溯法 | :star: :star: :star: [92](https://leetcode.com/problems/reverse-linked-list-ii/) | [Reverse Linked List II](/src/Q92ReverseLinkedListII.java) | LinkedList | :star: :star: :star: [94](https://leetcode.com/problems/binary-tree-inorder-traversal/description/) | [Binary Tree Inorder Traversal](/src/Q94BinaryTreeInorderTraversal.java) | Tree | :star: :star: :star: -[96](https://leetcode.com/problems/unique-binary-search-trees/) | [Unique Binary Search Trees](/src/Q96UniqueBinarySearchTrees.java) | BST, 递归 | :star: :star: :star: -[98](https://leetcode.com/problems/validate-binary-search-tree/) | [Validate Binary Search Tree](/src/Q98ValidateBinarySearchTree.java) | 递归 | :star: :star: :star: | ByteDance +[95](https://leetcode.com/problems/unique-binary-search-trees-ii/) | [Unique Binary Search Trees II](/src/Q95UniqueBinarySearchTreesII.java) | BST | :star: :star: :star: +[96](https://leetcode.com/problems/unique-binary-search-trees/) | [Unique Binary Search Trees](/src/Q96UniqueBinarySearchTrees.java) | BST | :star: :star: :star: +[98](https://leetcode.com/problems/validate-binary-search-tree/) | [Validate Binary Search Tree](/src/Q98ValidateBinarySearchTree.java) | BST | :star: :star: :star: | ByteDance [102](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/) | [Binary Tree Level Order Traversal](/src/Q102BinaryTreeLevelOrderTraversal.java) | Tree | :star: :star: :star: [103](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/) | [Binary Tree Zigzag Level Order Traversal](/src/Q103BinaryTreeZigzagLevelOrderTraversal.java) | Tree | :star: :star: :star: | ByteDance [113](https://leetcode.com/problems/path-sum-ii/) | [Path Sum II](/src/Q113PathSumII.java) | Tree | :star: :star: @@ -104,13 +105,15 @@ Medium [139](https://leetcode.com/problems/word-break/) | [Word Break](/src/Q139WordBreak.java) | DP | :star: :star: :star: [142](https://leetcode.com/problems/linked-list-cycle-ii/description/) | [Linked List Cycle II](/src/Q142LinkedListCycleII.java) | LinkedList、双指针 | :star: :star: :star: [143](https://leetcode.com/problems/reorder-list/) | [Reorder List](/src/Q143ReorderList.java) | LinkedList | :star: :star: :star: -[152](https://leetcode.com/problems/maximum-product-subarray/description/) | [Maximum Product Subarray](/src/Q152MaximumProductSubarray.java) | Array、 DP | :star: :star: :star: +[152](https://leetcode.com/problems/maximum-product-subarray/description/) | [Maximum Product Subarray](/src/Q152MaximumProductSubarray.java) | Array、 DP | :star: :star: :star: +[173](https://leetcode.com/problems/binary-search-tree-iterator/) | [Binary Search Tree Iterator](/src/Q173BinarySearchTreeIterator.java) | BST | :star: :star: :star: [199](https://leetcode.com/problems/binary-tree-right-side-view/) | [Binary Tree Right Side View](/src/Q199BinaryTreeRightSideView.java) | Tree,递归 | :star: :star: :star: :star: | ByteDance [209](https://leetcode.com/problems/minimum-size-subarray-sum/description/) | [Minimum Size Subarray Sum](/src/Q209MinimumSizeSubarraySum.java) | Array、滑动窗口 [213](https://leetcode.com/problems/house-robber-ii/) | [House Robber II](/src/Q213HouseRobberII.java) | 动态规划 | :star: :star: [215](https://leetcode.com/problems/kth-largest-element-in-an-array/description/) | [Kth Largest Element in an Array](/src/Q215KthLargestElementinanArray.java) | Array、快速选择算法 | :star: :star: :star: :star: | ihandy,ByteDance [216](https://leetcode.com/problems/combination-sum-iii/description/) | [CombinationSumIII](/src/Q216CombinationSumIII.java) | Array、回溯法 | :star: :star: :star: [221](https://leetcode.com/problems/maximal-square/) | [Maximal Square](/src/Q221MaximalSquare.java) | DP | :star: :star: :star: +[230](https://leetcode.com/problems/kth-smallest-element-in-a-bst/) | [Kth Smallest Element in a BST](/src/Q230KthSmallestElementinaBST.java) | BST | :star: :star: :star: :star: [236](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) | [Lowest Common Ancestor of a Binary Tree](/src/Q236LowestCommonAncestorofaBinaryTree.java) | 递归 | :star: :star: :star: :star: | ByteDance [238](https://leetcode.com/problems/product-of-array-except-self/description/) | [Product of Array Except Self](/src/Q238ProductofArrayExceptSelf.java) | Array [240](https://leetcode.com/problems/search-a-2d-matrix-ii/) | [Search a 2D Matrix II](/src/Q240Searcha2DMatrixII.java) | | :star: :star: :star: diff --git a/src/Q173BinarySearchTreeIterator.java b/src/Q173BinarySearchTreeIterator.java new file mode 100644 index 0000000..d17d4b2 --- /dev/null +++ b/src/Q173BinarySearchTreeIterator.java @@ -0,0 +1,95 @@ +import util.TreeNode; + +import java.util.ArrayDeque; +import java.util.LinkedList; +import java.util.Queue; + +/** + * @author ahscuml + * @date 2019/5/18 + * @time 0:04 + */ +public class Q173BinarySearchTreeIterator { + /** + * 测试函数 + */ + public static void main(String[] args) { + + } + + /** + * 把按照顺序遍历的过程通过三个函数展现出来,里面有很多细节的处理 + */ + class BSTIterator { + private ArrayDeque stack = new ArrayDeque<>(); + + public BSTIterator(TreeNode root) { + // 先到达最小的子节点 + while (root != null) { + stack.push(root); + root = root.left; + } + } + + /** + * @return the next smallest number + */ + public int next() { + TreeNode n = stack.peek(); + stack.pop(); + int res = n.val; + if (n.right != null) { + n = n.right; + while (n != null) { + stack.push(n); + n = n.left; + } + } + return res; + } + + /** + * @return whether we have a next smallest number + */ + public boolean hasNext() { + return !stack.isEmpty(); + } + } + + + /** + * 题目很简单,这个解法是相对笨一点的解法 + */ + class BSTIteratorII { + Queue queue = new LinkedList(); + + public void BSTIteratorII(TreeNode root) { + helper(root); + } + + void helper(TreeNode root) { + if (root == null) { + return; + } + helper(root.left); + queue.offer(root.val); + helper(root.right); + } + + /** + * @return the next smallest number + */ + public int next() { + if (hasNext()) + return queue.poll(); + return -1; + } + + /** + * @return whether we have a next smallest number + */ + public boolean hasNext() { + return !queue.isEmpty(); + } + } +} diff --git a/src/Q230KthSmallestElementinaBST.java b/src/Q230KthSmallestElementinaBST.java new file mode 100644 index 0000000..5d0945a --- /dev/null +++ b/src/Q230KthSmallestElementinaBST.java @@ -0,0 +1,79 @@ +import util.TreeNode; + +import java.util.ArrayDeque; + +/** + * @author ahscuml + * @date 2019/5/17 + * @time 23:14 + */ +public class Q230KthSmallestElementinaBST { + /** + * 测试函数 + * */ + public static void main(String[] args) { + + } + + /** + * BST的特点就是中序遍历就是顺序的数组 + * 按照中序遍历的结构来完成 + * */ + int count = 0; + int res = -1; + public int kthSmallest(TreeNode root, int k) { + helper(root, k); + return res; + } + + void helper(TreeNode root, int k) { + if(root != null) { + kthSmallest(root.left, k); + if(++count == k) { + res = root.val; + } + kthSmallest(root.right, k); + } + } + + /** + * 利用循环的方法 + * */ + public int kthSmallestIte(TreeNode root, int k) { + TreeNode cur = root; + ArrayDeque stack = new ArrayDeque(); + while(!stack.isEmpty() || cur != null) { + if(cur != null) { + stack.push(cur); + cur = cur.left; + } else { + cur = stack.pop(); + if(--k == 0) { + return cur.val; + } + cur = cur.right; + } + } + return -1; + } + + /** + * 另外一种,利用二分查找,分别统计这个节点的左右节点各有多少个节点,直到找到K个 + * */ + public int kthSmallestIII(TreeNode root, int k) { + int cnt = count(root.left); + if(k <= cnt) { + return kthSmallestIII(root.left, k); + } else if(k > cnt + 1) { + return kthSmallestIII(root.right, k - cnt - 1); + } + return root.val; + } + + int count(TreeNode root) { + if(root == null) { + return 0; + } + return 1 + count(root.left) + count(root.right); + } +} diff --git a/src/Q96UniqueBinarySearchTrees.java b/src/Q96UniqueBinarySearchTrees.java index 9cd7299..7b35601 100644 --- a/src/Q96UniqueBinarySearchTrees.java +++ b/src/Q96UniqueBinarySearchTrees.java @@ -15,6 +15,7 @@ public static void main(String[] args) { /** * 空间换时间,记录之前的结果 + * 卡塔兰数的一个例子 */ public int numTrees(int n) { // 二叉搜索树要满足左小右大的条件 From 88140c6e96d8c30afe6f3f8903acfc546c578e51 Mon Sep 17 00:00:00 2001 From: ahscuml Date: Sat, 18 May 2019 01:15:38 +0800 Subject: [PATCH 33/33] =?UTF-8?q?109=E6=8A=8Alist=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E4=B8=BAbst=EF=BC=8C=E9=9C=80=E8=A6=81=E6=B3=A8=E6=84=8F?= =?UTF-8?q?=E5=BE=88=E5=A4=9A=E7=BB=86=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + ...09ConvertSortedListtoBinarySearchTree.java | 70 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 src/Q109ConvertSortedListtoBinarySearchTree.java diff --git a/README.md b/README.md index 652f39f..f048155 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,7 @@ Medium [98](https://leetcode.com/problems/validate-binary-search-tree/) | [Validate Binary Search Tree](/src/Q98ValidateBinarySearchTree.java) | BST | :star: :star: :star: | ByteDance [102](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/) | [Binary Tree Level Order Traversal](/src/Q102BinaryTreeLevelOrderTraversal.java) | Tree | :star: :star: :star: [103](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/) | [Binary Tree Zigzag Level Order Traversal](/src/Q103BinaryTreeZigzagLevelOrderTraversal.java) | Tree | :star: :star: :star: | ByteDance +[109](https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/) | [Convert Sorted List to Binary Search Tree](/src/Q109ConvertSortedListtoBinarySearchTree.java) | BST | :star: :star: :star: :star [113](https://leetcode.com/problems/path-sum-ii/) | [Path Sum II](/src/Q113PathSumII.java) | Tree | :star: :star: [114](https://leetcode.com/problems/flatten-binary-tree-to-linked-list/) | [Flatten Binary Tree to Linked List](/src/Q114FlattenBinaryTreetoLinkedList.java) | Tree、递归 | :star: :star: :star: :star | ByteDance [120](https://leetcode.com/problems/triangle/) | [Triangle](/src/Q120Triangle.java) | DP | :star: :star: :star: :star: diff --git a/src/Q109ConvertSortedListtoBinarySearchTree.java b/src/Q109ConvertSortedListtoBinarySearchTree.java new file mode 100644 index 0000000..0966fe7 --- /dev/null +++ b/src/Q109ConvertSortedListtoBinarySearchTree.java @@ -0,0 +1,70 @@ +import util.ListNode; +import util.TreeNode; + +/** + * 把一个有序链表变成二叉查找树 + * + * @author ahscuml + * @date 2019/5/18 + * @time 1:00 + */ +public class Q109ConvertSortedListtoBinarySearchTree { + /** + * 测试函数 + */ + public static void main(String[] args) { + + } + + /** + * 思路很简单和108题对应,但是108题中的array可以用index来找到中间值,list只能使用双指针这个方法 + * 同样这个里面有很多的细节 + */ + public TreeNode sortedListToBST(ListNode head) { + if (head == null) { + return null; + } + if (head.next == null) { + return new TreeNode(head.val); + } + ListNode fast = head, slow = head, last = slow; + // 利用这种判断方法可以保障fast不是空 + while (fast.next != null && fast.next.next != null) { + fast = fast.next.next; + last = slow; + slow = slow.next; + } + // 分裂为两个list + fast = slow.next; + last.next = null; + TreeNode cur = new TreeNode(slow.val); + if (head != slow) { + cur.left = sortedListToBST(head); + } + cur.right = sortedListToBST(fast); + return cur; + } + + /** + * 跟上面的思路是一样的,但是分成了两个方法,更加好理解 + */ + public TreeNode sortedListToBSTII(ListNode head) { + if (head == null) return null; + return toBST(head, null); + } + + public TreeNode toBST(ListNode head, ListNode tail) { + ListNode slow = head; + ListNode fast = head; + if (head == tail) return null; + + while (fast != tail && fast.next != tail) { + fast = fast.next.next; + slow = slow.next; + } + TreeNode thead = new TreeNode(slow.val); + thead.left = toBST(head, slow); + thead.right = toBST(slow.next, tail); + return thead; + } +}